@fibery/ui-kit 1.15.0 → 1.17.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 +8 -6
- package/src/Button/actions-button-compact.tsx +13 -0
- package/src/Button/actions-button.tsx +30 -0
- package/src/Button/button-base.tsx +2 -12
- package/src/Button/button.tsx +3 -34
- package/src/Select/components.tsx +6 -0
- package/src/Select/styles.ts +9 -4
- package/src/antd/styles.ts +5 -5
- package/src/designSystem.ts +11 -26
- package/src/emoji-picker/app-icon-picker.tsx +31 -26
- package/src/emoji-picker/emoji-picker-content-with-color.tsx +110 -0
- package/src/emoji-picker/emoji-picker.tsx +34 -39
- package/src/emoji-picker/icon-emoji-picker.tsx +3 -14
- package/src/emoji-picker/primitives/category.tsx +82 -25
- package/src/emoji-picker/primitives/emoji.tsx +7 -49
- package/src/emoji-picker/primitives/footer.tsx +3 -1
- package/src/emoji-picker/primitives/grid.tsx +56 -24
- package/src/emoji-picker/primitives/search.tsx +21 -11
- package/src/emoji-picker/primitives/skin-tone.tsx +18 -12
- package/src/emoji-picker/stores/emoji-data-store.tsx +0 -1
- package/src/emoji-picker/stores/lazy-icon-data-store.tsx +19 -30
- package/src/icons/ast/AiAssistant.ts +1 -1
- package/src/icons/ast/AiAvatar.ts +1 -1
- package/src/icons/ast/AppDetails.ts +1 -1
- package/src/icons/ast/AppTemplates.ts +1 -1
- package/src/icons/ast/BellCircle.ts +8 -0
- package/src/icons/ast/BellX.ts +8 -0
- package/src/icons/ast/Bolt.ts +8 -0
- package/src/icons/ast/CheckCircle.ts +8 -0
- package/src/icons/ast/ClockForward.ts +8 -0
- package/src/icons/ast/ColorCodingFilled.ts +8 -0
- package/src/icons/ast/Delete.ts +1 -1
- package/src/icons/ast/EmojiDelete.ts +8 -0
- package/src/icons/ast/ExtensionAssignments.ts +1 -1
- package/src/icons/ast/Fields.ts +1 -1
- package/src/icons/ast/Figma.ts +8 -0
- package/src/icons/ast/FocusMode.ts +1 -1
- package/src/icons/ast/GoogleDrive.ts +8 -0
- package/src/icons/ast/GoogleMap.ts +8 -0
- package/src/icons/ast/InvitePeople.ts +1 -1
- package/src/icons/ast/Loom.ts +8 -0
- package/src/icons/ast/Miro.ts +8 -0
- package/src/icons/ast/Mixpanel.ts +8 -0
- package/src/icons/ast/RicheditorBlockCode.ts +1 -1
- package/src/icons/ast/RicheditorBlockEmbed.ts +8 -0
- package/src/icons/ast/RicheditorImageZoom.ts +1 -1
- package/src/icons/ast/RicheditorMarkCode.ts +1 -1
- package/src/icons/ast/RicheditorOpenLink.ts +1 -1
- package/src/icons/ast/Shared.ts +1 -1
- package/src/icons/ast/Twitter.ts +8 -0
- package/src/icons/ast/Youtube.ts +8 -0
- package/src/icons/ast/index.tsx +16 -0
- package/src/icons/react/BellCircle.tsx +12 -0
- package/src/icons/react/BellX.tsx +12 -0
- package/src/icons/react/Bolt.tsx +12 -0
- package/src/icons/react/CheckCircle.tsx +12 -0
- package/src/icons/react/ClockForward.tsx +12 -0
- package/src/icons/react/ColorCodingFilled.tsx +12 -0
- package/src/icons/react/EmojiDelete.tsx +12 -0
- package/src/icons/react/Figma.tsx +12 -0
- package/src/icons/react/GoogleDrive.tsx +12 -0
- package/src/icons/react/GoogleMap.tsx +12 -0
- package/src/icons/react/Loom.tsx +12 -0
- package/src/icons/react/Miro.tsx +12 -0
- package/src/icons/react/Mixpanel.tsx +12 -0
- package/src/icons/react/RicheditorBlockEmbed.tsx +12 -0
- package/src/icons/react/Twitter.tsx +12 -0
- package/src/icons/react/Youtube.tsx +12 -0
- package/src/icons/react/index.tsx +16 -0
- package/src/tooltip.tsx +75 -53
- package/src/Button/icon-button-with-tooltip.tsx +0 -15
- package/src/emoji-picker/index.tsx +0 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fibery/ui-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"main": "index.ts",
|
|
5
5
|
"private": false,
|
|
6
6
|
"files": [
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"chroma-js": "2.1.2",
|
|
41
41
|
"chrono-node": "^2.4.1",
|
|
42
42
|
"classnames": "2.3.1",
|
|
43
|
+
"cmdk": "0.2.0",
|
|
43
44
|
"color-hash": "1.0.3",
|
|
44
45
|
"d3-shape": "1.3.7",
|
|
45
46
|
"date-fns": "^2.29.2",
|
|
@@ -53,15 +54,16 @@
|
|
|
53
54
|
"rc-progress": "3.4.1",
|
|
54
55
|
"react-color": "2.19.3",
|
|
55
56
|
"react-day-picker": "8.1.4",
|
|
57
|
+
"react-intersection-observer": "9.3.5",
|
|
56
58
|
"react-popper": "2.3.0",
|
|
57
59
|
"react-select": "5.3.2",
|
|
58
60
|
"react-select-country-list": "2.2.1",
|
|
59
61
|
"react-windowed-select": "5.0.0",
|
|
60
62
|
"screenfull": "6.0.1",
|
|
61
63
|
"ua-parser-js": "0.7.24",
|
|
62
|
-
"@fibery/
|
|
64
|
+
"@fibery/emoji-data": "2.1.1",
|
|
63
65
|
"@fibery/helpers": "1.1.0",
|
|
64
|
-
"@fibery/
|
|
66
|
+
"@fibery/react": "1.0.3"
|
|
65
67
|
},
|
|
66
68
|
"peerDependencies": {
|
|
67
69
|
"react": "^18.2.0",
|
|
@@ -91,10 +93,10 @@
|
|
|
91
93
|
"react-dom": "18.2.0",
|
|
92
94
|
"svg-parser": "2.0.4",
|
|
93
95
|
"svgo": "2.8.0",
|
|
94
|
-
"typescript": "5.
|
|
96
|
+
"typescript": "5.1.6",
|
|
95
97
|
"unist-util-reduce": "0.2.2",
|
|
96
|
-
"@fibery/
|
|
97
|
-
"@fibery/
|
|
98
|
+
"@fibery/babel-preset": "7.2.0",
|
|
99
|
+
"@fibery/eslint-config": "8.3.0"
|
|
98
100
|
},
|
|
99
101
|
"jest": {
|
|
100
102
|
"testEnvironment": "jsdom",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {IconButton, IconButtonProps} from "./icon-button";
|
|
2
|
+
import MoreCompactIcon from "../icons/react/MoreCompact";
|
|
3
|
+
import {forwardRef} from "react";
|
|
4
|
+
|
|
5
|
+
export const ActionsButtonCompact = forwardRef<HTMLButtonElement, IconButtonProps>(
|
|
6
|
+
function ActionsButtonCompactComponent({...rest}, ref) {
|
|
7
|
+
return (
|
|
8
|
+
<IconButton ref={ref} size="small" {...rest}>
|
|
9
|
+
<MoreCompactIcon iconSize={18} containerSize={20} />
|
|
10
|
+
</IconButton>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {IconButton, IconButtonProps} from "./icon-button";
|
|
2
|
+
import MoreCompact from "../icons/react/MoreCompact";
|
|
3
|
+
import {forwardRef} from "react";
|
|
4
|
+
import {css} from "@linaria/core";
|
|
5
|
+
import {border, themeVars} from "../designSystem";
|
|
6
|
+
|
|
7
|
+
export const ActionsButton = forwardRef<HTMLButtonElement, IconButtonProps>(function ActionsButtonComponent(
|
|
8
|
+
{...rest},
|
|
9
|
+
ref
|
|
10
|
+
) {
|
|
11
|
+
return (
|
|
12
|
+
<IconButton ref={ref} size="normal" {...rest}>
|
|
13
|
+
<MoreCompact iconSize={18} containerSize={20} />
|
|
14
|
+
</IconButton>
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// TODO: Shoud be a variant inside button?
|
|
19
|
+
export const actionButtonInlineStyle = css`
|
|
20
|
+
background-color: ${themeVars.actionMenuButtonColor};
|
|
21
|
+
box-shadow: ${themeVars.entityCardShadow};
|
|
22
|
+
border-radius: ${border.radius6};
|
|
23
|
+
|
|
24
|
+
.Button:hover {
|
|
25
|
+
background-color: ${themeVars.actionMenuButtonHoverColor} !important;
|
|
26
|
+
}
|
|
27
|
+
.Button:focus {
|
|
28
|
+
background-color: ${themeVars.actionMenuButtonHoverColor} !important;
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
@@ -143,14 +143,13 @@ const StyledButtonBase = styled.button<StyledProps>`
|
|
|
143
143
|
`;
|
|
144
144
|
|
|
145
145
|
export type ButtonBaseProps = {
|
|
146
|
-
dataId?: string;
|
|
147
146
|
color?: string;
|
|
148
147
|
primary?: boolean;
|
|
149
148
|
dangerous?: boolean;
|
|
150
149
|
borderless?: boolean;
|
|
151
150
|
} & ComponentPropsWithoutRef<"button">;
|
|
152
151
|
export const ButtonBase = forwardRef<HTMLButtonElement, ButtonBaseProps>(function ButtonBase(
|
|
153
|
-
{primary, color, borderless, dangerous, className, type = "button",
|
|
152
|
+
{primary, color, borderless, dangerous, className, type = "button", ...buttonProps},
|
|
154
153
|
ref
|
|
155
154
|
) {
|
|
156
155
|
const theme = useTheme();
|
|
@@ -177,14 +176,5 @@ export const ButtonBase = forwardRef<HTMLButtonElement, ButtonBaseProps>(functio
|
|
|
177
176
|
borderWidth,
|
|
178
177
|
};
|
|
179
178
|
|
|
180
|
-
return
|
|
181
|
-
<StyledButtonBase
|
|
182
|
-
ref={ref}
|
|
183
|
-
type={type}
|
|
184
|
-
className={className}
|
|
185
|
-
data-testid={dataId}
|
|
186
|
-
{...styledProps}
|
|
187
|
-
{...buttonProps}
|
|
188
|
-
/>
|
|
189
|
-
);
|
|
179
|
+
return <StyledButtonBase ref={ref} type={type} className={className} {...styledProps} {...buttonProps} />;
|
|
190
180
|
});
|
package/src/Button/button.tsx
CHANGED
|
@@ -4,14 +4,12 @@ import {styled} from "@linaria/react";
|
|
|
4
4
|
import cx from "classnames";
|
|
5
5
|
import _ from "lodash";
|
|
6
6
|
import React, {forwardRef} from "react";
|
|
7
|
-
import {
|
|
7
|
+
import {Item} from "../Item";
|
|
8
|
+
import {useTheme} from "../ThemeProvider";
|
|
8
9
|
import {border, colors, getOpacities, opacity, space, textStyles} from "../designSystem";
|
|
9
|
-
import MoreIcon from "../icons/react/More";
|
|
10
|
-
import MoreCompactIcon from "../icons/react/MoreCompact";
|
|
11
10
|
import {IconBaseProps} from "../icons/types";
|
|
12
|
-
import {Item} from "../Item";
|
|
13
11
|
import {Spinner} from "../loaders";
|
|
14
|
-
import {
|
|
12
|
+
import {ButtonBase, ButtonBaseProps, buttonBorderWidth, getMainColor, getTextColor} from "./button-base";
|
|
15
13
|
|
|
16
14
|
type PositionInGroup = "first" | "middle" | "last";
|
|
17
15
|
|
|
@@ -218,32 +216,3 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
|
|
|
218
216
|
</StyledButton>
|
|
219
217
|
);
|
|
220
218
|
});
|
|
221
|
-
|
|
222
|
-
// TODO can be inlined
|
|
223
|
-
export function ActionsButton({
|
|
224
|
-
onClick,
|
|
225
|
-
label = ``,
|
|
226
|
-
disabled,
|
|
227
|
-
}: {
|
|
228
|
-
onClick: ButtonProps["onClick"];
|
|
229
|
-
label?: string;
|
|
230
|
-
disabled?: boolean;
|
|
231
|
-
}) {
|
|
232
|
-
return <Button Icon={MoreIcon} onClick={onClick} borderless aria-label={label} disabled={disabled} />;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
export const ActionsButtonCompact = forwardRef<HTMLButtonElement, ButtonProps & {inverted?: boolean}>(
|
|
236
|
-
({inverted, ...rest}, ref) => {
|
|
237
|
-
const theme = useTheme();
|
|
238
|
-
return (
|
|
239
|
-
<Button
|
|
240
|
-
ref={ref}
|
|
241
|
-
size={":button-size/small"}
|
|
242
|
-
Icon={MoreCompactIcon}
|
|
243
|
-
color={inverted ? colors.inversedTextColor : theme.buttonColor}
|
|
244
|
-
borderless
|
|
245
|
-
{...rest}
|
|
246
|
-
/>
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
);
|
|
@@ -28,6 +28,9 @@ export function DropdownIndicator<
|
|
|
28
28
|
IsMulti extends boolean = boolean,
|
|
29
29
|
Group extends GroupBase<TOption> = GroupBase<TOption>
|
|
30
30
|
>(props: DropdownIndicatorProps<TOption, IsMulti, Group>) {
|
|
31
|
+
if (props.selectProps.isDisabled) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
31
34
|
return (
|
|
32
35
|
<div className={cn(expanderStyle, props.selectProps.menuIsOpen && expanderExpandedStyle)}>
|
|
33
36
|
<ArrowCollapseVertical color={themeVars.disabledTextColor} />
|
|
@@ -43,6 +46,9 @@ export function ClearIndicator<
|
|
|
43
46
|
innerProps,
|
|
44
47
|
selectProps,
|
|
45
48
|
}: ClearIndicatorProps<TOption, IsMulti, Group> | MultiValueRemoveProps<TOption, IsMulti, Group>) {
|
|
49
|
+
if (selectProps.isDisabled) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
46
52
|
return (
|
|
47
53
|
<div {...innerProps}>
|
|
48
54
|
<Button borderless Icon={RemoveIcon} disabled={selectProps.isDisabled} size={":button-size/super-small"} />
|
package/src/Select/styles.ts
CHANGED
|
@@ -165,10 +165,15 @@ export const componentsStyles: StylesConfig = {
|
|
|
165
165
|
cursor: state.isDisabled ? "not-allowed" : "default",
|
|
166
166
|
}),
|
|
167
167
|
indicatorSeparator: () => ({}),
|
|
168
|
-
input: (provided) =>
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
168
|
+
input: (provided, state) => {
|
|
169
|
+
if (state.isDisabled) {
|
|
170
|
+
return {display: "none"};
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
...provided,
|
|
174
|
+
color: themeVars.textColor,
|
|
175
|
+
};
|
|
176
|
+
},
|
|
172
177
|
};
|
|
173
178
|
|
|
174
179
|
export const singleLineComponentsStyle: StylesConfig = {
|
package/src/antd/styles.ts
CHANGED
|
@@ -22,7 +22,7 @@ export const inputOverrides = {
|
|
|
22
22
|
font: "inherit",
|
|
23
23
|
color: themeVars.textColor,
|
|
24
24
|
outline: "none",
|
|
25
|
-
backgroundColor: themeVars.inputBgColor
|
|
25
|
+
backgroundColor: `${themeVars.inputBgColor} !important`,
|
|
26
26
|
borderRadius: border.radius6,
|
|
27
27
|
minHeight: layout.inputHeight,
|
|
28
28
|
paddingTop: 0,
|
|
@@ -32,22 +32,22 @@ export const inputOverrides = {
|
|
|
32
32
|
border: 0,
|
|
33
33
|
borderColor: colors.transparent,
|
|
34
34
|
transition: `box-shadow ${transition}`,
|
|
35
|
-
boxShadow:
|
|
35
|
+
boxShadow: `var(--input-border, ${themeVars.inputBorderColor})`,
|
|
36
36
|
letterSpacing: 0,
|
|
37
37
|
"::placeholder": {
|
|
38
38
|
color: themeVars.inputPlaceholderTextColor,
|
|
39
39
|
},
|
|
40
40
|
},
|
|
41
41
|
hover: {
|
|
42
|
-
boxShadow:
|
|
42
|
+
boxShadow: `var(--input-hover-border, 0 0 0 1px ${themeVars.opacity.opacity40}) !important`,
|
|
43
43
|
transition: `box-shadow ${transition}`,
|
|
44
44
|
},
|
|
45
45
|
focus: {
|
|
46
|
-
boxShadow:
|
|
46
|
+
boxShadow: `var(--input-focus-border, 0 0 0 1px ${themeVars.opacity.opacity25}), var(--input-focus-shadow, 0 0 0 3px ${themeVars.focus}) !important`,
|
|
47
47
|
transition: `box-shadow ${transition}`,
|
|
48
48
|
},
|
|
49
49
|
disabled: {
|
|
50
|
-
color: `${themeVars.
|
|
50
|
+
color: `${themeVars.textColor}`,
|
|
51
51
|
backgroundColor: `${themeVars.inputDisabledBgColor} !important`,
|
|
52
52
|
borderColor: colors.transparent,
|
|
53
53
|
boxShadow: `${themeVars.inputDisabledBorderColor} !important`,
|
package/src/designSystem.ts
CHANGED
|
@@ -61,7 +61,7 @@ const makeChromaColor = (color: string) => {
|
|
|
61
61
|
try {
|
|
62
62
|
return chroma(color);
|
|
63
63
|
} catch (e) {
|
|
64
|
-
return chroma(brandColors.
|
|
64
|
+
return chroma(brandColors.blue);
|
|
65
65
|
}
|
|
66
66
|
};
|
|
67
67
|
|
|
@@ -103,7 +103,7 @@ const brandColors = {
|
|
|
103
103
|
} as const;
|
|
104
104
|
|
|
105
105
|
export const getDarkenColor = _.memoize((color: string): string => {
|
|
106
|
-
return makeChromaColor(color).darken(0.
|
|
106
|
+
return makeChromaColor(color).darken(0.6).css();
|
|
107
107
|
});
|
|
108
108
|
|
|
109
109
|
const lightColors = {
|
|
@@ -245,6 +245,8 @@ const lightColors = {
|
|
|
245
245
|
filterGroup1Bg: slate.slate2,
|
|
246
246
|
filterGroup2Bg: slate.slate3,
|
|
247
247
|
filterGroupBorder: blackA.blackA3,
|
|
248
|
+
colorBgNotificationFocusedDefault: indigo.indigo3,
|
|
249
|
+
colorBgNotificationFocusedHover: indigo.indigo4,
|
|
248
250
|
//end
|
|
249
251
|
disabledInversedTextColor: shades.opacity25,
|
|
250
252
|
danger: red.red9,
|
|
@@ -370,7 +372,7 @@ const darkColors = {
|
|
|
370
372
|
}`,
|
|
371
373
|
separatorColor: getOpacities(slateDark.slate8).opacity50,
|
|
372
374
|
separatorBreadcrumbsColor: slateDark.slate8,
|
|
373
|
-
iconColor:
|
|
375
|
+
iconColor: slateDark.slate10,
|
|
374
376
|
appIconColor: getOpacities(slate.slate2).opacity70,
|
|
375
377
|
mentionBgColor: slateDark.slate5,
|
|
376
378
|
entityCardBgColor: slateDark.slate5,
|
|
@@ -430,6 +432,8 @@ const darkColors = {
|
|
|
430
432
|
filterGroup1Bg: slateDark.slate6,
|
|
431
433
|
filterGroup2Bg: slateDark.slate7,
|
|
432
434
|
filterGroupBorder: whiteA.whiteA3,
|
|
435
|
+
colorBgNotificationFocusedDefault: getOpacities(indigoDark.indigo11).opacity20,
|
|
436
|
+
colorBgNotificationFocusedHover: getOpacities(indigoDark.indigo11).opacity30,
|
|
433
437
|
//end
|
|
434
438
|
disabledInversedTextColor: lights.opacity25,
|
|
435
439
|
danger: redDark.red10,
|
|
@@ -579,11 +583,7 @@ export const getThemeColors: (themeColor: string, theme: ThemeMode) => ThemeColo
|
|
|
579
583
|
);
|
|
580
584
|
|
|
581
585
|
export const getTextColor = _.memoize((color: string): string => {
|
|
582
|
-
return makeChromaColor(color).
|
|
583
|
-
});
|
|
584
|
-
|
|
585
|
-
export const getBrightenColor = _.memoize((color: string): string => {
|
|
586
|
-
return makeChromaColor(color).brighten(0.15).hex();
|
|
586
|
+
return makeChromaColor(color).hex();
|
|
587
587
|
});
|
|
588
588
|
|
|
589
589
|
export const getLinkedHighlightBackgroundColor = _.memoize(
|
|
@@ -600,24 +600,11 @@ export const getLinkedHighlightBackgroundColor = _.memoize(
|
|
|
600
600
|
(themeMode, color) => `${themeMode}-${color}`
|
|
601
601
|
);
|
|
602
602
|
|
|
603
|
-
// REMOVE AFTER MIGRATION ON BACKEND
|
|
604
|
-
export const migrateEnumColor = (color: string) => {
|
|
605
|
-
const pastelIdx = pastelColors.indexOf(color);
|
|
606
|
-
|
|
607
|
-
if (pastelIdx > -1) {
|
|
608
|
-
return cardTypeColors[pastelIdx];
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
return color;
|
|
612
|
-
};
|
|
613
|
-
|
|
614
603
|
export const getEnumBackgroundColor = _.memoize(
|
|
615
604
|
(mode: ThemeMode, color: string) => {
|
|
616
|
-
const migratedColor = migrateEnumColor(color);
|
|
617
|
-
|
|
618
605
|
return getThemeValue(mode, {
|
|
619
|
-
light: a11yColor(getOpacities(
|
|
620
|
-
dark: a11yColor(getOpacities(
|
|
606
|
+
light: a11yColor(getOpacities(color).opacity20, lightColors.whiteColor, 1),
|
|
607
|
+
dark: a11yColor(getOpacities(color).opacity30, darkColors.menuBg, 1.3),
|
|
621
608
|
});
|
|
622
609
|
},
|
|
623
610
|
(themeMode, color) => `${themeMode}-${color}`
|
|
@@ -660,8 +647,6 @@ export const cardTypeColors = [
|
|
|
660
647
|
"#B04E31",
|
|
661
648
|
] as const;
|
|
662
649
|
|
|
663
|
-
const pastelColors = cardTypeColors.map((color) => makeChromaColor(color).luminance(0.8).hex());
|
|
664
|
-
|
|
665
650
|
export const dropCursorColor = chroma(brandColors.blue).alpha(0.7).css();
|
|
666
651
|
export const colors = {
|
|
667
652
|
...getTypeColors(brandColors.green, "light"),
|
|
@@ -784,7 +769,7 @@ export const getObjectColorMemoized = _.memoize((name) => {
|
|
|
784
769
|
return "#999999";
|
|
785
770
|
}
|
|
786
771
|
const colorHash = new ColorHash({
|
|
787
|
-
lightness: [0.
|
|
772
|
+
lightness: [0.5, 0.6, 0.7],
|
|
788
773
|
saturation: [0.6, 0.7, 0.8, 0.9, 1],
|
|
789
774
|
});
|
|
790
775
|
return colorHash.hex(name);
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import {EmojiItem} from "@fibery/emoji-data
|
|
2
|
-
import {
|
|
1
|
+
import {CustomEmoji, EmojiItem} from "@fibery/emoji-data";
|
|
2
|
+
import {useThemeMode} from "../ThemeProvider";
|
|
3
|
+
import {cardTypeColors, getIconColor} from "../designSystem";
|
|
3
4
|
import {$TSFixMe} from "../tsfixme";
|
|
4
|
-
import {
|
|
5
|
+
import {EmojiPickerContentWithColor} from "./emoji-picker-content-with-color";
|
|
5
6
|
import {EmojiPickerContent} from "./primitives/content";
|
|
6
|
-
import {EmojiPickerFooter} from "./primitives/footer";
|
|
7
|
-
import {EmojiPickerGrid} from "./primitives/grid";
|
|
8
|
-
import {EmojiPickerHeader} from "./primitives/header";
|
|
9
7
|
import {EmojiPickerRoot} from "./primitives/root";
|
|
10
|
-
import {
|
|
11
|
-
import {cardTypeColors} from "../designSystem";
|
|
8
|
+
import {LazyIconDataStore} from "./stores/lazy-icon-data-store";
|
|
12
9
|
|
|
13
10
|
const i18n = {search: "Search icon...", notfound: "No Icons Found"};
|
|
14
11
|
|
|
@@ -19,35 +16,43 @@ export type AppIconPickerProps = {
|
|
|
19
16
|
onColorSelect?: (c: $TSFixMe) => void;
|
|
20
17
|
|
|
21
18
|
onSelect: (emoji: EmojiItem) => void;
|
|
19
|
+
autoFocus?: boolean;
|
|
22
20
|
};
|
|
23
21
|
export const AppIconPicker: React.FC<AppIconPickerProps> = ({
|
|
24
22
|
onSelect,
|
|
25
23
|
color,
|
|
26
|
-
colors = cardTypeColors,
|
|
24
|
+
colors = cardTypeColors as unknown as string[],
|
|
27
25
|
onColorSelect,
|
|
28
26
|
getHoverColor,
|
|
27
|
+
autoFocus = true,
|
|
29
28
|
}) => {
|
|
29
|
+
const themeMode = useThemeMode();
|
|
30
|
+
|
|
30
31
|
return (
|
|
31
32
|
<EmojiPickerRoot i18n={i18n} onEmojiSelect={onSelect}>
|
|
32
33
|
<EmojiPickerContent emojiHoverColor={color ? getHoverColor?.(color) : undefined} emojiSize={20}>
|
|
33
|
-
<LazyIconDataStore fallback={<div style={{height: "
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
<LazyIconDataStore fallback={<div style={{height: "302px"}}></div>}>
|
|
35
|
+
<EmojiPickerContentWithColor
|
|
36
|
+
color={color}
|
|
37
|
+
colors={colors}
|
|
38
|
+
getHoverColor={getHoverColor}
|
|
39
|
+
onColorSelect={onColorSelect}
|
|
40
|
+
searchAutofocus={autoFocus}
|
|
41
|
+
renderEmoji={({emoji}) => (
|
|
42
|
+
<svg
|
|
43
|
+
style={{
|
|
44
|
+
display: "block",
|
|
45
|
+
width: 20,
|
|
46
|
+
height: 20,
|
|
47
|
+
fill: color ? getIconColor(themeMode, color) : undefined,
|
|
48
|
+
}}
|
|
49
|
+
viewBox="0 0 24 24"
|
|
50
|
+
>
|
|
51
|
+
<use href={(emoji as CustomEmoji).imageUrl} />
|
|
52
|
+
</svg>
|
|
53
|
+
)}
|
|
54
|
+
/>
|
|
39
55
|
</LazyIconDataStore>
|
|
40
|
-
|
|
41
|
-
{onColorSelect ? (
|
|
42
|
-
<EmojiPickerFooter>
|
|
43
|
-
<ColorPicker
|
|
44
|
-
colors={colors}
|
|
45
|
-
getSwatchHoverColor={getHoverColor}
|
|
46
|
-
color={color}
|
|
47
|
-
onChangeComplete={onColorSelect}
|
|
48
|
-
/>
|
|
49
|
-
</EmojiPickerFooter>
|
|
50
|
-
) : null}
|
|
51
56
|
</EmojiPickerContent>
|
|
52
57
|
</EmojiPickerRoot>
|
|
53
58
|
);
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import {css} from "@linaria/core";
|
|
2
|
+
import {useState} from "react";
|
|
3
|
+
import {IconButton} from "../Button/icon-button";
|
|
4
|
+
import {CollapsibleContent, CollapsibleRoot, CollapsibleTrigger} from "../Collapsible";
|
|
5
|
+
import {ColorPicker} from "../ColorPicker";
|
|
6
|
+
import {useThemeMode} from "../ThemeProvider";
|
|
7
|
+
import {getIconColor, space} from "../designSystem";
|
|
8
|
+
import ColorCoding from "../icons/react/ColorCoding";
|
|
9
|
+
import ColorCodingFilled from "../icons/react/ColorCodingFilled";
|
|
10
|
+
import {$TSFixMe} from "../tsfixme";
|
|
11
|
+
import {EmojiPickerGrid, EmojiPickerGridProps} from "./primitives/grid";
|
|
12
|
+
import {EmojiPickerHeader} from "./primitives/header";
|
|
13
|
+
import {EmojiPickerSearch} from "./primitives/search";
|
|
14
|
+
import {Tooltip} from "../tooltip";
|
|
15
|
+
|
|
16
|
+
const colorPickerWrapperCss = css`
|
|
17
|
+
padding-top: ${space.l}px;
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
const disableScrollCss = css`
|
|
21
|
+
overflow-y: hidden;
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
type ColorPickerCollapsibleTrigger = {opened: boolean; color?: string};
|
|
25
|
+
|
|
26
|
+
const ColorPickerCollapsibleTrigger: React.FC<ColorPickerCollapsibleTrigger> = ({opened, color}) => {
|
|
27
|
+
const themeMode = useThemeMode();
|
|
28
|
+
const iconColor = color ? getIconColor(themeMode, color) : undefined;
|
|
29
|
+
|
|
30
|
+
const Icon = opened ? ColorCodingFilled : ColorCoding;
|
|
31
|
+
|
|
32
|
+
const label = opened ? "Hide color picker" : "Show color picker";
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<CollapsibleTrigger asChild>
|
|
36
|
+
<Tooltip title={label}>
|
|
37
|
+
<IconButton
|
|
38
|
+
data-testid="emoji-picker-color-trigger"
|
|
39
|
+
size="big"
|
|
40
|
+
className={css`
|
|
41
|
+
border-top-left-radius: 0;
|
|
42
|
+
border-bottom-left-radius: 0;
|
|
43
|
+
`}
|
|
44
|
+
>
|
|
45
|
+
<Icon color={iconColor} iconSize={18} containerSize={20} />
|
|
46
|
+
</IconButton>
|
|
47
|
+
</Tooltip>
|
|
48
|
+
</CollapsibleTrigger>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const collapsibleWrapperCss = css`
|
|
53
|
+
max-height: 302px; // search + emoji grid
|
|
54
|
+
overflow: hidden;
|
|
55
|
+
`;
|
|
56
|
+
|
|
57
|
+
export type EmojiPickerContentWithColorProps = {
|
|
58
|
+
color?: string;
|
|
59
|
+
getHoverColor?: (color: string) => string | undefined;
|
|
60
|
+
colors?: string[];
|
|
61
|
+
onColorSelect?: (c: $TSFixMe) => void;
|
|
62
|
+
|
|
63
|
+
searchRef?: React.RefObject<HTMLInputElement>;
|
|
64
|
+
searchAutofocus?: boolean;
|
|
65
|
+
} & Pick<EmojiPickerGridProps, "renderEmoji">;
|
|
66
|
+
|
|
67
|
+
export const EmojiPickerContentWithColor: React.FC<EmojiPickerContentWithColorProps> = ({
|
|
68
|
+
searchRef,
|
|
69
|
+
colors,
|
|
70
|
+
color,
|
|
71
|
+
onColorSelect,
|
|
72
|
+
getHoverColor,
|
|
73
|
+
searchAutofocus = true,
|
|
74
|
+
renderEmoji,
|
|
75
|
+
}) => {
|
|
76
|
+
const [colorOpened, setColorOpened] = useState(false);
|
|
77
|
+
|
|
78
|
+
const showColorPicker = Boolean(onColorSelect);
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<CollapsibleRoot
|
|
82
|
+
className={collapsibleWrapperCss}
|
|
83
|
+
open={colorOpened}
|
|
84
|
+
onOpenChange={setColorOpened}
|
|
85
|
+
onWheel={() => setColorOpened(false)}
|
|
86
|
+
>
|
|
87
|
+
<EmojiPickerHeader>
|
|
88
|
+
<EmojiPickerSearch
|
|
89
|
+
searchRef={searchRef}
|
|
90
|
+
autoFocus={searchAutofocus}
|
|
91
|
+
extraAction={showColorPicker ? <ColorPickerCollapsibleTrigger opened={colorOpened} color={color} /> : null}
|
|
92
|
+
/>
|
|
93
|
+
{showColorPicker ? (
|
|
94
|
+
<CollapsibleContent>
|
|
95
|
+
<div className={colorPickerWrapperCss}>
|
|
96
|
+
<ColorPicker
|
|
97
|
+
colors={colors}
|
|
98
|
+
getSwatchHoverColor={getHoverColor}
|
|
99
|
+
color={color}
|
|
100
|
+
onChangeComplete={onColorSelect}
|
|
101
|
+
/>
|
|
102
|
+
</div>
|
|
103
|
+
</CollapsibleContent>
|
|
104
|
+
) : null}
|
|
105
|
+
</EmojiPickerHeader>
|
|
106
|
+
|
|
107
|
+
<EmojiPickerGrid className={colorOpened ? disableScrollCss : undefined} renderEmoji={renderEmoji} />
|
|
108
|
+
</CollapsibleRoot>
|
|
109
|
+
);
|
|
110
|
+
};
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import {EmojiItem} from "@fibery/emoji-data/lib/src";
|
|
2
|
+
import {css} from "@linaria/core";
|
|
3
|
+
import {Button} from "../Button";
|
|
4
|
+
import {cardTypeColors, space} from "../designSystem";
|
|
2
5
|
import {$TSFixMe} from "../tsfixme";
|
|
3
|
-
import {
|
|
6
|
+
import {EmojiPickerContentWithColor} from "./emoji-picker-content-with-color";
|
|
4
7
|
import {EmojiPickerContent} from "./primitives/content";
|
|
5
|
-
import {EmojiPickerHeader} from "./primitives/header";
|
|
6
|
-
import {EmojiPickerSearch} from "./primitives/search";
|
|
7
|
-
import {cx, css} from "@linaria/core";
|
|
8
|
-
import {EmojiPickerSkinTone} from "./primitives/skin-tone";
|
|
9
|
-
import {EmojiPickerGrid} from "./primitives/grid";
|
|
10
|
-
import {ColorPicker} from "../ColorPicker";
|
|
11
8
|
import {EmojiPickerFooter} from "./primitives/footer";
|
|
12
|
-
import {
|
|
9
|
+
import {EmojiPickerRoot} from "./primitives/root";
|
|
10
|
+
import {EmojiPickerSkinTone} from "./primitives/skin-tone";
|
|
13
11
|
|
|
14
12
|
const i18n = {search: "Search emoji..."};
|
|
15
13
|
|
|
@@ -19,6 +17,7 @@ export type EmojiPickerProps = {
|
|
|
19
17
|
colors?: string[];
|
|
20
18
|
onColorSelect?: (c: $TSFixMe) => void;
|
|
21
19
|
onCustomCategorySettings?: () => void;
|
|
20
|
+
onAddCustomEmoji?: () => void;
|
|
22
21
|
onSelect: (emoji: EmojiItem) => void;
|
|
23
22
|
showSkinTones?: boolean;
|
|
24
23
|
|
|
@@ -27,48 +26,44 @@ export type EmojiPickerProps = {
|
|
|
27
26
|
export const EmojiPicker: React.FC<EmojiPickerProps> = ({
|
|
28
27
|
onSelect,
|
|
29
28
|
color,
|
|
30
|
-
colors = cardTypeColors,
|
|
29
|
+
colors = cardTypeColors as unknown as string[],
|
|
31
30
|
onColorSelect,
|
|
32
31
|
onCustomCategorySettings,
|
|
32
|
+
onAddCustomEmoji,
|
|
33
33
|
getHoverColor,
|
|
34
34
|
showSkinTones,
|
|
35
35
|
searchRef,
|
|
36
36
|
}) => {
|
|
37
|
+
const showFooter = Boolean(onAddCustomEmoji) || showSkinTones;
|
|
38
|
+
|
|
37
39
|
return (
|
|
38
40
|
<EmojiPickerRoot i18n={i18n} onEmojiSelect={onSelect} onCustomCategorySettings={onCustomCategorySettings}>
|
|
39
41
|
<EmojiPickerContent emojiHoverColor={color ? getHoverColor?.(color) : undefined} emojiSize={20}>
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
width: 250px !important;
|
|
48
|
-
`
|
|
49
|
-
)}
|
|
50
|
-
/>
|
|
51
|
-
{/* Temporary hacks. SkinTone should move to footer */}
|
|
52
|
-
{showSkinTones ? (
|
|
53
|
-
<EmojiPickerSkinTone
|
|
54
|
-
className={css`
|
|
55
|
-
position: absolute;
|
|
56
|
-
top: 4px;
|
|
57
|
-
right: 12px;
|
|
58
|
-
`}
|
|
59
|
-
/>
|
|
60
|
-
) : null}
|
|
61
|
-
</EmojiPickerHeader>
|
|
62
|
-
<EmojiPickerGrid />
|
|
42
|
+
<EmojiPickerContentWithColor
|
|
43
|
+
color={color}
|
|
44
|
+
colors={colors}
|
|
45
|
+
getHoverColor={getHoverColor}
|
|
46
|
+
onColorSelect={onColorSelect}
|
|
47
|
+
searchRef={searchRef}
|
|
48
|
+
/>
|
|
63
49
|
|
|
64
|
-
{
|
|
50
|
+
{showFooter ? (
|
|
65
51
|
<EmojiPickerFooter>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
52
|
+
{onAddCustomEmoji ? (
|
|
53
|
+
<Button size=":button-size/small" onClick={onAddCustomEmoji}>
|
|
54
|
+
Add Emoji
|
|
55
|
+
</Button>
|
|
56
|
+
) : null}
|
|
57
|
+
|
|
58
|
+
{showSkinTones ? (
|
|
59
|
+
<EmojiPickerSkinTone
|
|
60
|
+
className={css`
|
|
61
|
+
position: absolute;
|
|
62
|
+
top: 4px;
|
|
63
|
+
right: ${space.l}px;
|
|
64
|
+
`}
|
|
65
|
+
/>
|
|
66
|
+
) : null}
|
|
72
67
|
</EmojiPickerFooter>
|
|
73
68
|
) : null}
|
|
74
69
|
</EmojiPickerContent>
|