@fibery/ui-kit 1.10.1 β 1.11.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 +3 -2
- package/src/Button/button.tsx +14 -7
- package/src/designSystem.ts +79 -8
- package/src/emoji-mart/app-icon-picker.tsx +27 -21
- package/src/emoji-mart/data/get-data.tsx +58 -0
- package/src/emoji-mart/emoji/emoji.tsx +26 -0
- package/src/emoji-mart/emoji/index.tsx +24 -0
- package/src/emoji-mart/emoji-index.ts +5 -0
- package/src/emoji-mart/emoji-mart.tsx +30 -40
- package/src/emoji-mart/emoji-picker.tsx +61 -28
- package/src/emoji-mart/emoji-support.ts +1 -0
- package/src/emoji-mart/icon-emoji-picker.tsx +26 -6
- package/src/icons/ast/Activity.ts +1 -1
- package/src/icons/ast/ActivityLog.ts +1 -1
- package/src/icons/ast/AddReactions.ts +1 -1
- package/src/icons/ast/AppStore.ts +1 -1
- package/src/icons/ast/AppStoreOneColor.ts +1 -1
- package/src/icons/ast/AppTemplates.ts +1 -1
- package/src/icons/ast/AppTemplatesOneColor.ts +1 -1
- package/src/icons/ast/AskForInput.ts +1 -1
- package/src/icons/ast/Cards.ts +1 -1
- package/src/icons/ast/ClearValue.ts +1 -1
- package/src/icons/ast/Close.ts +1 -1
- package/src/icons/ast/ColorCoding.ts +1 -1
- package/src/icons/ast/Columns.ts +1 -1
- package/src/icons/ast/Favorites.ts +1 -1
- package/src/icons/ast/FavoritesChecked.ts +1 -1
- package/src/icons/ast/FavoritesMenu.ts +1 -1
- package/src/icons/ast/Fields.ts +1 -1
- package/src/icons/ast/Filter.ts +1 -1
- package/src/icons/ast/FocusMode.ts +1 -1
- package/src/icons/ast/FocusModeOff.ts +1 -1
- package/src/icons/ast/ImageXmark.ts +8 -0
- package/src/icons/ast/InvitePeople.ts +1 -1
- package/src/icons/ast/Items.ts +1 -1
- package/src/icons/ast/Levels.ts +1 -1
- package/src/icons/ast/Lock.ts +1 -1
- package/src/icons/ast/MoreCompact.ts +1 -1
- package/src/icons/ast/MySpace.ts +1 -1
- package/src/icons/ast/OpenAsPage.ts +1 -1
- package/src/icons/ast/PageRegularMode.ts +1 -1
- package/src/icons/ast/PageWideMode.ts +1 -1
- package/src/icons/ast/Popup.ts +1 -1
- package/src/icons/ast/Posts.ts +1 -1
- package/src/icons/ast/RicheditorImageUpload.ts +1 -1
- package/src/icons/ast/Rows.ts +1 -1
- package/src/icons/ast/Search.ts +1 -1
- package/src/icons/ast/Settings.ts +1 -1
- package/src/icons/ast/Share.ts +1 -1
- package/src/icons/ast/Shared.ts +1 -1
- package/src/icons/ast/SidebarFields.ts +1 -1
- package/src/icons/ast/SidebarFieldsOpened.ts +1 -1
- package/src/icons/ast/Sort.ts +1 -1
- package/src/icons/ast/SortOnBottom.ts +1 -1
- package/src/icons/ast/SortOnTop.ts +1 -1
- package/src/icons/ast/TypeButton.ts +1 -1
- package/src/icons/ast/TypeEmoji.ts +1 -1
- package/src/icons/ast/Upgrade.ts +1 -1
- package/src/icons/ast/index.tsx +1 -0
- package/src/icons/react/ImageXmark.tsx +12 -0
- package/src/icons/react/index.tsx +1 -0
- package/src/emoji-mart/emoji.tsx +0 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fibery/ui-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.1",
|
|
4
4
|
"main": "index.ts",
|
|
5
5
|
"private": false,
|
|
6
6
|
"files": [
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"src/tooltip.tsx",
|
|
24
24
|
"src/BackButton.tsx",
|
|
25
25
|
"src/Button",
|
|
26
|
-
"src/emoji-mart
|
|
26
|
+
"src/emoji-mart/**/*.ts*"
|
|
27
27
|
],
|
|
28
28
|
"license": "UNLICENSED",
|
|
29
29
|
"dependencies": {
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"react-windowed-select": "5.0.0",
|
|
60
60
|
"screenfull": "6.0.1",
|
|
61
61
|
"ua-parser-js": "0.7.24",
|
|
62
|
+
"@fibery/emoji-data": "1.1.0",
|
|
62
63
|
"@fibery/react": "1.0.2",
|
|
63
64
|
"@fibery/helpers": "1.0.4"
|
|
64
65
|
},
|
package/src/Button/button.tsx
CHANGED
|
@@ -38,10 +38,10 @@ const HorizontalPaddings = {
|
|
|
38
38
|
} as const;
|
|
39
39
|
|
|
40
40
|
const IconSizes = {
|
|
41
|
-
":button-size/super-small":
|
|
42
|
-
":button-size/small": 18,
|
|
43
|
-
":button-size/normal":
|
|
44
|
-
":button-size/big":
|
|
41
|
+
":button-size/super-small": 14,
|
|
42
|
+
":button-size/small": 18, // if you want to change it please ping Alex T.
|
|
43
|
+
":button-size/normal": 18,
|
|
44
|
+
":button-size/big": 20,
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
type StyledProps = {
|
|
@@ -111,7 +111,9 @@ const getIconMagicConstants = _.memoize((size: ButtonSize) => {
|
|
|
111
111
|
const leftContainerSize = 8;
|
|
112
112
|
const leftContainerMarginRight = iconSize - leftContainerSize;
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
const spinnerSize = Math.round(iconSize * 0.8);
|
|
115
|
+
|
|
116
|
+
return {iconSize, spinnerSize, leftContainerSize, leftContainerMarginRight};
|
|
115
117
|
});
|
|
116
118
|
|
|
117
119
|
const shortcutStyle = css`
|
|
@@ -169,10 +171,15 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
|
|
|
169
171
|
const spinnerBgColor = getOpacities(textColor).opacity25;
|
|
170
172
|
const spinnerColor = getSpinnerColor({mainColor, primary: baseProps.primary});
|
|
171
173
|
|
|
172
|
-
const {iconSize, leftContainerSize, leftContainerMarginRight} = getIconMagicConstants(size);
|
|
174
|
+
const {iconSize, spinnerSize, leftContainerSize, leftContainerMarginRight} = getIconMagicConstants(size);
|
|
173
175
|
|
|
174
176
|
const leftContainer = pending ? (
|
|
175
|
-
<Spinner
|
|
177
|
+
<Spinner
|
|
178
|
+
backgroundColor={spinnerBgColor}
|
|
179
|
+
color={spinnerColor}
|
|
180
|
+
size={spinnerSize}
|
|
181
|
+
containerSize={leftContainerSize}
|
|
182
|
+
/>
|
|
176
183
|
) : Icon ? (
|
|
177
184
|
<Icon color={textColor} iconSize={iconSize} containerSize={leftContainerSize} />
|
|
178
185
|
) : null;
|
package/src/designSystem.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
} from "./Pallete";
|
|
19
19
|
import _ from "lodash";
|
|
20
20
|
import {createInlineTheme as createInlineStyles, varPrefix} from "./create-inline-theme";
|
|
21
|
+
import {a11yColor} from "./a11y-color";
|
|
21
22
|
|
|
22
23
|
export const typeSizes = [28, 24, 18, 16, 14, 12, 10, 8] as const;
|
|
23
24
|
|
|
@@ -107,6 +108,7 @@ const lightColors = {
|
|
|
107
108
|
mode: "light",
|
|
108
109
|
brandColors,
|
|
109
110
|
stateColors,
|
|
111
|
+
primaryBlue: indigo.indigo10,
|
|
110
112
|
whiteColor: whiteA.whiteA0,
|
|
111
113
|
blackColor: blackA.blackA0,
|
|
112
114
|
mainBg: slate.slate2,
|
|
@@ -153,6 +155,7 @@ const lightColors = {
|
|
|
153
155
|
inputBorderFocusColor: `0 0 0 1px ${getOpacities(slate.slate8).opacity100}`,
|
|
154
156
|
inputBorderBlendMode: "multiply",
|
|
155
157
|
inputPlaceholderTextColor: slate.slate9,
|
|
158
|
+
buttonPrimaryColor: indigo.indigo10,
|
|
156
159
|
buttonColor: slate.slate10,
|
|
157
160
|
buttonPrimaryTextColor: slate.slate2,
|
|
158
161
|
checkboxColor: slate.slate10,
|
|
@@ -256,6 +259,22 @@ const lightColors = {
|
|
|
256
259
|
progressFillText: whiteA.whiteA0,
|
|
257
260
|
searchFiltersBg: slate.slate1,
|
|
258
261
|
colorPickerSwatchBorder: blackA.blackA7,
|
|
262
|
+
richTextTableBorder: blackA.blackA5,
|
|
263
|
+
// GRID
|
|
264
|
+
// header
|
|
265
|
+
gridHeaderBgColor: slate.slate2,
|
|
266
|
+
gridHeaderHoverBgColor: slate.slate3,
|
|
267
|
+
gridHeaderTextColor: slate.slate9,
|
|
268
|
+
// cell
|
|
269
|
+
gridCellBgColor: whiteA.whiteA0,
|
|
270
|
+
gridCellBorderColor: slate.slate4,
|
|
271
|
+
gridPinnedCellBorderColor: slate.slate8,
|
|
272
|
+
gridDisabledCellBgColor: slate.slate2,
|
|
273
|
+
gridSelectedCellBgColor: indigo.indigo3,
|
|
274
|
+
gridSelectedCellBorderColor: indigo.indigo5,
|
|
275
|
+
gridSelectedPinnedCellBorderColor: indigo.indigo7,
|
|
276
|
+
gridDisabledSelectedCellBgColor: indigo.indigo4,
|
|
277
|
+
gridActiveCellBorderColor: indigo.indigo8,
|
|
259
278
|
} as const;
|
|
260
279
|
|
|
261
280
|
const darkMenu = {
|
|
@@ -281,6 +300,7 @@ const darkColors = {
|
|
|
281
300
|
mode: "dark",
|
|
282
301
|
brandColors,
|
|
283
302
|
stateColors,
|
|
303
|
+
primaryBlue: indigoDark.indigo10,
|
|
284
304
|
whiteColor: whiteA.whiteA0,
|
|
285
305
|
blackColor: blackA.blackA0,
|
|
286
306
|
mainBg: slateDark.slate1,
|
|
@@ -318,6 +338,7 @@ const darkColors = {
|
|
|
318
338
|
inputBorderFocusColor: `0 0 0 1px ${getOpacities(slateDark.slate9).opacity100}`,
|
|
319
339
|
inputBorderBlendMode: "lighten",
|
|
320
340
|
inputPlaceholderTextColor: slateDark.slate9,
|
|
341
|
+
buttonPrimaryColor: indigoDark.indigo10,
|
|
321
342
|
buttonColor: slateDark.slate10,
|
|
322
343
|
buttonPrimaryTextColor: slate.slate6,
|
|
323
344
|
checkboxColor: slateDark.slate10,
|
|
@@ -418,10 +439,28 @@ const darkColors = {
|
|
|
418
439
|
progressFillText: whiteA.whiteA0,
|
|
419
440
|
searchFiltersBg: slateDark.slate2,
|
|
420
441
|
colorPickerSwatchBorder: blackA.blackA7,
|
|
442
|
+
richTextTableBorder: whiteA.whiteA7,
|
|
443
|
+
// GRID
|
|
444
|
+
// header
|
|
445
|
+
gridHeaderBgColor: slateDark.slate3,
|
|
446
|
+
gridHeaderHoverBgColor: slateDark.slate4,
|
|
447
|
+
gridHeaderTextColor: slateDark.slate10,
|
|
448
|
+
// cell
|
|
449
|
+
gridCellBgColor: slateDark.slate2,
|
|
450
|
+
gridCellBorderColor: slateDark.slate5,
|
|
451
|
+
gridPinnedCellBorderColor: slateDark.slate8,
|
|
452
|
+
gridDisabledCellBgColor: slateDark.slate3,
|
|
453
|
+
gridSelectedCellBgColor: indigoDark.indigo3,
|
|
454
|
+
gridSelectedCellBorderColor: indigoDark.indigo6,
|
|
455
|
+
gridSelectedPinnedCellBorderColor: indigoDark.indigo7,
|
|
456
|
+
gridDisabledSelectedCellBgColor: indigoDark.indigo5,
|
|
457
|
+
gridActiveCellBorderColor: indigoDark.indigo9,
|
|
421
458
|
...darkMenu,
|
|
422
459
|
} as const;
|
|
423
460
|
|
|
424
461
|
export function getLightColors(): typeof lightColors {
|
|
462
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
463
|
+
// @ts-ignore
|
|
425
464
|
if (process.env.NODE_ENV !== "test") {
|
|
426
465
|
throw new Error("Only for test purpose");
|
|
427
466
|
}
|
|
@@ -429,6 +468,8 @@ export function getLightColors(): typeof lightColors {
|
|
|
429
468
|
}
|
|
430
469
|
|
|
431
470
|
export function getDarkColors(): typeof darkColors {
|
|
471
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
472
|
+
// @ts-ignore
|
|
432
473
|
if (process.env.NODE_ENV !== "test") {
|
|
433
474
|
throw new Error("Only for test purpose");
|
|
434
475
|
}
|
|
@@ -436,6 +477,8 @@ export function getDarkColors(): typeof darkColors {
|
|
|
436
477
|
}
|
|
437
478
|
|
|
438
479
|
export function getLight2Colors(): typeof light2Colors {
|
|
480
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
481
|
+
// @ts-ignore
|
|
439
482
|
if (process.env.NODE_ENV !== "test") {
|
|
440
483
|
throw new Error("Only for test purpose");
|
|
441
484
|
}
|
|
@@ -545,18 +588,46 @@ export const getLinkedHighlightBackgroundColor = _.memoize(
|
|
|
545
588
|
(themeMode, color) => `${themeMode}-${color}`
|
|
546
589
|
);
|
|
547
590
|
|
|
591
|
+
// REMOVE AFTER MIGRATION ON BACKEND
|
|
592
|
+
export const migrateEnumColor = (color: string) => {
|
|
593
|
+
const pastelIdx = pastelColors.indexOf(color);
|
|
594
|
+
|
|
595
|
+
if (pastelIdx > -1) {
|
|
596
|
+
return cardTypeColors[pastelIdx];
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
return color;
|
|
600
|
+
};
|
|
601
|
+
|
|
548
602
|
export const getEnumBackgroundColor = _.memoize(
|
|
549
|
-
(
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
603
|
+
(mode: ThemeMode, color: string) => {
|
|
604
|
+
const migratedColor = migrateEnumColor(color);
|
|
605
|
+
|
|
606
|
+
return getThemeValue(mode, {
|
|
607
|
+
light: a11yColor(getOpacities(migratedColor).opacity20, lightColors.whiteColor, 1),
|
|
608
|
+
dark: a11yColor(getOpacities(migratedColor).opacity30, darkColors.menuBg, 1.3),
|
|
609
|
+
});
|
|
556
610
|
},
|
|
557
611
|
(themeMode, color) => `${themeMode}-${color}`
|
|
558
612
|
);
|
|
559
613
|
|
|
614
|
+
// TODO: fix color for light2. It should same as 'dark' only on dark menu but same as 'light' on other parts of application
|
|
615
|
+
export const getAppIconBackgroundColor = (mode: ThemeMode, color: string) =>
|
|
616
|
+
getThemeValue(mode, {
|
|
617
|
+
dark: a11yColor(getOpacities(color).opacity30, darkColors.menuBg, 1.3),
|
|
618
|
+
light: a11yColor(getOpacities(color).opacity15, lightColors.whiteColor, 1),
|
|
619
|
+
light2: a11yColor(getOpacities(color).opacity30, darkColors.menuBg, 1.3),
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
export const getIconColor = _.memoize(
|
|
623
|
+
(mode: ThemeMode, color: string) =>
|
|
624
|
+
getThemeValue(mode, {
|
|
625
|
+
light: a11yColor(getOpacities(color).opacity95, lightColors.whiteColor, 3),
|
|
626
|
+
dark: a11yColor(getOpacities(color).opacity95, darkColors.menuBg, 5),
|
|
627
|
+
}),
|
|
628
|
+
(themeMode, color) => `${themeMode}-${color}`
|
|
629
|
+
);
|
|
630
|
+
|
|
560
631
|
export const cardTypeColors = [
|
|
561
632
|
"#4A4A4A",
|
|
562
633
|
"#6A849B",
|
|
@@ -577,7 +648,7 @@ export const cardTypeColors = [
|
|
|
577
648
|
"#B04E31",
|
|
578
649
|
] as const;
|
|
579
650
|
|
|
580
|
-
|
|
651
|
+
const pastelColors = cardTypeColors.map((color) => makeChromaColor(color).luminance(0.8).hex());
|
|
581
652
|
|
|
582
653
|
export const dropCursorColor = chroma(brandColors.blue).alpha(0.7).css();
|
|
583
654
|
export const colors = {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {forwardRef, useMemo} from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {getThemedUrl} from "../AppIconWithFallback";
|
|
3
3
|
import {useThemeMode} from "../ThemeProvider";
|
|
4
|
-
import {alignTheme} from "../theme-settings";
|
|
5
4
|
import appIcons from "../appIcons.json";
|
|
6
|
-
import {
|
|
5
|
+
import {alignTheme} from "../theme-settings";
|
|
7
6
|
import {$TSFixMe} from "../tsfixme";
|
|
8
|
-
import {
|
|
7
|
+
import type {EmojiDataProps} from "./data/get-data";
|
|
8
|
+
import {EmojiMartWrapper, NimblePicker, NimblePickerProps} from "./emoji-mart";
|
|
9
9
|
import {ColorPicker} from "../ColorPicker";
|
|
10
|
+
import {cardTypeColors} from "../designSystem";
|
|
10
11
|
|
|
11
12
|
const EMPTY_DATA = {
|
|
12
13
|
aliases: {},
|
|
@@ -15,16 +16,20 @@ const EMPTY_DATA = {
|
|
|
15
16
|
compressed: false,
|
|
16
17
|
};
|
|
17
18
|
|
|
19
|
+
type NimblePickerWithData = Omit<NimblePickerProps, keyof EmojiDataProps>;
|
|
20
|
+
|
|
18
21
|
export type AppIconPickerProps = {
|
|
19
22
|
borderless?: boolean;
|
|
20
23
|
color?: string;
|
|
24
|
+
getHoverColor?: (color: string) => string | undefined;
|
|
25
|
+
colors?: string[];
|
|
21
26
|
onColorSelect?: (c: $TSFixMe) => void;
|
|
22
|
-
} &
|
|
27
|
+
} & NimblePickerWithData;
|
|
23
28
|
|
|
24
|
-
const i18n = {search: "Search icon..."};
|
|
29
|
+
const i18n = {search: "Search icon...", notfound: "No Icons Found"};
|
|
25
30
|
|
|
26
31
|
export const AppIconPicker = forwardRef<HTMLDivElement, AppIconPickerProps>(function AppIconPicker(
|
|
27
|
-
{borderless = true,
|
|
32
|
+
{borderless = true, color, getHoverColor, colors = cardTypeColors, onColorSelect, ...pickerProps},
|
|
28
33
|
ref
|
|
29
34
|
) {
|
|
30
35
|
const themeMode = useThemeMode();
|
|
@@ -43,20 +48,21 @@ export const AppIconPicker = forwardRef<HTMLDivElement, AppIconPickerProps>(func
|
|
|
43
48
|
);
|
|
44
49
|
|
|
45
50
|
return (
|
|
46
|
-
<EmojiMartWrapper
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
<EmojiMartWrapper
|
|
52
|
+
ref={ref}
|
|
53
|
+
emojiHoverColor={color ? getHoverColor?.(color) : undefined}
|
|
54
|
+
borderless={borderless}
|
|
55
|
+
hideCategories
|
|
56
|
+
>
|
|
57
|
+
<NimblePicker custom={customIcons} i18n={i18n} {...pickerProps} data={EMPTY_DATA} showSkinTones={false} />
|
|
58
|
+
{onColorSelect ? (
|
|
59
|
+
<ColorPicker
|
|
60
|
+
colors={colors}
|
|
61
|
+
getSwatchHoverColor={getHoverColor}
|
|
62
|
+
color={color}
|
|
63
|
+
onChangeComplete={onColorSelect}
|
|
64
|
+
/>
|
|
65
|
+
) : null}
|
|
60
66
|
</EmojiMartWrapper>
|
|
61
67
|
);
|
|
62
68
|
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {detectEmojiSupportLevel} from "../emoji-support";
|
|
2
|
+
import type {Data} from "emoji-mart";
|
|
3
|
+
|
|
4
|
+
export type EmojiDataProps = {
|
|
5
|
+
native: boolean;
|
|
6
|
+
data: Data;
|
|
7
|
+
backgroundImageFn: (set: string) => string;
|
|
8
|
+
set: "apple" | "twitter";
|
|
9
|
+
sheetColumns: number;
|
|
10
|
+
sheetRows: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
let promise: Promise<EmojiDataProps>;
|
|
14
|
+
|
|
15
|
+
const backgroundImageFn = (set: string) =>
|
|
16
|
+
`https://fibery-ui-public-assets.s3.eu-central-1.amazonaws.com/images/emoji-datasource-${set}-15_0_1-64.png`;
|
|
17
|
+
|
|
18
|
+
export const loadEmojiData = async () => {
|
|
19
|
+
const data = await import("@fibery/emoji-data/data/all.json");
|
|
20
|
+
return data.default;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const getAppleDataProps = async (): Promise<EmojiDataProps> => {
|
|
24
|
+
const [level, data] = await Promise.all([detectEmojiSupportLevel(), loadEmojiData()]);
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
native: level >= 14,
|
|
28
|
+
// type declarations between @fibery/emoji-data and emoji-mart conflict a bit but they are compatible
|
|
29
|
+
data: data as unknown as Data,
|
|
30
|
+
backgroundImageFn,
|
|
31
|
+
set: "apple",
|
|
32
|
+
sheetColumns: 61,
|
|
33
|
+
sheetRows: 61,
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
const getTwitterDataProps = async (): Promise<EmojiDataProps> => {
|
|
37
|
+
const data = await loadEmojiData();
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
native: false,
|
|
41
|
+
// type declarations between @fibery/emoji-data and emoji-mart conflict a bit but they are compatible
|
|
42
|
+
data: data as unknown as Data,
|
|
43
|
+
backgroundImageFn,
|
|
44
|
+
set: "twitter",
|
|
45
|
+
sheetColumns: 61,
|
|
46
|
+
sheetRows: 61,
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const isApple = () => /Mac|iPhone|iPad/.test(navigator.userAgent);
|
|
51
|
+
|
|
52
|
+
export const getEmojiDataProps = async () => {
|
|
53
|
+
if (!promise) {
|
|
54
|
+
promise = isApple() ? getAppleDataProps() : getTwitterDataProps();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return promise;
|
|
58
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {css} from "@linaria/core";
|
|
2
|
+
import {NimbleEmoji, NimbleEmojiProps} from "emoji-mart";
|
|
3
|
+
import {themeVars} from "../../designSystem";
|
|
4
|
+
|
|
5
|
+
const emojiWrapperCss = css`
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
|
|
9
|
+
& span.emoji-mart-emoji {
|
|
10
|
+
color: ${themeVars.textColor};
|
|
11
|
+
line-height: 1;
|
|
12
|
+
vertical-align: middle;
|
|
13
|
+
& span {
|
|
14
|
+
vertical-align: middle;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
export type EmojiMartEmojiProps = NimbleEmojiProps;
|
|
20
|
+
export const EmojiMartEmoji: React.FC<NimbleEmojiProps> = (props) => {
|
|
21
|
+
return (
|
|
22
|
+
<span className={emojiWrapperCss}>
|
|
23
|
+
<NimbleEmoji {...props} />
|
|
24
|
+
</span>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {lazy, Suspense} from "react";
|
|
2
|
+
import {EmojiDataProps, getEmojiDataProps} from "../data/get-data";
|
|
3
|
+
import {EmojiMartEmoji, type EmojiMartEmojiProps} from "./emoji";
|
|
4
|
+
|
|
5
|
+
type EmojiProps = Omit<EmojiMartEmojiProps, keyof EmojiDataProps>;
|
|
6
|
+
|
|
7
|
+
const LazyEmojiComponent = lazy(async () => {
|
|
8
|
+
const emojiDataProps = await getEmojiDataProps();
|
|
9
|
+
|
|
10
|
+
function Emoji(props: EmojiProps) {
|
|
11
|
+
return <EmojiMartEmoji {...props} {...emojiDataProps} />;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
default: Emoji,
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const Emoji: React.FC<EmojiProps> = function EmojiOrLoader(props) {
|
|
19
|
+
return (
|
|
20
|
+
<Suspense fallback={<div style={{width: props.size, height: props.size}} />}>
|
|
21
|
+
<LazyEmojiComponent {...props} />
|
|
22
|
+
</Suspense>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
@@ -1,15 +1,32 @@
|
|
|
1
1
|
import {CSSProperties, css, cx} from "@linaria/core";
|
|
2
|
-
import {Emoji, EmojiProps} from "emoji-mart";
|
|
3
2
|
import "emoji-mart/css/emoji-mart.css";
|
|
4
3
|
import {forwardRef} from "react";
|
|
5
|
-
import {useTheme} from "../ThemeProvider";
|
|
6
|
-
import {
|
|
7
|
-
import {border, fontFamily, getOpacities, space, textStyles, themeVars} from "../designSystem";
|
|
4
|
+
import {useTheme, useThemeMode} from "../ThemeProvider";
|
|
5
|
+
import {border, fontFamily, space, textStyles, themeVars} from "../designSystem";
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
import {NimblePickerProps, NimblePicker as Picker} from "emoji-mart";
|
|
8
|
+
import {alignTheme} from "../theme-settings";
|
|
11
9
|
|
|
12
|
-
export
|
|
10
|
+
export type {BaseEmoji, EmojiSkin, NimblePickerProps} from "emoji-mart";
|
|
11
|
+
|
|
12
|
+
export const NimblePicker = (props: NimblePickerProps) => {
|
|
13
|
+
const themeMode = useThemeMode();
|
|
14
|
+
const theme = useTheme();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Picker
|
|
18
|
+
theme={alignTheme(themeMode)}
|
|
19
|
+
title={""}
|
|
20
|
+
showPreview={false}
|
|
21
|
+
skinEmoji="hand"
|
|
22
|
+
color={theme.primary}
|
|
23
|
+
emoji=""
|
|
24
|
+
emojiSize={20}
|
|
25
|
+
emojiTooltip
|
|
26
|
+
{...props}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
13
30
|
|
|
14
31
|
const emojiMartCss = css`
|
|
15
32
|
padding: 0 ${space.l}px;
|
|
@@ -58,6 +75,7 @@ const emojiMartCss = css`
|
|
|
58
75
|
.emoji-mart-scroll {
|
|
59
76
|
padding-left: 0;
|
|
60
77
|
padding-right: 0;
|
|
78
|
+
height: 238px;
|
|
61
79
|
}
|
|
62
80
|
|
|
63
81
|
.emoji-anchor-bar {
|
|
@@ -80,7 +98,7 @@ const emojiMartCss = css`
|
|
|
80
98
|
}
|
|
81
99
|
|
|
82
100
|
.emoji-mart-category .emoji-mart-emoji:hover::before {
|
|
83
|
-
background-color: var(--emoji-
|
|
101
|
+
background-color: var(--fibery-emoji-hover-color, ${themeVars.badgeBgColor}) !important;
|
|
84
102
|
border-radius: ${border.radius8}px !important;
|
|
85
103
|
}
|
|
86
104
|
.emoji-mart-dark .emoji-mart-category-label span {
|
|
@@ -97,6 +115,7 @@ const emojiMartCss = css`
|
|
|
97
115
|
}
|
|
98
116
|
|
|
99
117
|
.emoji-mart-emoji {
|
|
118
|
+
color: ${themeVars.textColor};
|
|
100
119
|
/* pathetic attemts to make it a bit faster without forking */
|
|
101
120
|
content-visibility: auto;
|
|
102
121
|
contain-intrinsic-size: 20px;
|
|
@@ -130,13 +149,6 @@ const emojiMartCss = css`
|
|
|
130
149
|
padding: 0;
|
|
131
150
|
}
|
|
132
151
|
|
|
133
|
-
& .emoji-mart-emoji-native span {
|
|
134
|
-
width: 20px;
|
|
135
|
-
font-size: 20px !important;
|
|
136
|
-
height: 20px;
|
|
137
|
-
display: inline-block;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
152
|
&:hover {
|
|
141
153
|
background-color: ${themeVars.badgeBgColor} !important;
|
|
142
154
|
border-radius: ${border.radius8}px !important;
|
|
@@ -180,20 +192,16 @@ type EmojiMartWrapperProps = React.PropsWithChildren<{
|
|
|
180
192
|
borderless?: boolean;
|
|
181
193
|
hideCategories?: boolean;
|
|
182
194
|
shortSearch?: boolean;
|
|
183
|
-
|
|
195
|
+
emojiHoverColor?: string;
|
|
184
196
|
}>;
|
|
185
197
|
|
|
186
198
|
export const EmojiMartWrapper = forwardRef<HTMLDivElement, EmojiMartWrapperProps>(function EmojiMartWrapper(
|
|
187
|
-
{borderless, hideCategories,
|
|
199
|
+
{borderless, hideCategories, emojiHoverColor, shortSearch, children},
|
|
188
200
|
ref
|
|
189
201
|
) {
|
|
190
|
-
const theme = useTheme();
|
|
191
|
-
|
|
192
|
-
const bgColor = color ? a11yColor(getOpacities(color).opacity20, theme.menuBg, 1.3) : theme.badgeBgColor;
|
|
193
|
-
|
|
194
202
|
return (
|
|
195
203
|
<div
|
|
196
|
-
style={{"--emoji-
|
|
204
|
+
style={{"--fibery-emoji-hover-color": emojiHoverColor} as CSSProperties}
|
|
197
205
|
ref={ref}
|
|
198
206
|
className={cx(
|
|
199
207
|
emojiMartCss,
|
|
@@ -206,21 +214,3 @@ export const EmojiMartWrapper = forwardRef<HTMLDivElement, EmojiMartWrapperProps
|
|
|
206
214
|
</div>
|
|
207
215
|
);
|
|
208
216
|
});
|
|
209
|
-
|
|
210
|
-
const emojiWrapperCss = css`
|
|
211
|
-
& span.emoji-mart-emoji-native {
|
|
212
|
-
line-height: 1;
|
|
213
|
-
vertical-align: middle;
|
|
214
|
-
& span {
|
|
215
|
-
vertical-align: middle;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
`;
|
|
219
|
-
|
|
220
|
-
export const EmojiMartEmoji: React.FC<EmojiProps> = (props) => {
|
|
221
|
-
return (
|
|
222
|
-
<span className={emojiWrapperCss}>
|
|
223
|
-
<Emoji backgroundImageFn={backgroundImageFn} {...props} />
|
|
224
|
-
</span>
|
|
225
|
-
);
|
|
226
|
-
};
|
|
@@ -1,45 +1,78 @@
|
|
|
1
|
-
import {forwardRef} from "react";
|
|
2
|
-
import {useTheme, useThemeMode} from "../ThemeProvider";
|
|
3
|
-
import {EmojiMartWrapper, Picker, PickerProps, backgroundImageFn} from "./emoji-mart";
|
|
4
|
-
import {alignTheme} from "../theme-settings";
|
|
5
|
-
import {$TSFixMe} from "../tsfixme";
|
|
1
|
+
import {Suspense, forwardRef, lazy} from "react";
|
|
6
2
|
import {ColorPicker} from "../ColorPicker";
|
|
7
3
|
import {cardTypeColors} from "../designSystem";
|
|
4
|
+
import {$TSFixMe} from "../tsfixme";
|
|
5
|
+
import {EmojiMartWrapper, NimblePicker, NimblePickerProps} from "./emoji-mart";
|
|
6
|
+
import {EmojiDataProps, getEmojiDataProps} from "./data/get-data";
|
|
7
|
+
|
|
8
|
+
type NimblePickerWithData = Omit<NimblePickerProps, keyof EmojiDataProps>;
|
|
9
|
+
|
|
10
|
+
const NimblePickerWithData = lazy(async () => {
|
|
11
|
+
const emojiDataProps = await getEmojiDataProps();
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
default: function EmojiPicker(props: NimblePickerWithData) {
|
|
15
|
+
return <NimblePicker {...props} {...emojiDataProps} />;
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const EmojiPickerComponent: React.FC<NimblePickerWithData> = (props) => {
|
|
21
|
+
return (
|
|
22
|
+
<Suspense
|
|
23
|
+
fallback={
|
|
24
|
+
<div
|
|
25
|
+
className="emoji-mart"
|
|
26
|
+
style={{
|
|
27
|
+
height: "280px",
|
|
28
|
+
}}
|
|
29
|
+
/>
|
|
30
|
+
}
|
|
31
|
+
>
|
|
32
|
+
<NimblePickerWithData {...props} />
|
|
33
|
+
</Suspense>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
8
36
|
|
|
9
37
|
export type EmojiPickerProps = {
|
|
10
38
|
borderless?: boolean;
|
|
11
39
|
color?: string;
|
|
40
|
+
getHoverColor?: (color: string) => string | undefined;
|
|
12
41
|
colors?: string[];
|
|
13
42
|
onColorSelect?: (c: $TSFixMe) => void;
|
|
14
|
-
} &
|
|
43
|
+
} & NimblePickerWithData;
|
|
15
44
|
|
|
16
45
|
const i18n = {search: "Search emoji..."};
|
|
17
46
|
|
|
18
|
-
export const EmojiPicker = forwardRef<HTMLDivElement, EmojiPickerProps>(function
|
|
19
|
-
{
|
|
47
|
+
export const EmojiPicker = forwardRef<HTMLDivElement, EmojiPickerProps>(function EmojiPicker(
|
|
48
|
+
{
|
|
49
|
+
borderless = true,
|
|
50
|
+
color,
|
|
51
|
+
getHoverColor,
|
|
52
|
+
colors = cardTypeColors,
|
|
53
|
+
onColorSelect,
|
|
54
|
+
showSkinTones = true,
|
|
55
|
+
...pickerProps
|
|
56
|
+
},
|
|
20
57
|
ref
|
|
21
58
|
) {
|
|
22
|
-
const themeMode = useThemeMode();
|
|
23
|
-
const theme = useTheme();
|
|
24
|
-
|
|
25
59
|
return (
|
|
26
|
-
<EmojiMartWrapper
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
{onColorSelect ? <ColorPicker colors={colors} color={color} onChangeComplete={onColorSelect} /> : null}
|
|
60
|
+
<EmojiMartWrapper
|
|
61
|
+
ref={ref}
|
|
62
|
+
emojiHoverColor={color ? getHoverColor?.(color) : undefined}
|
|
63
|
+
borderless={borderless}
|
|
64
|
+
hideCategories
|
|
65
|
+
shortSearch={showSkinTones}
|
|
66
|
+
>
|
|
67
|
+
<EmojiPickerComponent showSkinTones={showSkinTones} i18n={i18n} {...pickerProps} />
|
|
68
|
+
{onColorSelect ? (
|
|
69
|
+
<ColorPicker
|
|
70
|
+
colors={colors}
|
|
71
|
+
getSwatchHoverColor={getHoverColor}
|
|
72
|
+
color={color}
|
|
73
|
+
onChangeComplete={onColorSelect}
|
|
74
|
+
/>
|
|
75
|
+
) : null}
|
|
43
76
|
</EmojiMartWrapper>
|
|
44
77
|
);
|
|
45
78
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// copied from https://github.com/nolanlawson/emoji-picker-element/
|
|
2
2
|
const versionsAndTestEmoji = {
|
|
3
|
+
"π«Έπ»": 15,
|
|
3
4
|
"π« ": 14,
|
|
4
5
|
"π₯²": 13.1, // smiling face with tear, technically from v13 but see note above
|
|
5
6
|
"π₯»": 12.1, // sari, technically from v12 but see note above
|