@fibery/ui-kit 1.19.0 → 1.20.0
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 +7 -6
- package/src/a11y-color.ts +9 -6
- package/src/antd/styles.ts +6 -6
- package/src/button/button.tsx +5 -5
- package/src/design-system.ts +19 -18
- package/src/emoji-picker/emoji-picker-content-with-color.tsx +1 -1
- package/src/emoji-picker/emoji-picker.tsx +2 -2
- package/src/emoji-picker/icon-emoji-picker.tsx +1 -1
- package/src/emoji-picker/primitives/category.tsx +2 -2
- package/src/emoji-picker/primitives/emoji.tsx +26 -3
- package/src/emoji-picker/primitives/footer.tsx +1 -1
- package/src/emoji-picker/primitives/header.tsx +1 -1
- package/src/emoji-picker/primitives/layout.ts +2 -2
- package/src/emoji-picker/primitives/search.tsx +5 -5
- package/src/error-alert.tsx +3 -3
- package/src/form-field-loader.tsx +3 -3
- package/src/icons/ast/AlertTriangle.ts +8 -0
- package/src/icons/ast/DragBlockHandleSingle.ts +8 -0
- package/src/icons/ast/Eye.ts +8 -0
- package/src/icons/ast/NetworkAdd.ts +8 -0
- package/src/icons/ast/RemovePeople.ts +8 -0
- package/src/icons/ast/RicheditorMarkTextBackgroundColor.ts +8 -0
- package/src/icons/ast/index.tsx +6 -1
- package/src/icons/react/AlertTriangle.tsx +12 -0
- package/src/icons/react/DragBlockHandleSingle.tsx +12 -0
- package/src/icons/react/Eye.tsx +12 -0
- package/src/icons/react/NetworkAdd.tsx +12 -0
- package/src/icons/react/RemovePeople.tsx +12 -0
- package/src/icons/react/RicheditorMarkTextBackgroundColor.tsx +12 -0
- package/src/icons/react/index.tsx +6 -1
- package/src/loaders.tsx +10 -10
- package/src/loading-sausage.tsx +2 -2
- package/src/media-query-utils.ts +1 -1
- package/src/select/custom-select-partials/group-heading.tsx +2 -2
- package/src/select/custom-select-partials/menu.tsx +9 -1
- package/src/select/custom-select-partials/no-option-message.tsx +1 -1
- package/src/select/custom-select-partials/option.tsx +64 -7
- package/src/select/index.tsx +1 -1
- package/src/select/select-in-popover.tsx +10 -10
- package/src/select/styles.ts +12 -4
- package/src/toast/primitives.tsx +21 -8
- package/src/toast/toast-action.tsx +9 -1
- package/src/toast/toast-provider.tsx +15 -0
- package/src/toast/{toast-queue.tsx → toast-queue.ts} +21 -25
- package/src/toast/toast.tsx +35 -28
- package/src/toast/toaster.tsx +11 -48
- package/src/toast/utils/toastify-item-name.ts +6 -0
- package/src/tooltip.tsx +2 -2
- package/src/icons/ast/RicheditorMarkHighlight.ts +0 -8
- package/src/icons/react/RicheditorMarkHighlight.tsx +0 -12
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// This icon file is generated automatically.
|
|
2
|
+
|
|
3
|
+
import RicheditorMarkTextBackgroundColorSvg from '../ast/RicheditorMarkTextBackgroundColor';
|
|
4
|
+
import { Icon } from '../Icon';
|
|
5
|
+
import { IconBaseProps } from '../types';
|
|
6
|
+
|
|
7
|
+
const RicheditorMarkTextBackgroundColor = (
|
|
8
|
+
props: IconBaseProps,
|
|
9
|
+
): JSX.Element => <Icon {...props} icon={RicheditorMarkTextBackgroundColorSvg} />;
|
|
10
|
+
|
|
11
|
+
RicheditorMarkTextBackgroundColor.displayName = 'RicheditorMarkTextBackgroundColor';
|
|
12
|
+
export default RicheditorMarkTextBackgroundColor;
|
|
@@ -9,6 +9,7 @@ export { default as AddReactions } from './AddReactions';
|
|
|
9
9
|
export { default as Add } from './Add';
|
|
10
10
|
export { default as AiAssistant } from './AiAssistant';
|
|
11
11
|
export { default as AiAvatar } from './AiAvatar';
|
|
12
|
+
export { default as AlertTriangle } from './AlertTriangle';
|
|
12
13
|
export { default as AntdFilledCheckCircle } from './AntdFilledCheckCircle';
|
|
13
14
|
export { default as AntdFilledCloseCircle } from './AntdFilledCloseCircle';
|
|
14
15
|
export { default as AntdFilledExclamationCircle } from './AntdFilledExclamationCircle';
|
|
@@ -58,6 +59,7 @@ export { default as Delete } from './Delete';
|
|
|
58
59
|
export { default as Demo } from './Demo';
|
|
59
60
|
export { default as DoubleArrowLeft } from './DoubleArrowLeft';
|
|
60
61
|
export { default as DoubleArrowRight } from './DoubleArrowRight';
|
|
62
|
+
export { default as DragBlockHandleSingle } from './DragBlockHandleSingle';
|
|
61
63
|
export { default as DragBlockHandle } from './DragBlockHandle';
|
|
62
64
|
export { default as DragHandle } from './DragHandle';
|
|
63
65
|
export { default as DynamicFilterValue } from './DynamicFilterValue';
|
|
@@ -70,6 +72,7 @@ export { default as ExtensionComments } from './ExtensionComments';
|
|
|
70
72
|
export { default as ExtensionFiles } from './ExtensionFiles';
|
|
71
73
|
export { default as ExtensionReferences } from './ExtensionReferences';
|
|
72
74
|
export { default as ExtensionWorkflow } from './ExtensionWorkflow';
|
|
75
|
+
export { default as Eye } from './Eye';
|
|
73
76
|
export { default as FavoritesChecked } from './FavoritesChecked';
|
|
74
77
|
export { default as FavoritesOff } from './FavoritesOff';
|
|
75
78
|
export { default as Favorites } from './Favorites';
|
|
@@ -114,6 +117,7 @@ export { default as Monitor } from './Monitor';
|
|
|
114
117
|
export { default as MoreCompact } from './MoreCompact';
|
|
115
118
|
export { default as More } from './More';
|
|
116
119
|
export { default as MySpace } from './MySpace';
|
|
120
|
+
export { default as NetworkAdd } from './NetworkAdd';
|
|
117
121
|
export { default as Network } from './Network';
|
|
118
122
|
export { default as Notifications } from './Notifications';
|
|
119
123
|
export { default as ObjChild } from './ObjChild';
|
|
@@ -130,6 +134,7 @@ export { default as People } from './People';
|
|
|
130
134
|
export { default as Photo } from './Photo';
|
|
131
135
|
export { default as Popup } from './Popup';
|
|
132
136
|
export { default as Posts } from './Posts';
|
|
137
|
+
export { default as RemovePeople } from './RemovePeople';
|
|
133
138
|
export { default as Remove } from './Remove';
|
|
134
139
|
export { default as Reply } from './Reply';
|
|
135
140
|
export { default as Restore } from './Restore';
|
|
@@ -167,9 +172,9 @@ export { default as RicheditorListOrdered } from './RicheditorListOrdered';
|
|
|
167
172
|
export { default as RicheditorListUnindent } from './RicheditorListUnindent';
|
|
168
173
|
export { default as RicheditorMarkCode } from './RicheditorMarkCode';
|
|
169
174
|
export { default as RicheditorMarkEm } from './RicheditorMarkEm';
|
|
170
|
-
export { default as RicheditorMarkHighlight } from './RicheditorMarkHighlight';
|
|
171
175
|
export { default as RicheditorMarkStrike } from './RicheditorMarkStrike';
|
|
172
176
|
export { default as RicheditorMarkStrong } from './RicheditorMarkStrong';
|
|
177
|
+
export { default as RicheditorMarkTextBackgroundColor } from './RicheditorMarkTextBackgroundColor';
|
|
173
178
|
export { default as RicheditorMarkUnderline } from './RicheditorMarkUnderline';
|
|
174
179
|
export { default as RicheditorOpenLink } from './RicheditorOpenLink';
|
|
175
180
|
export { default as RicheditorTableCreate } from './RicheditorTableCreate';
|
package/src/loaders.tsx
CHANGED
|
@@ -16,7 +16,7 @@ export const LoadingView = styled.div<{absolute: boolean; backgroundColor?: stri
|
|
|
16
16
|
left: 0,
|
|
17
17
|
bottom: 0,
|
|
18
18
|
right: 0,
|
|
19
|
-
padding: space.
|
|
19
|
+
padding: space.s24,
|
|
20
20
|
}}
|
|
21
21
|
`;
|
|
22
22
|
|
|
@@ -28,8 +28,8 @@ export const LoadingHeader = styled.div<{absolute: boolean}>`
|
|
|
28
28
|
right: 0,
|
|
29
29
|
height: layout.viewHeaderHeight,
|
|
30
30
|
backgroundColor: themeVars.mainBg,
|
|
31
|
-
paddingBottom: space.
|
|
32
|
-
paddingLeft: space.
|
|
31
|
+
paddingBottom: space.s12,
|
|
32
|
+
paddingLeft: space.s12 + space.s6,
|
|
33
33
|
display: "flex",
|
|
34
34
|
justifyContent: "flex-end",
|
|
35
35
|
flexDirection: "column",
|
|
@@ -52,7 +52,7 @@ export const SidebarLoadingPage = () => (
|
|
|
52
52
|
${{
|
|
53
53
|
width: layout.typeEditorWidth,
|
|
54
54
|
minWidth: layout.typeEditorMinWidth,
|
|
55
|
-
paddingBottom: space.
|
|
55
|
+
paddingBottom: space.s24,
|
|
56
56
|
overflowY: "scroll",
|
|
57
57
|
height: "100%",
|
|
58
58
|
}}
|
|
@@ -64,20 +64,20 @@ export const SidebarLoadingPage = () => (
|
|
|
64
64
|
|
|
65
65
|
const loaderWrapperStyle = css`
|
|
66
66
|
${{
|
|
67
|
-
padding: space.
|
|
67
|
+
padding: space.s48,
|
|
68
68
|
height: "100%",
|
|
69
69
|
display: "flex",
|
|
70
70
|
alignItems: "center",
|
|
71
71
|
justifyContent: "center",
|
|
72
72
|
flexDirection: "column",
|
|
73
|
-
marginLeft: space.
|
|
74
|
-
marginRight: space.
|
|
73
|
+
marginLeft: space.s12,
|
|
74
|
+
marginRight: space.s12,
|
|
75
75
|
borderRadius: border.radius6,
|
|
76
76
|
}}
|
|
77
77
|
`;
|
|
78
78
|
|
|
79
79
|
const loaderStyle = css`
|
|
80
|
-
${{paddingBottom: space.
|
|
80
|
+
${{paddingBottom: space.s6, ...textStyles.regular}}
|
|
81
81
|
`;
|
|
82
82
|
export const LoadingApp = ({backgroundColor = "transparent", appName}: {backgroundColor?: string; appName: string}) => (
|
|
83
83
|
<div className={loaderWrapperStyle} style={{backgroundColor}}>
|
|
@@ -158,12 +158,12 @@ export const LoadingTreeMenuItem = ({
|
|
|
158
158
|
level === 0 &&
|
|
159
159
|
css`
|
|
160
160
|
padding-left: 5px;
|
|
161
|
-
gap: ${space.
|
|
161
|
+
gap: ${space.s6}px;
|
|
162
162
|
`
|
|
163
163
|
)}
|
|
164
164
|
>
|
|
165
165
|
<Icon color={color} containerSize={layout.newMenuItemHeight} iconSize={18} />
|
|
166
|
-
{children || <LoadingSausage height={space.
|
|
166
|
+
{children || <LoadingSausage height={space.s6} inverted={theme.mode === "dark"} />}
|
|
167
167
|
</div>
|
|
168
168
|
);
|
|
169
169
|
};
|
package/src/loading-sausage.tsx
CHANGED
package/src/media-query-utils.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const noop = () => {};
|
|
3
3
|
export function getMediaQueryList(query: string) {
|
|
4
4
|
// need for test
|
|
5
|
-
return typeof window !== undefined && window.matchMedia
|
|
5
|
+
return typeof window !== "undefined" && window.matchMedia
|
|
6
6
|
? window.matchMedia(query)
|
|
7
7
|
: ({matches: false, addEventListener: noop, removeEventListener: noop} as unknown as MediaQueryList);
|
|
8
8
|
}
|
|
@@ -17,11 +17,11 @@ const groupHeadingClass = css`
|
|
|
17
17
|
white-space: nowrap;
|
|
18
18
|
overflow: hidden;
|
|
19
19
|
text-overflow: ellipsis;
|
|
20
|
-
padding: ${space.
|
|
20
|
+
padding: ${space.s8 + space.s4}px ${space.s8}px ${space.s12}px ${space.s8}px;
|
|
21
21
|
color: ${themeVars.disabledTextColor};
|
|
22
22
|
`;
|
|
23
23
|
const groupDividerContainerStyle = css`
|
|
24
|
-
padding: ${space.
|
|
24
|
+
padding: ${space.s12}px 0;
|
|
25
25
|
box-sizing: content-box;
|
|
26
26
|
`;
|
|
27
27
|
|
|
@@ -3,12 +3,18 @@ import {CSSObjectWithLabel, MenuProps} from "react-select";
|
|
|
3
3
|
import cn from "classnames";
|
|
4
4
|
import {components} from "react-windowed-select";
|
|
5
5
|
import {css} from "@linaria/core";
|
|
6
|
-
import {border, themeVars} from "../../design-system";
|
|
6
|
+
import {border, space, themeVars} from "../../design-system";
|
|
7
7
|
|
|
8
|
+
export const MenuListNulledStyles: CSSObjectWithLabel = {
|
|
9
|
+
paddingTop: "",
|
|
10
|
+
paddingBottom: "",
|
|
11
|
+
};
|
|
8
12
|
export const MenuNulledStyles: CSSObjectWithLabel = {
|
|
9
13
|
backgroundColor: "",
|
|
10
14
|
borderRadius: "",
|
|
11
15
|
boxShadow: "",
|
|
16
|
+
paddingTop: "",
|
|
17
|
+
paddingBottom: "",
|
|
12
18
|
};
|
|
13
19
|
const MenuRootClass = css`
|
|
14
20
|
color: ${themeVars.disabledTextColor};
|
|
@@ -16,6 +22,8 @@ const MenuRootClass = css`
|
|
|
16
22
|
background-color: ${themeVars.colorBgSelectMenu};
|
|
17
23
|
box-shadow: ${themeVars.shadowSelectMenu};
|
|
18
24
|
border-radius: ${border.radius6}px;
|
|
25
|
+
padding-top: ${space.s6}px;
|
|
26
|
+
padding-bottom: ${space.s6}px;
|
|
19
27
|
overflow: hidden;
|
|
20
28
|
`;
|
|
21
29
|
export function Menu<Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>(
|
|
@@ -3,7 +3,7 @@ import {css} from "@linaria/core";
|
|
|
3
3
|
import {space} from "../../design-system";
|
|
4
4
|
|
|
5
5
|
const NopOptionMessageClass = css`
|
|
6
|
-
padding: ${space.
|
|
6
|
+
padding: ${space.s12 + 2}px ${space.s8}px;
|
|
7
7
|
`;
|
|
8
8
|
export const NoOptionsMessage = ({children}: {children: ReactNode}) => {
|
|
9
9
|
return <div className={NopOptionMessageClass}>{children}</div>;
|
|
@@ -3,14 +3,16 @@ import {components} from "react-windowed-select";
|
|
|
3
3
|
import {GroupBase} from "../index";
|
|
4
4
|
import {css} from "@linaria/core";
|
|
5
5
|
import {layout, space} from "../../design-system";
|
|
6
|
-
import {
|
|
6
|
+
import {ListItem} from "../../lists/list-item";
|
|
7
7
|
import cn from "classnames";
|
|
8
|
+
import {Children, ReactNode, useCallback, useMemo, useRef, useState} from "react";
|
|
9
|
+
import {Tooltip} from "antd";
|
|
8
10
|
|
|
9
11
|
export const OptionNulledVitualizedStyles = {
|
|
10
|
-
height: layout.
|
|
12
|
+
height: layout.menuItemHeight,
|
|
11
13
|
};
|
|
12
14
|
export const OptionNulledStyles = {
|
|
13
|
-
minHeight: layout.
|
|
15
|
+
minHeight: layout.menuItemHeight,
|
|
14
16
|
paddingLeft: "",
|
|
15
17
|
paddingRight: "",
|
|
16
18
|
paddingTop: "",
|
|
@@ -21,13 +23,63 @@ export const OptionNulledStyles = {
|
|
|
21
23
|
color: "",
|
|
22
24
|
};
|
|
23
25
|
const OptionRootClass = css`
|
|
24
|
-
padding: 0 ${space.
|
|
26
|
+
padding: 0 ${space.s6}px;
|
|
25
27
|
display: flex;
|
|
26
28
|
align-items: stretch;
|
|
27
29
|
justify-content: stretch;
|
|
28
30
|
cursor: pointer;
|
|
31
|
+
max-width: 100%;
|
|
29
32
|
`;
|
|
30
33
|
|
|
34
|
+
const optionWithTextContent = css`
|
|
35
|
+
max-width: 100%;
|
|
36
|
+
padding: 0 ${space.s4}px;
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
const optionTextOverflowWrapper = css`
|
|
40
|
+
max-width: 100%;
|
|
41
|
+
flex-basis: 100%;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
text-overflow: ellipsis;
|
|
44
|
+
white-space: nowrap;
|
|
45
|
+
padding: 0 ${space.s4}px;
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
function isOptionContentIsPureText(children: ReactNode) {
|
|
49
|
+
return !Children.toArray(children).find((child) => !(typeof child === "string" || typeof child === "number"));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type OptionTextContentWithTooltipProps = {
|
|
53
|
+
children: string | number;
|
|
54
|
+
isFocused?: boolean;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
function OptionTextContentWithTooltip({children, isFocused}: OptionTextContentWithTooltipProps) {
|
|
58
|
+
const [isTooltipActive, setTooltipActive] = useState<boolean>(false);
|
|
59
|
+
const textWrapperRef = useRef<HTMLDivElement>(null);
|
|
60
|
+
const textContentRef = useRef<HTMLSpanElement>(null);
|
|
61
|
+
const onOptionMouseEnter = useCallback(() => {
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
if (!textContentRef.current || !textWrapperRef.current) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
isFocused && setTooltipActive(textContentRef.current?.offsetWidth > textWrapperRef.current?.offsetWidth);
|
|
67
|
+
}, 300);
|
|
68
|
+
}, [textContentRef, textWrapperRef, isFocused]);
|
|
69
|
+
return (
|
|
70
|
+
<div
|
|
71
|
+
className={optionWithTextContent}
|
|
72
|
+
onMouseEnter={onOptionMouseEnter}
|
|
73
|
+
onMouseLeave={() => setTooltipActive(false)}
|
|
74
|
+
>
|
|
75
|
+
<Tooltip title={children} mouseEnterDelay={300} placement={"right"} open={isTooltipActive}>
|
|
76
|
+
<div ref={textWrapperRef} className={optionTextOverflowWrapper}>
|
|
77
|
+
<span ref={textContentRef}>{children}</span>
|
|
78
|
+
</div>
|
|
79
|
+
</Tooltip>
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
31
83
|
/**
|
|
32
84
|
* Attention! Do not use this option for potentially long lists inside React Select
|
|
33
85
|
* Why is this option slow? Read here https://the.fibery.io/SoftDev/bug/Select-option-behaviour-is-incorrect-9413
|
|
@@ -38,11 +90,16 @@ export function OptionSlow<
|
|
|
38
90
|
Group extends GroupBase<Option> = GroupBase<Option>
|
|
39
91
|
>({children, ...rest}: OptionProps<Option, IsMulti, Group>) {
|
|
40
92
|
const {isDisabled, isSelected, isFocused} = rest;
|
|
93
|
+
const isPureText = useMemo(() => isOptionContentIsPureText(children), [children]);
|
|
41
94
|
return (
|
|
42
95
|
<components.Option {...rest} className={cn(rest.className, OptionRootClass)}>
|
|
43
|
-
<
|
|
44
|
-
{
|
|
45
|
-
|
|
96
|
+
<ListItem focused={isFocused} selected={isSelected} hovered={false} done={isDisabled}>
|
|
97
|
+
{isPureText ? (
|
|
98
|
+
<OptionTextContentWithTooltip isFocused={isFocused}>{children as string}</OptionTextContentWithTooltip>
|
|
99
|
+
) : (
|
|
100
|
+
children
|
|
101
|
+
)}
|
|
102
|
+
</ListItem>
|
|
46
103
|
</components.Option>
|
|
47
104
|
);
|
|
48
105
|
}
|
package/src/select/index.tsx
CHANGED
|
@@ -140,7 +140,7 @@ export const Select = forwardRef(function Select<
|
|
|
140
140
|
(e) => {
|
|
141
141
|
switch (e.key) {
|
|
142
142
|
case "Escape":
|
|
143
|
-
// we
|
|
143
|
+
// we can't rely on "menuIsOpen" prop here, as user may not pass this prop and rely on internal component behavior instead.
|
|
144
144
|
if (menuOpenState) {
|
|
145
145
|
e.stopPropagation();
|
|
146
146
|
}
|
|
@@ -27,14 +27,14 @@ import {
|
|
|
27
27
|
} from "./index";
|
|
28
28
|
import {SelectControlSettingsProvider} from "./select-control-settings-context";
|
|
29
29
|
|
|
30
|
-
const offset = [0, space.
|
|
30
|
+
const offset = [0, space.s4] as [number, number];
|
|
31
31
|
const popupClassName = css`
|
|
32
32
|
z-index: 1050;
|
|
33
33
|
max-width: 360px;
|
|
34
|
-
padding-top: ${space.
|
|
35
|
-
padding-bottom: ${space.
|
|
36
|
-
padding-left: ${space.
|
|
37
|
-
padding-right: ${space.
|
|
34
|
+
padding-top: ${space.s8}px;
|
|
35
|
+
padding-bottom: ${space.s4}px;
|
|
36
|
+
padding-left: ${space.s8}px;
|
|
37
|
+
padding-right: ${space.s8}px;
|
|
38
38
|
`;
|
|
39
39
|
|
|
40
40
|
const valueClassName = css`
|
|
@@ -58,10 +58,10 @@ const valueClassName = css`
|
|
|
58
58
|
|
|
59
59
|
const titleClassName = css`
|
|
60
60
|
${textStyles.heading6}
|
|
61
|
-
padding-top: ${space.
|
|
62
|
-
padding-left: ${space.
|
|
63
|
-
padding-right: ${space.
|
|
64
|
-
padding-bottom: ${space.
|
|
61
|
+
padding-top: ${space.s6}px;
|
|
62
|
+
padding-left: ${space.s8}px;
|
|
63
|
+
padding-right: ${space.s8}px;
|
|
64
|
+
padding-bottom: ${space.s12}px;
|
|
65
65
|
`;
|
|
66
66
|
|
|
67
67
|
export const selectInPopupStyles = {
|
|
@@ -78,7 +78,7 @@ export const selectInPopupStyles = {
|
|
|
78
78
|
...props,
|
|
79
79
|
minWidth: 100,
|
|
80
80
|
position: "static",
|
|
81
|
-
marginTop: space.
|
|
81
|
+
marginTop: space.s6,
|
|
82
82
|
marginBottom: 0,
|
|
83
83
|
boxShadow: "none",
|
|
84
84
|
borderRadius: border.radius4,
|
package/src/select/styles.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type {ControlProps, CSSObjectWithLabel, StylesConfig} from "react-select"
|
|
|
3
3
|
import {inputOverrides} from "../antd/styles";
|
|
4
4
|
import {layout, space, themeVars} from "../design-system";
|
|
5
5
|
import {OptionNulledStyles, OptionNulledVitualizedStyles} from "./custom-select-partials/option";
|
|
6
|
-
import {MenuNulledStyles} from "./custom-select-partials/menu";
|
|
6
|
+
import {MenuListNulledStyles, MenuNulledStyles} from "./custom-select-partials/menu";
|
|
7
7
|
import {groupHeadingNulledStyles} from "./custom-select-partials/group-heading";
|
|
8
8
|
|
|
9
9
|
export const expanderExpandedStyle = css`
|
|
@@ -35,8 +35,8 @@ function createControlStyle({
|
|
|
35
35
|
...(state.isFocused && inputOverrides.focus),
|
|
36
36
|
...(state.isDisabled && inputOverrides.disabled),
|
|
37
37
|
":hover": !state.isFocused && !state.isDisabled ? inputOverrides.hover : {},
|
|
38
|
-
paddingLeft: space.
|
|
39
|
-
paddingRight: space.
|
|
38
|
+
paddingLeft: space.s10,
|
|
39
|
+
paddingRight: space.s12,
|
|
40
40
|
"& > div": childDivStyle,
|
|
41
41
|
} as unknown as CSSObjectWithLabel);
|
|
42
42
|
}
|
|
@@ -78,11 +78,15 @@ export const componentsStyles: StylesConfig = {
|
|
|
78
78
|
...provided,
|
|
79
79
|
overflow: "visible",
|
|
80
80
|
color: themeVars.textColor,
|
|
81
|
+
marginLeft: "",
|
|
82
|
+
marginRight: "",
|
|
83
|
+
margin: "",
|
|
81
84
|
}),
|
|
82
85
|
valueContainer(provided) {
|
|
83
86
|
return {
|
|
84
87
|
...provided,
|
|
85
88
|
minWidth: 10,
|
|
89
|
+
gridTemplateColumns: "1fr",
|
|
86
90
|
};
|
|
87
91
|
},
|
|
88
92
|
multiValue: (provided) => ({
|
|
@@ -92,7 +96,7 @@ export const componentsStyles: StylesConfig = {
|
|
|
92
96
|
marginTop: 0,
|
|
93
97
|
marginBottom: 0,
|
|
94
98
|
marginLeft: 0,
|
|
95
|
-
marginRight: space.
|
|
99
|
+
marginRight: space.s12,
|
|
96
100
|
alignItems: "center",
|
|
97
101
|
height: layout.inputHeight - 2,
|
|
98
102
|
}),
|
|
@@ -115,6 +119,10 @@ export const componentsStyles: StylesConfig = {
|
|
|
115
119
|
...provided,
|
|
116
120
|
...MenuNulledStyles,
|
|
117
121
|
}),
|
|
122
|
+
menuList: (provided) => ({
|
|
123
|
+
...provided,
|
|
124
|
+
...MenuListNulledStyles,
|
|
125
|
+
}),
|
|
118
126
|
container: (provided, state) => ({
|
|
119
127
|
...provided,
|
|
120
128
|
pointerEvents: "auto",
|
package/src/toast/primitives.tsx
CHANGED
|
@@ -6,8 +6,6 @@ import {IconButton} from "../button/icon-button";
|
|
|
6
6
|
import {border, space, textStyles, themeVars} from "../design-system";
|
|
7
7
|
import CloseIcon from "../icons/react/Close";
|
|
8
8
|
|
|
9
|
-
export const ToastProvider = ToastPrimitives.Provider;
|
|
10
|
-
|
|
11
9
|
const viewportCss = css`
|
|
12
10
|
position: fixed;
|
|
13
11
|
left: 50%;
|
|
@@ -24,7 +22,7 @@ const viewportCss = css`
|
|
|
24
22
|
list-style: none;
|
|
25
23
|
|
|
26
24
|
&:not(:empty) {
|
|
27
|
-
padding: ${space.
|
|
25
|
+
padding: ${space.s24}px; // increased mouse hover area to pause timers of toast
|
|
28
26
|
}
|
|
29
27
|
`;
|
|
30
28
|
|
|
@@ -39,11 +37,22 @@ const rootCss = css`
|
|
|
39
37
|
user-select: auto !important;
|
|
40
38
|
|
|
41
39
|
background-color: ${themeVars.colorBgToastDefault};
|
|
42
|
-
padding: ${space.
|
|
40
|
+
padding: ${space.s12}px ${space.s8 * 2}px;
|
|
43
41
|
border-radius: ${border.radius6}px;
|
|
44
42
|
box-shadow: ${themeVars.shadowModal};
|
|
45
43
|
|
|
46
|
-
|
|
44
|
+
will-change: opacity;
|
|
45
|
+
|
|
46
|
+
@keyframes fadeIn {
|
|
47
|
+
from {
|
|
48
|
+
opacity: 0;
|
|
49
|
+
}
|
|
50
|
+
to {
|
|
51
|
+
opacity: 1;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@keyframes fadeOut {
|
|
47
56
|
from {
|
|
48
57
|
opacity: 1;
|
|
49
58
|
}
|
|
@@ -80,15 +89,19 @@ const rootCss = css`
|
|
|
80
89
|
transition: transform 200ms ease-out;
|
|
81
90
|
}
|
|
82
91
|
|
|
92
|
+
&[data-state="open"] {
|
|
93
|
+
animation: fadeIn 200ms ease-out;
|
|
94
|
+
}
|
|
95
|
+
&[data-state="closed"] {
|
|
96
|
+
animation: fadeOut 200ms ease-out;
|
|
97
|
+
}
|
|
98
|
+
|
|
83
99
|
@media (prefers-reduced-motion: no-preference) {
|
|
84
100
|
will-change: transform, opacity;
|
|
85
101
|
|
|
86
102
|
&[data-state="open"] {
|
|
87
103
|
animation: slideIn 200ms ease-out;
|
|
88
104
|
}
|
|
89
|
-
&[data-state="closed"] {
|
|
90
|
-
animation: hide 200ms ease-out;
|
|
91
|
-
}
|
|
92
105
|
|
|
93
106
|
&[data-swipe="end"] {
|
|
94
107
|
animation: swipeOut 200ms ease-out;
|
|
@@ -3,6 +3,14 @@ import {ElementRef, forwardRef} from "react";
|
|
|
3
3
|
import {ButtonProps} from "../button/button";
|
|
4
4
|
import {Button} from "../button";
|
|
5
5
|
import {useTheme} from "../theme-provider";
|
|
6
|
+
import {css} from "@linaria/core";
|
|
7
|
+
import {space} from "../design-system";
|
|
8
|
+
|
|
9
|
+
const toastActionCss = css`
|
|
10
|
+
margin-top: -${space.s4}px;
|
|
11
|
+
margin-bottom: -${space.s4}px;
|
|
12
|
+
flex-shrink: 0;
|
|
13
|
+
`;
|
|
6
14
|
|
|
7
15
|
export const ToastAction = forwardRef<
|
|
8
16
|
ElementRef<typeof RadixToastAction>,
|
|
@@ -10,7 +18,7 @@ export const ToastAction = forwardRef<
|
|
|
10
18
|
>(({children, altText, ...props}, ref) => {
|
|
11
19
|
const theme = useTheme();
|
|
12
20
|
return (
|
|
13
|
-
<RadixToastAction ref={ref} altText={altText} asChild>
|
|
21
|
+
<RadixToastAction className={toastActionCss} ref={ref} altText={altText} asChild>
|
|
14
22
|
<Button color={theme.textColor} {...props}>
|
|
15
23
|
{children}
|
|
16
24
|
</Button>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {createContext} from "@fibery/react/src/create-context";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import type {ToastQueue} from "./toast-queue";
|
|
4
|
+
import {ToastProvider as PrimitiveToastProvider} from "@radix-ui/react-toast";
|
|
5
|
+
|
|
6
|
+
const [Provider, useCtx] = createContext<ToastQueue>("ToastQueue");
|
|
7
|
+
|
|
8
|
+
export const ToastProvider: React.FC<React.PropsWithChildren<{toastQueue: ToastQueue}>> = ({toastQueue, children}) => {
|
|
9
|
+
return (
|
|
10
|
+
<Provider value={toastQueue}>
|
|
11
|
+
<PrimitiveToastProvider>{children}</PrimitiveToastProvider>
|
|
12
|
+
</Provider>
|
|
13
|
+
);
|
|
14
|
+
};
|
|
15
|
+
export const useToast = useCtx;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import {makePubSub} from "@fibery/helpers/utils/pub-sub";
|
|
2
2
|
import type {ToastProps} from "./toast";
|
|
3
3
|
|
|
4
|
-
type AddToastProps = Pick<
|
|
4
|
+
export type AddToastProps = Pick<
|
|
5
|
+
ToastProps,
|
|
6
|
+
"type" | "title" | "subTitle" | "icon" | "action" | "duration" | "open"
|
|
7
|
+
> & {
|
|
5
8
|
id?: string;
|
|
6
9
|
};
|
|
7
10
|
type TypedAddProps = Omit<AddToastProps, "type">;
|
|
@@ -12,8 +15,15 @@ type QueuedToast = AddToastProps & {
|
|
|
12
15
|
|
|
13
16
|
type ToastQueueOpts = {
|
|
14
17
|
maxActiveToasts?: number;
|
|
18
|
+
onToastAdd?: (params: AddToastProps) => void;
|
|
19
|
+
|
|
20
|
+
/** Overrides toast props.
|
|
21
|
+
* This option is added only to support mapping of billing errors as it was done in toast actions.
|
|
22
|
+
* Ideally this should be removed and billing errors moved to thunk middlewares
|
|
23
|
+
*/
|
|
24
|
+
transformToast?: (params: AddToastProps) => AddToastProps;
|
|
15
25
|
};
|
|
16
|
-
export const makeToastQueue = ({maxActiveToasts = 1}: ToastQueueOpts = {}) => {
|
|
26
|
+
export const makeToastQueue = ({maxActiveToasts = 1, onToastAdd, transformToast}: ToastQueueOpts = {}) => {
|
|
17
27
|
const pubSub = makePubSub();
|
|
18
28
|
let queue: QueuedToast[] = [];
|
|
19
29
|
let activeToasts: QueuedToast[] = [];
|
|
@@ -35,39 +45,24 @@ export const makeToastQueue = ({maxActiveToasts = 1}: ToastQueueOpts = {}) => {
|
|
|
35
45
|
pubSub.publish();
|
|
36
46
|
};
|
|
37
47
|
|
|
38
|
-
const closeActive = (id: string) => {
|
|
39
|
-
activeToasts = activeToasts.map((t) => (t.id === id ? {...t, open: false} : t));
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const removeFromQueue = (id: string) => {
|
|
43
|
-
queue = queue.filter((queued) => queued.id !== id);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
48
|
/**
|
|
47
49
|
* Add toast to queue
|
|
48
50
|
*
|
|
49
51
|
* Pass custom `id` if you don't want toasts to be duplicated.
|
|
50
52
|
* If toast with same id already exists it will be closed to display fresh more relevant one
|
|
51
53
|
*/
|
|
52
|
-
const add = ({id, ...toast}: AddToastProps
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
!replace &&
|
|
56
|
-
(queue.some((queued) => queued.id === id) || activeToasts.some((active) => active.id === id))
|
|
57
|
-
) {
|
|
58
|
-
return id;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (id && replace) {
|
|
62
|
-
closeActive(id);
|
|
63
|
-
removeFromQueue(id);
|
|
54
|
+
const add = ({id, ...toast}: AddToastProps) => {
|
|
55
|
+
if (activeToasts.length > 0) {
|
|
56
|
+
activeToasts[0].open = false;
|
|
64
57
|
}
|
|
65
58
|
|
|
66
59
|
const t: QueuedToast = {
|
|
67
60
|
id: id || makeId(),
|
|
68
|
-
...toast,
|
|
61
|
+
...(transformToast ? transformToast(toast) : toast),
|
|
69
62
|
};
|
|
70
63
|
|
|
64
|
+
onToastAdd?.(t);
|
|
65
|
+
|
|
71
66
|
queue.push(t);
|
|
72
67
|
|
|
73
68
|
updateActiveToasts();
|
|
@@ -77,9 +72,10 @@ export const makeToastQueue = ({maxActiveToasts = 1}: ToastQueueOpts = {}) => {
|
|
|
77
72
|
|
|
78
73
|
return {
|
|
79
74
|
add,
|
|
80
|
-
/**
|
|
75
|
+
/** Mark active toast as closed. Can be used to play exit animation */
|
|
81
76
|
close(id: string) {
|
|
82
|
-
|
|
77
|
+
activeToasts = activeToasts.map((t) => (t.id === id ? {...t, open: false} : t));
|
|
78
|
+
|
|
83
79
|
pubSub.publish();
|
|
84
80
|
},
|
|
85
81
|
/** remove toast from active ones, should be called after exit animation */
|