@fibery/ui-kit 1.34.7 → 1.35.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 +2 -2
- package/src/actions-menu/actions-menu-sub-menu.tsx +3 -0
- package/src/antd/styles.ts +6 -6
- package/src/button/base-button.tsx +1 -1
- package/src/button/icon-button.tsx +2 -2
- package/src/design-system.ts +88 -31
- package/src/dropdown-menu/index.tsx +2 -3
- package/src/emoji-picker/app-icon-picker.tsx +1 -0
- package/src/emoji-picker/emoji-picker-content-with-color.tsx +1 -1
- package/src/emoji-picker/primitives/emoji.tsx +4 -2
- package/src/emoji-picker/primitives/render-config-provider.tsx +12 -0
- package/src/icons/ast/AddDatabase.ts +8 -0
- package/src/icons/ast/AddIntegration.ts +8 -0
- package/src/icons/ast/AiSearch.ts +8 -0
- package/src/icons/ast/Clean.ts +8 -0
- package/src/icons/ast/CollapseAll.ts +8 -0
- package/src/icons/ast/CreditsFilled.ts +8 -0
- package/src/icons/ast/DatabaseOff.ts +8 -0
- package/src/icons/ast/Dependency.ts +8 -0
- package/src/icons/ast/Gift.ts +8 -0
- package/src/icons/ast/ManyPeople.ts +8 -0
- package/src/icons/ast/Markdown.ts +8 -0
- package/src/icons/ast/PeopleCheck.ts +8 -0
- package/src/icons/ast/PresentPlay.ts +8 -0
- package/src/icons/ast/PresentStop.ts +8 -0
- package/src/icons/ast/SendArrow.ts +1 -1
- package/src/icons/ast/SettingsOff.ts +8 -0
- package/src/icons/ast/Template.ts +8 -0
- package/src/icons/ast/UserCheck.ts +8 -0
- package/src/icons/ast/UserGroupRemove.ts +8 -0
- package/src/icons/ast/UserX.ts +8 -0
- package/src/icons/ast/ViewAi.ts +8 -0
- package/src/icons/ast/Views.ts +1 -1
- package/src/icons/ast/index.tsx +20 -0
- package/src/icons/react/AddDatabase.tsx +13 -0
- package/src/icons/react/AddIntegration.tsx +13 -0
- package/src/icons/react/AiSearch.tsx +13 -0
- package/src/icons/react/Clean.tsx +13 -0
- package/src/icons/react/CollapseAll.tsx +13 -0
- package/src/icons/react/CreditsFilled.tsx +13 -0
- package/src/icons/react/DatabaseOff.tsx +13 -0
- package/src/icons/react/Dependency.tsx +13 -0
- package/src/icons/react/Gift.tsx +13 -0
- package/src/icons/react/ManyPeople.tsx +13 -0
- package/src/icons/react/Markdown.tsx +13 -0
- package/src/icons/react/PeopleCheck.tsx +13 -0
- package/src/icons/react/PresentPlay.tsx +13 -0
- package/src/icons/react/PresentStop.tsx +13 -0
- package/src/icons/react/SettingsOff.tsx +13 -0
- package/src/icons/react/Template.tsx +13 -0
- package/src/icons/react/UserCheck.tsx +13 -0
- package/src/icons/react/UserGroupRemove.tsx +13 -0
- package/src/icons/react/UserX.tsx +13 -0
- package/src/icons/react/ViewAi.tsx +13 -0
- package/src/icons/react/index.tsx +20 -0
- package/src/palette.ts +2 -30
- package/src/select/custom-select-partials/clear-indicator.tsx +4 -0
- package/src/select/custom-select-partials/group-heading.tsx +7 -5
- package/src/select/custom-select-partials/menu-list-virtualized.tsx +22 -4
- package/src/select/custom-select-partials/menu.tsx +5 -6
- package/src/select/index.tsx +39 -28
- package/src/select/select-in-popover.tsx +32 -19
- package/src/select/styles.ts +10 -2
- package/src/toast/primitives.tsx +3 -1
- package/src/toast/toast-queue.ts +22 -0
- package/src/toast/toaster.tsx +2 -1
- package/src/tooltip.tsx +13 -0
package/src/palette.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const slate = {
|
|
2
|
+
slateBase: "hsl(0, 0%, 99%)",
|
|
2
3
|
slate1: "hsl(206, 30%, 99%)",
|
|
3
4
|
slate2: "hsl(210, 17%, 98%)",
|
|
4
5
|
slate3: "hsl(209, 13%, 95%)",
|
|
@@ -14,6 +15,7 @@ export const slate = {
|
|
|
14
15
|
} as const;
|
|
15
16
|
|
|
16
17
|
export const slateDark = {
|
|
18
|
+
slateBase: "hsl(0, 0%, 3%)",
|
|
17
19
|
slate1: "hsl(200, 7%, 9%)",
|
|
18
20
|
slate2: "hsl(195, 7%, 11%)",
|
|
19
21
|
slate3: "hsl(197, 7%, 14%)",
|
|
@@ -28,36 +30,6 @@ export const slateDark = {
|
|
|
28
30
|
slate12: "hsl(210, 6%, 93%)",
|
|
29
31
|
} as const;
|
|
30
32
|
|
|
31
|
-
export const sage = {
|
|
32
|
-
sage1: "hsl(155, 30%, 99%)",
|
|
33
|
-
sage2: "hsl(150, 17%, 98%)",
|
|
34
|
-
sage3: "hsl(151, 11%, 95%)",
|
|
35
|
-
sage4: "hsl(151, 9%, 93%)",
|
|
36
|
-
sage5: "hsl(151, 8%, 91%)",
|
|
37
|
-
sage6: "hsl(152, 7%, 88%)",
|
|
38
|
-
sage7: "hsl(153, 7%, 85%)",
|
|
39
|
-
sage8: "hsl(154, 6%, 78%)",
|
|
40
|
-
sage9: "hsl(155, 4%, 56%)",
|
|
41
|
-
sage10: "hsl(154, 3%, 52%)",
|
|
42
|
-
sage11: "hsl(155, 3%, 43%)",
|
|
43
|
-
sage12: "hsl(155, 24%, 9%)",
|
|
44
|
-
} as const;
|
|
45
|
-
|
|
46
|
-
export const sageDark = {
|
|
47
|
-
sage1: "hsl(160, 7%, 8%)",
|
|
48
|
-
sage2: "hsl(150, 7%, 11%)",
|
|
49
|
-
sage3: "hsl(150, 7%, 13%)",
|
|
50
|
-
sage4: "hsl(150, 6%, 15%)",
|
|
51
|
-
sage5: "hsl(150, 6%, 17%)",
|
|
52
|
-
sage6: "hsl(150, 6%, 20%)",
|
|
53
|
-
sage7: "hsl(150, 5%, 24%)",
|
|
54
|
-
sage8: "hsl(150, 5%, 31%)",
|
|
55
|
-
sage9: "hsl(155, 6%, 42%)",
|
|
56
|
-
sage10: "hsl(153, 5%, 48%)",
|
|
57
|
-
sage11: "hsl(155, 5%, 62%)",
|
|
58
|
-
sage12: "hsl(155, 6%, 93%)",
|
|
59
|
-
} as const;
|
|
60
|
-
|
|
61
33
|
export const teal = {
|
|
62
34
|
teal1: "hsl(165, 60%, 99%)",
|
|
63
35
|
teal2: "hsl(169, 65%, 97%)",
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {GroupBase} from "../index";
|
|
2
|
-
import {GroupHeadingProps, components} from "react-select";
|
|
3
1
|
import {css} from "@linaria/core";
|
|
2
|
+
import {GroupHeadingProps, components} from "react-select";
|
|
4
3
|
import {layout, space, textStyles, themeVars} from "../../design-system";
|
|
5
|
-
import React from "react";
|
|
6
|
-
import {isPureTextChildren} from "../util";
|
|
7
4
|
import {TooltipIfOverflown} from "../../tooltip-if-overflown";
|
|
5
|
+
import {GroupBase} from "../index";
|
|
6
|
+
import {isPureTextChildren} from "../util";
|
|
8
7
|
|
|
9
8
|
export const groupHeadingNulledStyles = {
|
|
10
9
|
paddingLeft: "",
|
|
@@ -20,7 +19,7 @@ export const groupHeadingNulledStyles = {
|
|
|
20
19
|
const groupHeadingClass = css`
|
|
21
20
|
min-height: ${layout.menuItemHeight}px;
|
|
22
21
|
color: ${themeVars.disabledTextColor};
|
|
23
|
-
padding: 0 ${space.s6}px
|
|
22
|
+
padding: 0 ${space.s6}px ${space.s2}px ${space.s8}px;
|
|
24
23
|
display: flex;
|
|
25
24
|
align-content: flex-end;
|
|
26
25
|
align-items: flex-end;
|
|
@@ -56,6 +55,9 @@ export function GroupHeading<
|
|
|
56
55
|
if (props.data.separator) {
|
|
57
56
|
return <GroupDivider />;
|
|
58
57
|
}
|
|
58
|
+
if (props.data.label === undefined) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
59
61
|
const isPureText = isPureTextChildren(children);
|
|
60
62
|
return (
|
|
61
63
|
<components.GroupHeading {...props} className={groupHeadingClass}>
|
|
@@ -1,9 +1,25 @@
|
|
|
1
|
+
import {css} from "@linaria/core";
|
|
2
|
+
import _, {isFunction, isObject} from "lodash";
|
|
3
|
+
import {Children, ComponentType, CSSProperties, ReactNode, useContext, useEffect, useRef, useState} from "react";
|
|
1
4
|
import {GroupHeadingProps, GroupProps, MenuListProps} from "react-select";
|
|
2
5
|
import {ItemContent, Virtuoso, VirtuosoHandle} from "react-virtuoso";
|
|
3
|
-
import {Children, ComponentType, CSSProperties, ReactNode, useContext, useEffect, useRef, useState} from "react";
|
|
4
|
-
import {GroupBase, ReactSelectRefContext} from "../util";
|
|
5
6
|
import {layout} from "../../../src/design-system";
|
|
6
|
-
import
|
|
7
|
+
import {GroupBase, ReactSelectRefContext} from "../util";
|
|
8
|
+
|
|
9
|
+
const PADDING_BLOCK_HEIGHT = 6;
|
|
10
|
+
|
|
11
|
+
const Spacer = () => (
|
|
12
|
+
<div
|
|
13
|
+
className={css`
|
|
14
|
+
height: ${PADDING_BLOCK_HEIGHT}px;
|
|
15
|
+
`}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const components = {
|
|
20
|
+
Footer: Spacer,
|
|
21
|
+
Header: Spacer,
|
|
22
|
+
};
|
|
7
23
|
|
|
8
24
|
const OPTION_HEIGHT = layout.menuItemHeight;
|
|
9
25
|
// this code is logic stolen from windowed-select SCROLL_INTO_VIEW_CHECK_FIX prevents list scrolling when focusing
|
|
@@ -128,7 +144,7 @@ export function MenuListVirtualized<
|
|
|
128
144
|
}
|
|
129
145
|
}
|
|
130
146
|
}, [flattenChildren, initialFocusedOption, select]);
|
|
131
|
-
const menuHeight = Math.min(flattenChildren.length * layout.menuItemHeight, maxHeight);
|
|
147
|
+
const menuHeight = Math.min(flattenChildren.length * layout.menuItemHeight + PADDING_BLOCK_HEIGHT * 2, maxHeight);
|
|
132
148
|
//scrolling to focused option
|
|
133
149
|
useEffect(() => {
|
|
134
150
|
let to: number | undefined;
|
|
@@ -171,6 +187,7 @@ export function MenuListVirtualized<
|
|
|
171
187
|
window.clearTimeout(to);
|
|
172
188
|
};
|
|
173
189
|
}, [focusedOption, flattenChildren, menuHeight, initialFocusedOption, virtuoso]);
|
|
190
|
+
|
|
174
191
|
return (
|
|
175
192
|
// Needed for correct display inside portals and etc.
|
|
176
193
|
<div style={getStyles("menuList", props) as CSSProperties}>
|
|
@@ -183,6 +200,7 @@ export function MenuListVirtualized<
|
|
|
183
200
|
data={flattenChildren}
|
|
184
201
|
totalCount={flattenChildren.length}
|
|
185
202
|
itemContent={drawListElement}
|
|
203
|
+
components={components}
|
|
186
204
|
/>
|
|
187
205
|
</div>
|
|
188
206
|
);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {GroupBase} from "../index";
|
|
2
|
-
import {CSSObjectWithLabel, MenuProps, components} from "react-select";
|
|
3
|
-
import cn from "classnames";
|
|
4
1
|
import {css} from "@linaria/core";
|
|
5
|
-
import
|
|
2
|
+
import cn from "classnames";
|
|
3
|
+
import {CSSObjectWithLabel, MenuProps, components} from "react-select";
|
|
4
|
+
import {border, themeVars} from "../../design-system";
|
|
5
|
+
import {GroupBase} from "../index";
|
|
6
6
|
|
|
7
7
|
export const MenuListNulledStyles: CSSObjectWithLabel = {
|
|
8
8
|
paddingTop: "",
|
|
@@ -21,10 +21,9 @@ const MenuRootClass = css`
|
|
|
21
21
|
background-color: ${themeVars.colorBgSelectMenu};
|
|
22
22
|
box-shadow: ${themeVars.shadowSelectMenu};
|
|
23
23
|
border-radius: ${border.radius6}px;
|
|
24
|
-
padding-top: ${space.s6}px;
|
|
25
|
-
padding-bottom: ${space.s6}px;
|
|
26
24
|
overflow: hidden;
|
|
27
25
|
`;
|
|
26
|
+
|
|
28
27
|
export function Menu<Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>(
|
|
29
28
|
props: MenuProps<Option, IsMulti, Group>
|
|
30
29
|
) {
|
package/src/select/index.tsx
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import {useComposedRefs} from "@fibery/react/src/use-composed-refs";
|
|
1
2
|
import {forwardRef, RefObject, useCallback, useMemo, useRef, useState} from "react";
|
|
2
3
|
import BaseSelect, {
|
|
3
4
|
ActionMeta,
|
|
4
|
-
|
|
5
|
+
Props as BaseSelectProps,
|
|
5
6
|
createFilter,
|
|
6
7
|
MenuListProps,
|
|
7
8
|
MenuProps,
|
|
@@ -11,43 +12,47 @@ import BaseSelect, {
|
|
|
11
12
|
OnChangeValue,
|
|
12
13
|
OptionProps,
|
|
13
14
|
OptionsOrGroups,
|
|
14
|
-
Props as BaseSelectProps,
|
|
15
15
|
PropsValue,
|
|
16
|
+
components as reactSelectComponents,
|
|
16
17
|
SelectInstance,
|
|
17
18
|
SingleValue,
|
|
18
19
|
SingleValueProps,
|
|
19
20
|
StylesConfig,
|
|
20
21
|
} from "react-select";
|
|
21
22
|
import BaseCreatableSelect, {CreatableProps} from "react-select/creatable";
|
|
22
|
-
import {
|
|
23
|
-
import {useSelectControlSettings} from "./select-control-settings-context";
|
|
24
|
-
import {Option, OptionSlow} from "./custom-select-partials/option";
|
|
25
|
-
import {Menu} from "./custom-select-partials/menu";
|
|
26
|
-
import {GroupHeading} from "./custom-select-partials/group-heading";
|
|
23
|
+
import {ClearIndicator, NoClearIndicator} from "./custom-select-partials/clear-indicator";
|
|
27
24
|
import {DropdownIndicator} from "./custom-select-partials/drop-down-indicator";
|
|
25
|
+
import {GroupHeading} from "./custom-select-partials/group-heading";
|
|
26
|
+
import {Menu} from "./custom-select-partials/menu";
|
|
27
|
+
import {MenuListVirtualized} from "./custom-select-partials/menu-list-virtualized";
|
|
28
28
|
import {NoOptionsMessage} from "./custom-select-partials/no-option-message";
|
|
29
|
-
import {
|
|
29
|
+
import {Option, OptionSlow} from "./custom-select-partials/option";
|
|
30
|
+
import {useSelectControlSettings} from "./select-control-settings-context";
|
|
31
|
+
import {
|
|
32
|
+
componentsStyles,
|
|
33
|
+
nonVirtualizedStyles,
|
|
34
|
+
singleLineComponentsStyle,
|
|
35
|
+
virtualizedStyles,
|
|
36
|
+
zIndexStyles,
|
|
37
|
+
} from "./styles";
|
|
30
38
|
import {countOptions, GroupBase, ReactSelectRefContext} from "./util";
|
|
31
|
-
import {MenuListVirtualized} from "./custom-select-partials/menu-list-virtualized";
|
|
32
|
-
import {useComposedRefs} from "@fibery/react/src/use-composed-refs";
|
|
33
39
|
|
|
40
|
+
export {reactSelectComponents as components, MenuListVirtualized};
|
|
34
41
|
export type {
|
|
35
|
-
|
|
42
|
+
ActionMeta,
|
|
36
43
|
GroupBase,
|
|
37
|
-
StylesConfig,
|
|
38
|
-
MenuProps,
|
|
39
44
|
MenuListProps,
|
|
40
|
-
|
|
41
|
-
SingleValueProps,
|
|
42
|
-
MultiValueProps,
|
|
43
|
-
SingleValue,
|
|
45
|
+
MenuProps,
|
|
44
46
|
MultiValue,
|
|
45
|
-
|
|
47
|
+
MultiValueProps,
|
|
46
48
|
OnChangeValue,
|
|
49
|
+
OptionProps,
|
|
50
|
+
OptionsOrGroups,
|
|
47
51
|
PropsValue,
|
|
52
|
+
SingleValue,
|
|
53
|
+
SingleValueProps,
|
|
54
|
+
StylesConfig,
|
|
48
55
|
};
|
|
49
|
-
export {reactSelectComponents as components};
|
|
50
|
-
export {MenuListVirtualized};
|
|
51
56
|
|
|
52
57
|
//Group dummy for virtualized option-lists. For performance.
|
|
53
58
|
function GroupVirtualized() {
|
|
@@ -71,6 +76,7 @@ export type SelectProps<
|
|
|
71
76
|
virtualized?: boolean;
|
|
72
77
|
isCollectionMode?: IsMulti;
|
|
73
78
|
disabled?: boolean;
|
|
79
|
+
forbidValuesClearInCollnMode?: boolean;
|
|
74
80
|
};
|
|
75
81
|
|
|
76
82
|
export function SingleRowSelect<
|
|
@@ -110,6 +116,7 @@ export const Select = forwardRef(function Select<
|
|
|
110
116
|
onMenuOpen,
|
|
111
117
|
onMenuClose,
|
|
112
118
|
onChange,
|
|
119
|
+
forbidValuesClearInCollnMode,
|
|
113
120
|
...rest
|
|
114
121
|
}: SelectProps<Option, IsMulti, Group>,
|
|
115
122
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -161,11 +168,10 @@ export const Select = forwardRef(function Select<
|
|
|
161
168
|
},
|
|
162
169
|
[onKeyDown, menuOpenState]
|
|
163
170
|
);
|
|
164
|
-
|
|
165
171
|
const combinedStyles = useMemo(() => {
|
|
166
172
|
return combineStyles<Option, IsMulti, Group>([
|
|
167
173
|
componentsStyles,
|
|
168
|
-
virtualized ? virtualizedStyles :
|
|
174
|
+
virtualized ? virtualizedStyles : nonVirtualizedStyles,
|
|
169
175
|
zIndex ? zIndexStyles(zIndex) : {},
|
|
170
176
|
styles,
|
|
171
177
|
] as StylesConfig<Option, IsMulti, Group>[]);
|
|
@@ -183,7 +189,7 @@ export const Select = forwardRef(function Select<
|
|
|
183
189
|
menuPlacement={"auto"}
|
|
184
190
|
styles={combinedStyles}
|
|
185
191
|
isMulti={isCollectionMode}
|
|
186
|
-
backspaceRemovesValue={isCollectionMode}
|
|
192
|
+
backspaceRemovesValue={isCollectionMode && !forbidValuesClearInCollnMode}
|
|
187
193
|
tabSelectsValue={false}
|
|
188
194
|
components={{
|
|
189
195
|
Menu: Menu,
|
|
@@ -195,7 +201,7 @@ export const Select = forwardRef(function Select<
|
|
|
195
201
|
Read Option definition for more info
|
|
196
202
|
bug here: https://the.fibery.io/SoftDev/bug/Select-option-behaviour-is-incorrect-9413
|
|
197
203
|
*/
|
|
198
|
-
MultiValueRemove: ClearIndicator,
|
|
204
|
+
MultiValueRemove: isCollectionMode && forbidValuesClearInCollnMode ? NoClearIndicator : ClearIndicator,
|
|
199
205
|
NoOptionsMessage,
|
|
200
206
|
GroupHeading,
|
|
201
207
|
Option: optionsCount > FAST_OPTION_USAGE_THRESHOLD ? Option : OptionSlow,
|
|
@@ -253,15 +259,20 @@ export function CreatableSelectInner<
|
|
|
253
259
|
return countOptions<Option, Group>(rest.options);
|
|
254
260
|
}, [rest.options]);
|
|
255
261
|
|
|
262
|
+
const combinedStyles = useMemo(() => {
|
|
263
|
+
return combineStyles<Option, IsMulti, Group>([
|
|
264
|
+
componentsStyles,
|
|
265
|
+
virtualized ? virtualizedStyles : nonVirtualizedStyles,
|
|
266
|
+
styles,
|
|
267
|
+
] as StylesConfig<Option, IsMulti, Group>[]);
|
|
268
|
+
}, [styles, virtualized]);
|
|
269
|
+
|
|
256
270
|
return (
|
|
257
271
|
<BaseCreatableSelect
|
|
258
272
|
ref={ref}
|
|
259
273
|
menuPortalTarget={menuPortalTarget}
|
|
260
274
|
menuPlacement={"auto"}
|
|
261
|
-
styles={
|
|
262
|
-
componentsStyles as unknown as StylesConfig<Option, IsMulti, Group>,
|
|
263
|
-
styles,
|
|
264
|
-
])}
|
|
275
|
+
styles={combinedStyles}
|
|
265
276
|
isMulti={isCollectionMode}
|
|
266
277
|
backspaceRemovesValue={isCollectionMode}
|
|
267
278
|
tabSelectsValue={false}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
+
import {useControllableState} from "@fibery/react/src/use-controllable-state";
|
|
1
2
|
import {css, cx} from "@linaria/core";
|
|
2
|
-
import {border, space, textStyles} from "../design-system";
|
|
3
|
-
import {inputOverrides} from "../antd/styles";
|
|
4
3
|
import React, {
|
|
5
4
|
ComponentProps,
|
|
6
5
|
ComponentType,
|
|
@@ -13,8 +12,12 @@ import React, {
|
|
|
13
12
|
useRef,
|
|
14
13
|
useState,
|
|
15
14
|
} from "react";
|
|
15
|
+
import {inputOverrides} from "../antd/styles";
|
|
16
|
+
import {border, space, textStyles} from "../design-system";
|
|
16
17
|
import {Popup} from "../popup";
|
|
17
18
|
import {$TSFixMe} from "../tsfixme";
|
|
19
|
+
import {useIsPhone} from "../use-is-phone";
|
|
20
|
+
import {Menu} from "./custom-select-partials/menu";
|
|
18
21
|
import {
|
|
19
22
|
ActionMeta,
|
|
20
23
|
combineStyles,
|
|
@@ -27,9 +30,6 @@ import {
|
|
|
27
30
|
StylesConfig,
|
|
28
31
|
} from "./index";
|
|
29
32
|
import {SelectControlSettingsProvider} from "./select-control-settings-context";
|
|
30
|
-
import {Menu} from "./custom-select-partials/menu";
|
|
31
|
-
import {useIsPhone} from "../use-is-phone";
|
|
32
|
-
import {useControllableState} from "@fibery/react/src/use-controllable-state";
|
|
33
33
|
|
|
34
34
|
const offset = [0, space.s4] as [number, number];
|
|
35
35
|
const popupHeightVH = 45;
|
|
@@ -53,10 +53,6 @@ const popupContainerClassName = css`
|
|
|
53
53
|
const popupClassName = css`
|
|
54
54
|
min-width: 320px;
|
|
55
55
|
max-width: 440px;
|
|
56
|
-
padding-top: ${popupPaddingTop}px;
|
|
57
|
-
padding-bottom: ${popupPaddingBottom}px;
|
|
58
|
-
padding-left: ${space.s8}px;
|
|
59
|
-
padding-right: ${space.s8}px;
|
|
60
56
|
`;
|
|
61
57
|
const mobileClassName = css`
|
|
62
58
|
padding-top: ${space.s12}px;
|
|
@@ -85,10 +81,8 @@ const valueClassName = css`
|
|
|
85
81
|
|
|
86
82
|
const titleClassName = css`
|
|
87
83
|
${textStyles.heading6}
|
|
88
|
-
padding-top: ${space.
|
|
89
|
-
padding-
|
|
90
|
-
padding-right: ${space.s8}px;
|
|
91
|
-
padding-bottom: ${space.s12}px;
|
|
84
|
+
padding-top: ${space.s12}px;
|
|
85
|
+
padding-inline: ${space.s12}px;
|
|
92
86
|
`;
|
|
93
87
|
|
|
94
88
|
export const valueMaxHeight = 116;
|
|
@@ -98,6 +92,8 @@ export const selectInPopupStyles = {
|
|
|
98
92
|
...props,
|
|
99
93
|
minWidth: 180,
|
|
100
94
|
width: "100%",
|
|
95
|
+
paddingTop: space.s6,
|
|
96
|
+
paddingInline: space.s6,
|
|
101
97
|
}),
|
|
102
98
|
option: (props: $TSFixMe) => ({
|
|
103
99
|
...props,
|
|
@@ -110,13 +106,16 @@ export const selectInPopupStyles = {
|
|
|
110
106
|
...props,
|
|
111
107
|
maxHeight: valueMaxHeight,
|
|
112
108
|
overflow: "auto",
|
|
109
|
+
margin: space.s2,
|
|
110
|
+
marginBottom: space.s4,
|
|
111
|
+
width: `calc(100% - ${space.s2 * 2}px)`,
|
|
112
|
+
borderRadius: border.radius4,
|
|
113
113
|
}),
|
|
114
114
|
menu: (props: $TSFixMe) => ({
|
|
115
115
|
...props,
|
|
116
116
|
minWidth: 100,
|
|
117
117
|
position: "static",
|
|
118
|
-
|
|
119
|
-
marginBottom: 0,
|
|
118
|
+
marginBlock: 0,
|
|
120
119
|
boxShadow: "none !important",
|
|
121
120
|
borderRadius: border.radius4,
|
|
122
121
|
}),
|
|
@@ -169,12 +168,12 @@ type Props<Option, IsMulti extends boolean, Group extends GroupBase<Option>> = {
|
|
|
169
168
|
renderValue?: () => ReactNode;
|
|
170
169
|
title?: string;
|
|
171
170
|
maxMenuHeight?: number;
|
|
172
|
-
hideOnChange?: boolean;
|
|
171
|
+
hideOnChange?: boolean | ((newValue: OnChangeValue<Option, IsMulti>, actionMeta: ActionMeta<Option>) => boolean);
|
|
173
172
|
renderInPortal?: boolean;
|
|
174
173
|
popupStyles?: string;
|
|
175
174
|
selectStyles?: StylesConfig<Option, IsMulti, Group>;
|
|
176
175
|
formatGroupLabel?: (group: Group) => ReactNode;
|
|
177
|
-
formatOptionLabel?: (option: Option) => ReactNode;
|
|
176
|
+
formatOptionLabel?: (option: Option, {context}: {context: "menu" | "value"}) => ReactNode;
|
|
178
177
|
components?: ComponentsConfig;
|
|
179
178
|
onInputChange?: (s: string, actionType: {action: string}) => void;
|
|
180
179
|
onFocus?: () => void;
|
|
@@ -183,6 +182,8 @@ type Props<Option, IsMulti extends boolean, Group extends GroupBase<Option>> = {
|
|
|
183
182
|
onMenuClose?: () => void | boolean;
|
|
184
183
|
getPopupContainer?: () => HTMLElement;
|
|
185
184
|
onSelectKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
|
|
185
|
+
forbidValuesClearInCollnMode?: boolean;
|
|
186
|
+
otherSelectProps?: Record<string, unknown>;
|
|
186
187
|
};
|
|
187
188
|
|
|
188
189
|
function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends GroupBase<Option>>(
|
|
@@ -219,6 +220,8 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
219
220
|
onMenuClose,
|
|
220
221
|
getPopupContainer,
|
|
221
222
|
onSelectKeyDown,
|
|
223
|
+
otherSelectProps,
|
|
224
|
+
forbidValuesClearInCollnMode,
|
|
222
225
|
} = props;
|
|
223
226
|
const [triggerElement, setTriggerElement] = useState<HTMLDivElement | null>(null);
|
|
224
227
|
const [visible, setVisible] = useControllableState({
|
|
@@ -280,6 +283,10 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
280
283
|
}, [visible]);
|
|
281
284
|
|
|
282
285
|
const onShow = useCallback(() => {
|
|
286
|
+
if (disabled) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
283
290
|
if (blurTimeoutRef.current) {
|
|
284
291
|
clearTimeout(blurTimeoutRef.current);
|
|
285
292
|
}
|
|
@@ -287,7 +294,7 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
287
294
|
if (onMenuOpen) {
|
|
288
295
|
onMenuOpen();
|
|
289
296
|
}
|
|
290
|
-
}, [onMenuOpen, setVisible]);
|
|
297
|
+
}, [disabled, onMenuOpen, setVisible]);
|
|
291
298
|
|
|
292
299
|
const styles = useMemo(() => {
|
|
293
300
|
return combineStyles<Option, IsMulti, Group>([selectInPopupStyles, selectStyles]);
|
|
@@ -385,7 +392,11 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
385
392
|
closeMenuOnScroll={false}
|
|
386
393
|
closeMenuOnSelect={false}
|
|
387
394
|
onChange={(newValue, actionMeta) => {
|
|
388
|
-
if (hideOnChange) {
|
|
395
|
+
if (typeof hideOnChange === "function") {
|
|
396
|
+
if (hideOnChange(newValue, actionMeta)) {
|
|
397
|
+
onHide();
|
|
398
|
+
}
|
|
399
|
+
} else if (hideOnChange) {
|
|
389
400
|
onHide();
|
|
390
401
|
}
|
|
391
402
|
onChange(newValue, actionMeta);
|
|
@@ -405,11 +416,13 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
|
|
|
405
416
|
isClearable={!isCollectionMode && isClearable}
|
|
406
417
|
formatGroupLabel={formatGroupLabel}
|
|
407
418
|
formatOptionLabel={formatOptionLabel}
|
|
419
|
+
{...otherSelectProps}
|
|
408
420
|
components={{
|
|
409
421
|
DropdownIndicator: null,
|
|
410
422
|
IndicatorSeparator: null,
|
|
411
423
|
Menu: mergedComponents.Menu as $TSFixMe,
|
|
412
424
|
}}
|
|
425
|
+
forbidValuesClearInCollnMode={forbidValuesClearInCollnMode}
|
|
413
426
|
/>
|
|
414
427
|
</SelectControlSettingsProvider>
|
|
415
428
|
</Popup>
|
package/src/select/styles.ts
CHANGED
|
@@ -2,9 +2,9 @@ import {css} from "@linaria/core";
|
|
|
2
2
|
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
|
-
import {OptionNulledStyles, OptionNulledVitualizedStyles} from "./custom-select-partials/option";
|
|
6
|
-
import {MenuListNulledStyles, MenuNulledStyles} from "./custom-select-partials/menu";
|
|
7
5
|
import {groupHeadingNulledStyles} from "./custom-select-partials/group-heading";
|
|
6
|
+
import {MenuListNulledStyles, MenuNulledStyles} from "./custom-select-partials/menu";
|
|
7
|
+
import {OptionNulledStyles, OptionNulledVitualizedStyles} from "./custom-select-partials/option";
|
|
8
8
|
|
|
9
9
|
export const expanderExpandedStyle = css`
|
|
10
10
|
transform: rotate(180deg);
|
|
@@ -50,6 +50,14 @@ export const virtualizedStyles: StylesConfig = {
|
|
|
50
50
|
}),
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
+
export const nonVirtualizedStyles: StylesConfig = {
|
|
54
|
+
menuList: (provided) => ({
|
|
55
|
+
...provided,
|
|
56
|
+
paddingTop: 6,
|
|
57
|
+
paddingBottom: 6,
|
|
58
|
+
}),
|
|
59
|
+
};
|
|
60
|
+
|
|
53
61
|
export const zIndexStyles = (zIndex: number): StylesConfig => ({
|
|
54
62
|
menuPortal: (provided) => ({
|
|
55
63
|
...provided,
|
package/src/toast/primitives.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import {css, cx} from "@linaria/core";
|
|
|
3
3
|
import * as ToastPrimitives from "@radix-ui/react-toast";
|
|
4
4
|
import {ElementRef, forwardRef} from "react";
|
|
5
5
|
import {IconButton} from "../button/icon-button";
|
|
6
|
-
import {border, space, textStyles, themeVars} from "../design-system";
|
|
6
|
+
import {border, space, textStyles, themeVars, transition} from "../design-system";
|
|
7
7
|
import CloseIcon from "../icons/react/Close";
|
|
8
8
|
|
|
9
9
|
const viewportCss = css`
|
|
@@ -21,6 +21,8 @@ const viewportCss = css`
|
|
|
21
21
|
padding: 0;
|
|
22
22
|
list-style: none;
|
|
23
23
|
|
|
24
|
+
transition: bottom ${transition}; // bottom may change dynamically
|
|
25
|
+
|
|
24
26
|
&:not(:empty) {
|
|
25
27
|
padding: ${space.s24}px; // increased mouse hover area to pause timers of toast
|
|
26
28
|
}
|
package/src/toast/toast-queue.ts
CHANGED
|
@@ -13,6 +13,11 @@ type QueuedToast = AddToastProps & {
|
|
|
13
13
|
id: string;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
type BottomOffsetRequest = {
|
|
17
|
+
id: string;
|
|
18
|
+
bottomOffset: number;
|
|
19
|
+
};
|
|
20
|
+
|
|
16
21
|
type ToastQueueOpts = {
|
|
17
22
|
maxActiveToasts?: number;
|
|
18
23
|
onToastAdd?: (params: AddToastProps) => void;
|
|
@@ -27,6 +32,7 @@ export const makeToastQueue = ({maxActiveToasts = 1, onToastAdd, transformToast}
|
|
|
27
32
|
const pubSub = makePubSub();
|
|
28
33
|
let queue: QueuedToast[] = [];
|
|
29
34
|
let activeToasts: QueuedToast[] = [];
|
|
35
|
+
let bottomOffsets: BottomOffsetRequest[] = [];
|
|
30
36
|
|
|
31
37
|
let count = 0;
|
|
32
38
|
|
|
@@ -87,6 +93,22 @@ export const makeToastQueue = ({maxActiveToasts = 1, onToastAdd, transformToast}
|
|
|
87
93
|
getActiveToasts() {
|
|
88
94
|
return activeToasts;
|
|
89
95
|
},
|
|
96
|
+
addBottomOffset: (bottomOffset: number) => {
|
|
97
|
+
const id = `${Math.random()}`;
|
|
98
|
+
bottomOffsets.push({id, bottomOffset});
|
|
99
|
+
pubSub.publish();
|
|
100
|
+
|
|
101
|
+
return () => {
|
|
102
|
+
bottomOffsets = bottomOffsets.filter((v) => v.id !== id);
|
|
103
|
+
pubSub.publish();
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
getBottomOffset() {
|
|
107
|
+
if (bottomOffsets.length === 0) {
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
return Math.max(...bottomOffsets.map((v) => v.bottomOffset));
|
|
111
|
+
},
|
|
90
112
|
subscribe: pubSub.subscribe,
|
|
91
113
|
unsubscribe: pubSub.unsubscribe,
|
|
92
114
|
|
package/src/toast/toaster.tsx
CHANGED
|
@@ -24,6 +24,7 @@ export const Toaster: React.FC = () => {
|
|
|
24
24
|
const toastQueue = useToast();
|
|
25
25
|
|
|
26
26
|
const toasts = useSyncExternalStore(toastQueue.subscribe, toastQueue.getActiveToasts);
|
|
27
|
+
const bottomOffset = useSyncExternalStore(toastQueue.subscribe, toastQueue.getBottomOffset);
|
|
27
28
|
|
|
28
29
|
return (
|
|
29
30
|
<ToastThemeProvider>
|
|
@@ -45,7 +46,7 @@ export const Toaster: React.FC = () => {
|
|
|
45
46
|
/>
|
|
46
47
|
))}
|
|
47
48
|
|
|
48
|
-
<ToastViewport id={viewportId} />
|
|
49
|
+
<ToastViewport id={viewportId} style={{bottom: bottomOffset}} />
|
|
49
50
|
</ToastThemeProvider>
|
|
50
51
|
);
|
|
51
52
|
};
|
package/src/tooltip.tsx
CHANGED
|
@@ -4,6 +4,8 @@ import {forwardRef, type ReactNode, type SyntheticEvent} from "react";
|
|
|
4
4
|
import {border, fontWeight, lineHeight, space, themeVars, tooltipDelay} from "./design-system";
|
|
5
5
|
import {ShortcutBadge} from "./shortcut-badge";
|
|
6
6
|
|
|
7
|
+
const isFlagPresent = (flag: string) => new RegExp(`[?&]${flag}\\b`).test(window.location.search);
|
|
8
|
+
|
|
7
9
|
const preventDefaultAndStopPropagation = (e: SyntheticEvent) => {
|
|
8
10
|
e.preventDefault();
|
|
9
11
|
e.stopPropagation();
|
|
@@ -114,6 +116,11 @@ export type TooltipProps = Omit<TooltipPrimitive.TooltipTriggerProps, "title"> &
|
|
|
114
116
|
visible?: boolean;
|
|
115
117
|
onVisibleChange?: (visible: boolean) => void;
|
|
116
118
|
disabled?: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* When `false`, allows to hover the content without closing the tooltip.
|
|
121
|
+
* @defaultValue trues
|
|
122
|
+
*/
|
|
123
|
+
disableHoverableContent?: boolean;
|
|
117
124
|
/** should keep tooltip visible after click */
|
|
118
125
|
keepOnClick?: boolean;
|
|
119
126
|
};
|
|
@@ -152,6 +159,7 @@ export const Tooltip = forwardRef<HTMLButtonElement, TooltipProps>(
|
|
|
152
159
|
setContentElement,
|
|
153
160
|
container,
|
|
154
161
|
tooltipContentStyle,
|
|
162
|
+
disableHoverableContent,
|
|
155
163
|
...triggerProps
|
|
156
164
|
},
|
|
157
165
|
ref
|
|
@@ -169,11 +177,16 @@ export const Tooltip = forwardRef<HTMLButtonElement, TooltipProps>(
|
|
|
169
177
|
}
|
|
170
178
|
: null;
|
|
171
179
|
|
|
180
|
+
if (isFlagPresent("no-tooltips")) {
|
|
181
|
+
return <>{children}</>;
|
|
182
|
+
}
|
|
183
|
+
|
|
172
184
|
return (
|
|
173
185
|
<TooltipPrimitive.Root
|
|
174
186
|
delayDuration={instant ? 0 : tooltipDelay.enter}
|
|
175
187
|
open={disabled ? false : Boolean(content) && visible}
|
|
176
188
|
onOpenChange={onVisibleChange}
|
|
189
|
+
disableHoverableContent={disableHoverableContent}
|
|
177
190
|
>
|
|
178
191
|
<TooltipPrimitive.Trigger ref={ref} {...triggerProps} {...keepOnClickProps} asChild>
|
|
179
192
|
{children}
|