@fibery/ui-kit 1.10.0 → 1.11.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 +5 -5
- package/src/Button/button.tsx +14 -7
- package/src/designSystem.ts +86 -10
- package/src/emoji-mart/app-icon-picker.tsx +34 -16
- package/src/emoji-mart/data/get-data.tsx +51 -0
- package/src/emoji-mart/data.tsx +4 -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 +117 -36
- package/src/emoji-mart/emoji-picker.tsx +68 -22
- package/src/emoji-mart/emoji-support.ts +1 -0
- package/src/emoji-mart/icon-emoji-picker.tsx +37 -9
- 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.0",
|
|
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": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"rc-input-number": "7.3.11",
|
|
52
52
|
"rc-menu": "9.8.1",
|
|
53
53
|
"rc-progress": "3.4.1",
|
|
54
|
-
"react-color": "2.
|
|
54
|
+
"react-color": "2.19.3",
|
|
55
55
|
"react-day-picker": "8.1.4",
|
|
56
56
|
"react-popper": "2.3.0",
|
|
57
57
|
"react-select": "5.3.2",
|
|
@@ -93,8 +93,8 @@
|
|
|
93
93
|
"svgo": "2.8.0",
|
|
94
94
|
"typescript": "5.0.3",
|
|
95
95
|
"unist-util-reduce": "0.2.2",
|
|
96
|
-
"@fibery/
|
|
97
|
-
"@fibery/
|
|
96
|
+
"@fibery/eslint-config": "8.3.0",
|
|
97
|
+
"@fibery/babel-preset": "7.2.0"
|
|
98
98
|
},
|
|
99
99
|
"jest": {
|
|
100
100
|
"testEnvironment": "jsdom",
|
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,
|
|
@@ -202,6 +205,7 @@ const lightColors = {
|
|
|
202
205
|
cellBackgroundColor: slate.slate2,
|
|
203
206
|
cellBackgroundHoverColor: getOpacities(slate.slate6).opacity30,
|
|
204
207
|
cellBorderColor: getOpacities(slate.slate8).opacity50,
|
|
208
|
+
cellPinnedBorderColor: getOpacities(slate.slate8).opacity70,
|
|
205
209
|
tableRowWarningColor: getOpacities(yellow.yellow6).opacity60,
|
|
206
210
|
errorBgColor: getOpacities(red.red9).opacity20,
|
|
207
211
|
errorTextColor: red.red11,
|
|
@@ -254,6 +258,23 @@ const lightColors = {
|
|
|
254
258
|
progressFillBg: slate.slate11,
|
|
255
259
|
progressFillText: whiteA.whiteA0,
|
|
256
260
|
searchFiltersBg: slate.slate1,
|
|
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,
|
|
257
278
|
} as const;
|
|
258
279
|
|
|
259
280
|
const darkMenu = {
|
|
@@ -279,6 +300,7 @@ const darkColors = {
|
|
|
279
300
|
mode: "dark",
|
|
280
301
|
brandColors,
|
|
281
302
|
stateColors,
|
|
303
|
+
primaryBlue: indigoDark.indigo10,
|
|
282
304
|
whiteColor: whiteA.whiteA0,
|
|
283
305
|
blackColor: blackA.blackA0,
|
|
284
306
|
mainBg: slateDark.slate1,
|
|
@@ -316,6 +338,7 @@ const darkColors = {
|
|
|
316
338
|
inputBorderFocusColor: `0 0 0 1px ${getOpacities(slateDark.slate9).opacity100}`,
|
|
317
339
|
inputBorderBlendMode: "lighten",
|
|
318
340
|
inputPlaceholderTextColor: slateDark.slate9,
|
|
341
|
+
buttonPrimaryColor: indigoDark.indigo10,
|
|
319
342
|
buttonColor: slateDark.slate10,
|
|
320
343
|
buttonPrimaryTextColor: slate.slate6,
|
|
321
344
|
checkboxColor: slateDark.slate10,
|
|
@@ -364,6 +387,7 @@ const darkColors = {
|
|
|
364
387
|
cellBackgroundColor: slateDark.slate2,
|
|
365
388
|
cellBackgroundHoverColor: getOpacities(slateDark.slate6).opacity30,
|
|
366
389
|
cellBorderColor: getOpacities(slateDark.slate9).opacity50,
|
|
390
|
+
cellPinnedBorderColor: getOpacities(slateDark.slate9).opacity70,
|
|
367
391
|
tableRowWarningColor: getOpacities(yellowDark.yellow9).opacity40,
|
|
368
392
|
errorBgColor: getOpacities(redDark.red9).opacity60,
|
|
369
393
|
errorTextColor: red.red7,
|
|
@@ -414,10 +438,29 @@ const darkColors = {
|
|
|
414
438
|
progressFillBg: slate.slate11,
|
|
415
439
|
progressFillText: whiteA.whiteA0,
|
|
416
440
|
searchFiltersBg: slateDark.slate2,
|
|
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,
|
|
417
458
|
...darkMenu,
|
|
418
459
|
} as const;
|
|
419
460
|
|
|
420
461
|
export function getLightColors(): typeof lightColors {
|
|
462
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
463
|
+
// @ts-ignore
|
|
421
464
|
if (process.env.NODE_ENV !== "test") {
|
|
422
465
|
throw new Error("Only for test purpose");
|
|
423
466
|
}
|
|
@@ -425,6 +468,8 @@ export function getLightColors(): typeof lightColors {
|
|
|
425
468
|
}
|
|
426
469
|
|
|
427
470
|
export function getDarkColors(): typeof darkColors {
|
|
471
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
472
|
+
// @ts-ignore
|
|
428
473
|
if (process.env.NODE_ENV !== "test") {
|
|
429
474
|
throw new Error("Only for test purpose");
|
|
430
475
|
}
|
|
@@ -432,6 +477,8 @@ export function getDarkColors(): typeof darkColors {
|
|
|
432
477
|
}
|
|
433
478
|
|
|
434
479
|
export function getLight2Colors(): typeof light2Colors {
|
|
480
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
481
|
+
// @ts-ignore
|
|
435
482
|
if (process.env.NODE_ENV !== "test") {
|
|
436
483
|
throw new Error("Only for test purpose");
|
|
437
484
|
}
|
|
@@ -541,19 +588,50 @@ export const getLinkedHighlightBackgroundColor = _.memoize(
|
|
|
541
588
|
(themeMode, color) => `${themeMode}-${color}`
|
|
542
589
|
);
|
|
543
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
|
+
|
|
544
602
|
export const getEnumBackgroundColor = _.memoize(
|
|
545
|
-
(
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
}
|
|
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
|
+
});
|
|
552
610
|
},
|
|
553
611
|
(themeMode, color) => `${themeMode}-${color}`
|
|
554
612
|
);
|
|
555
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
|
+
|
|
556
631
|
export const cardTypeColors = [
|
|
632
|
+
"#4A4A4A",
|
|
633
|
+
"#6A849B",
|
|
634
|
+
"#BEC5CC",
|
|
557
635
|
"#D40915",
|
|
558
636
|
"#E72065",
|
|
559
637
|
"#9C2BAF",
|
|
@@ -568,11 +646,9 @@ export const cardTypeColors = [
|
|
|
568
646
|
"#FBA32F",
|
|
569
647
|
"#FC551F",
|
|
570
648
|
"#B04E31",
|
|
571
|
-
"#6A849B",
|
|
572
|
-
"#4A4A4A",
|
|
573
649
|
] as const;
|
|
574
650
|
|
|
575
|
-
|
|
651
|
+
const pastelColors = cardTypeColors.map((color) => makeChromaColor(color).luminance(0.8).hex());
|
|
576
652
|
|
|
577
653
|
export const dropCursorColor = chroma(brandColors.blue).alpha(0.7).css();
|
|
578
654
|
export const colors = {
|
|
@@ -1,9 +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";
|
|
6
|
+
import {$TSFixMe} from "../tsfixme";
|
|
7
|
+
import type {EmojiDataProps} from "./data/get-data";
|
|
8
|
+
import {EmojiMartWrapper, NimblePicker, NimblePickerProps} from "./emoji-mart";
|
|
9
|
+
import {ColorPicker} from "../ColorPicker";
|
|
10
|
+
import {cardTypeColors} from "../designSystem";
|
|
7
11
|
|
|
8
12
|
const EMPTY_DATA = {
|
|
9
13
|
aliases: {},
|
|
@@ -12,10 +16,20 @@ const EMPTY_DATA = {
|
|
|
12
16
|
compressed: false,
|
|
13
17
|
};
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
type NimblePickerWithData = Omit<NimblePickerProps, keyof EmojiDataProps>;
|
|
20
|
+
|
|
21
|
+
export type AppIconPickerProps = {
|
|
22
|
+
borderless?: boolean;
|
|
23
|
+
color?: string;
|
|
24
|
+
getHoverColor?: (color: string) => string | undefined;
|
|
25
|
+
colors?: string[];
|
|
26
|
+
onColorSelect?: (c: $TSFixMe) => void;
|
|
27
|
+
} & NimblePickerWithData;
|
|
28
|
+
|
|
29
|
+
const i18n = {search: "Search icon...", notfound: "No Icons Found"};
|
|
16
30
|
|
|
17
31
|
export const AppIconPicker = forwardRef<HTMLDivElement, AppIconPickerProps>(function AppIconPicker(
|
|
18
|
-
{borderless = true, ...pickerProps},
|
|
32
|
+
{borderless = true, color, getHoverColor, colors = cardTypeColors, onColorSelect, ...pickerProps},
|
|
19
33
|
ref
|
|
20
34
|
) {
|
|
21
35
|
const themeMode = useThemeMode();
|
|
@@ -34,17 +48,21 @@ export const AppIconPicker = forwardRef<HTMLDivElement, AppIconPickerProps>(func
|
|
|
34
48
|
);
|
|
35
49
|
|
|
36
50
|
return (
|
|
37
|
-
<EmojiMartWrapper
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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}
|
|
48
66
|
</EmojiMartWrapper>
|
|
49
67
|
);
|
|
50
68
|
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type {Data} from "emoji-mart";
|
|
2
|
+
import {detectEmojiSupportLevel} from "../emoji-support";
|
|
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
|
+
const getAppleDataProps = async (): Promise<EmojiDataProps> => {
|
|
19
|
+
const [level, data] = await Promise.all([detectEmojiSupportLevel(), import("./all.json")]);
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
native: level >= 14, // until twemoji supports v15 our all.json represents data for v14
|
|
23
|
+
data: data.default,
|
|
24
|
+
backgroundImageFn,
|
|
25
|
+
set: "apple",
|
|
26
|
+
sheetColumns: 61,
|
|
27
|
+
sheetRows: 61,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
const getTwitterDataProps = async (): Promise<EmojiDataProps> => {
|
|
31
|
+
const data = await import("./all.json");
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
native: false,
|
|
35
|
+
data: data.default,
|
|
36
|
+
backgroundImageFn,
|
|
37
|
+
set: "twitter",
|
|
38
|
+
sheetColumns: 61,
|
|
39
|
+
sheetRows: 61,
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const isApple = () => /Mac|iPhone|iPad/.test(navigator.userAgent);
|
|
44
|
+
|
|
45
|
+
export const getEmojiDataProps = async () => {
|
|
46
|
+
if (!promise) {
|
|
47
|
+
promise = isApple() ? getAppleDataProps() : getTwitterDataProps();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return promise;
|
|
51
|
+
};
|
|
@@ -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,40 +1,81 @@
|
|
|
1
|
+
import {CSSProperties, css, cx} from "@linaria/core";
|
|
1
2
|
import "emoji-mart/css/emoji-mart.css";
|
|
2
3
|
import {forwardRef} from "react";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {Emoji, EmojiProps} from "emoji-mart";
|
|
4
|
+
import {useTheme, useThemeMode} from "../ThemeProvider";
|
|
5
|
+
import {border, fontFamily, space, textStyles, themeVars} from "../designSystem";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import {NimblePickerProps, NimblePicker as Picker} from "emoji-mart";
|
|
8
|
+
import {alignTheme} from "../theme-settings";
|
|
9
9
|
|
|
10
|
-
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
|
+
};
|
|
11
30
|
|
|
12
31
|
const emojiMartCss = css`
|
|
32
|
+
padding: 0 ${space.l}px;
|
|
33
|
+
position: relative;
|
|
34
|
+
|
|
13
35
|
.emoji-mart {
|
|
36
|
+
font-family: ${fontFamily};
|
|
14
37
|
background-color: ${themeVars.actionMenuBg};
|
|
15
38
|
margin-top: ${space.xxs}px;
|
|
16
39
|
display: block;
|
|
40
|
+
width: 288px !important;
|
|
41
|
+
|
|
42
|
+
+ * {
|
|
43
|
+
border-top: 1px solid ${themeVars.separatorColor};
|
|
44
|
+
}
|
|
17
45
|
}
|
|
18
46
|
|
|
19
47
|
.emoji-mart-bar {
|
|
20
48
|
border-bottom: 1px solid ${themeVars.separatorColor};
|
|
21
49
|
|
|
22
50
|
&:last-child {
|
|
23
|
-
border
|
|
51
|
+
border: 0;
|
|
24
52
|
}
|
|
25
53
|
}
|
|
26
54
|
|
|
27
55
|
.emoji-mart-search {
|
|
28
56
|
padding-bottom: ${space.s}px;
|
|
57
|
+
padding-left: 0;
|
|
58
|
+
padding-right: 0;
|
|
29
59
|
|
|
30
60
|
& input {
|
|
31
61
|
${textStyles.regular}
|
|
32
62
|
background-color: ${themeVars.inputBgColor};
|
|
33
63
|
color: ${themeVars.textColor};
|
|
34
64
|
box-shadow: ${themeVars.inputBorderColor};
|
|
35
|
-
height:
|
|
65
|
+
height: 32px;
|
|
36
66
|
border: 0;
|
|
37
67
|
}
|
|
68
|
+
|
|
69
|
+
& .emoji-mart-search-icon {
|
|
70
|
+
top: 5px;
|
|
71
|
+
right: 4px;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.emoji-mart-scroll {
|
|
76
|
+
padding-left: 0;
|
|
77
|
+
padding-right: 0;
|
|
78
|
+
height: 238px;
|
|
38
79
|
}
|
|
39
80
|
|
|
40
81
|
.emoji-anchor-bar {
|
|
@@ -57,7 +98,7 @@ const emojiMartCss = css`
|
|
|
57
98
|
}
|
|
58
99
|
|
|
59
100
|
.emoji-mart-category .emoji-mart-emoji:hover::before {
|
|
60
|
-
background-color: ${themeVars.badgeBgColor} !important;
|
|
101
|
+
background-color: var(--fibery-emoji-hover-color, ${themeVars.badgeBgColor}) !important;
|
|
61
102
|
border-radius: ${border.radius8}px !important;
|
|
62
103
|
}
|
|
63
104
|
.emoji-mart-dark .emoji-mart-category-label span {
|
|
@@ -69,23 +110,64 @@ const emojiMartCss = css`
|
|
|
69
110
|
}
|
|
70
111
|
|
|
71
112
|
.emoji-mart-preview {
|
|
72
|
-
height:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
.emoji-mart-preview-skins {
|
|
76
|
-
right: 15px;
|
|
113
|
+
height: 0px;
|
|
114
|
+
position: unset;
|
|
77
115
|
}
|
|
78
116
|
|
|
79
117
|
.emoji-mart-emoji {
|
|
118
|
+
color: ${themeVars.textColor};
|
|
80
119
|
/* pathetic attemts to make it a bit faster without forking */
|
|
81
120
|
content-visibility: auto;
|
|
82
|
-
contain-intrinsic-size:
|
|
121
|
+
contain-intrinsic-size: 20px;
|
|
122
|
+
cursor: pointer;
|
|
83
123
|
}
|
|
84
124
|
.emoji-mart-category-list,
|
|
85
125
|
.emoji-mart-category-list li {
|
|
86
126
|
/* hack to maintain correct size of hidden emojis becuase of content-visibility */
|
|
87
127
|
line-height: 0;
|
|
88
128
|
}
|
|
129
|
+
.emoji-mart-preview-skins {
|
|
130
|
+
top: 16px;
|
|
131
|
+
right: 12px !important;
|
|
132
|
+
z-index: 2;
|
|
133
|
+
background-color: ${themeVars.actionMenuBg};
|
|
134
|
+
|
|
135
|
+
& .emoji-mart-skin-swatches {
|
|
136
|
+
background-color: ${themeVars.actionMenuBg};
|
|
137
|
+
|
|
138
|
+
&.opened {
|
|
139
|
+
& .emoji-mart-skin-swatch {
|
|
140
|
+
width: 32px !important;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
& .emoji-mart-skin-swatch {
|
|
145
|
+
height: 32px !important;
|
|
146
|
+
|
|
147
|
+
&.selected {
|
|
148
|
+
width: 32px !important;
|
|
149
|
+
padding: 0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
&:hover {
|
|
153
|
+
background-color: ${themeVars.badgeBgColor} !important;
|
|
154
|
+
border-radius: ${border.radius8}px !important;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
& .emoji-mart-skin-text {
|
|
158
|
+
height: auto;
|
|
159
|
+
padding: 0;
|
|
160
|
+
background-color: ${themeVars.actionMenuBg};
|
|
161
|
+
color: ${themeVars.accentTextColor};
|
|
162
|
+
border-radius: 0;
|
|
163
|
+
|
|
164
|
+
&.opened {
|
|
165
|
+
width: 98px;
|
|
166
|
+
padding-left: 8px;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
89
171
|
`;
|
|
90
172
|
|
|
91
173
|
const borderlessEmojiMartCss = css`
|
|
@@ -100,36 +182,35 @@ const hideCategoriesEmojiMartCss = css`
|
|
|
100
182
|
}
|
|
101
183
|
`;
|
|
102
184
|
|
|
103
|
-
|
|
185
|
+
const emojiMartWithShortSearchCss = css`
|
|
186
|
+
.emoji-mart-search {
|
|
187
|
+
width: 250px;
|
|
188
|
+
}
|
|
189
|
+
`;
|
|
190
|
+
|
|
191
|
+
type EmojiMartWrapperProps = React.PropsWithChildren<{
|
|
192
|
+
borderless?: boolean;
|
|
193
|
+
hideCategories?: boolean;
|
|
194
|
+
shortSearch?: boolean;
|
|
195
|
+
emojiHoverColor?: string;
|
|
196
|
+
}>;
|
|
104
197
|
|
|
105
198
|
export const EmojiMartWrapper = forwardRef<HTMLDivElement, EmojiMartWrapperProps>(function EmojiMartWrapper(
|
|
106
|
-
{borderless, hideCategories, children},
|
|
199
|
+
{borderless, hideCategories, emojiHoverColor, shortSearch, children},
|
|
107
200
|
ref
|
|
108
201
|
) {
|
|
109
202
|
return (
|
|
110
203
|
<div
|
|
204
|
+
style={{"--fibery-emoji-hover-color": emojiHoverColor} as CSSProperties}
|
|
111
205
|
ref={ref}
|
|
112
|
-
className={cx(
|
|
206
|
+
className={cx(
|
|
207
|
+
emojiMartCss,
|
|
208
|
+
borderless && borderlessEmojiMartCss,
|
|
209
|
+
hideCategories && hideCategoriesEmojiMartCss,
|
|
210
|
+
shortSearch && emojiMartWithShortSearchCss
|
|
211
|
+
)}
|
|
113
212
|
>
|
|
114
213
|
{children}
|
|
115
214
|
</div>
|
|
116
215
|
);
|
|
117
216
|
});
|
|
118
|
-
|
|
119
|
-
const emojiWrapperCss = css`
|
|
120
|
-
& span.emoji-mart-emoji-native {
|
|
121
|
-
line-height: 1;
|
|
122
|
-
vertical-align: middle;
|
|
123
|
-
& span {
|
|
124
|
-
vertical-align: middle;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
`;
|
|
128
|
-
|
|
129
|
-
export const EmojiMartEmoji: React.FC<EmojiProps> = (props) => {
|
|
130
|
-
return (
|
|
131
|
-
<span className={emojiWrapperCss}>
|
|
132
|
-
<Emoji backgroundImageFn={backgroundImageFn} {...props} />
|
|
133
|
-
</span>
|
|
134
|
-
);
|
|
135
|
-
};
|