@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.
Files changed (63) hide show
  1. package/package.json +5 -5
  2. package/src/Button/button.tsx +14 -7
  3. package/src/designSystem.ts +86 -10
  4. package/src/emoji-mart/app-icon-picker.tsx +34 -16
  5. package/src/emoji-mart/data/get-data.tsx +51 -0
  6. package/src/emoji-mart/data.tsx +4 -0
  7. package/src/emoji-mart/emoji/emoji.tsx +26 -0
  8. package/src/emoji-mart/emoji/index.tsx +24 -0
  9. package/src/emoji-mart/emoji-index.ts +5 -0
  10. package/src/emoji-mart/emoji-mart.tsx +117 -36
  11. package/src/emoji-mart/emoji-picker.tsx +68 -22
  12. package/src/emoji-mart/emoji-support.ts +1 -0
  13. package/src/emoji-mart/icon-emoji-picker.tsx +37 -9
  14. package/src/icons/ast/Activity.ts +1 -1
  15. package/src/icons/ast/ActivityLog.ts +1 -1
  16. package/src/icons/ast/AddReactions.ts +1 -1
  17. package/src/icons/ast/AppStore.ts +1 -1
  18. package/src/icons/ast/AppStoreOneColor.ts +1 -1
  19. package/src/icons/ast/AppTemplates.ts +1 -1
  20. package/src/icons/ast/AppTemplatesOneColor.ts +1 -1
  21. package/src/icons/ast/AskForInput.ts +1 -1
  22. package/src/icons/ast/Cards.ts +1 -1
  23. package/src/icons/ast/ClearValue.ts +1 -1
  24. package/src/icons/ast/Close.ts +1 -1
  25. package/src/icons/ast/ColorCoding.ts +1 -1
  26. package/src/icons/ast/Columns.ts +1 -1
  27. package/src/icons/ast/Favorites.ts +1 -1
  28. package/src/icons/ast/FavoritesChecked.ts +1 -1
  29. package/src/icons/ast/FavoritesMenu.ts +1 -1
  30. package/src/icons/ast/Fields.ts +1 -1
  31. package/src/icons/ast/Filter.ts +1 -1
  32. package/src/icons/ast/FocusMode.ts +1 -1
  33. package/src/icons/ast/FocusModeOff.ts +1 -1
  34. package/src/icons/ast/ImageXmark.ts +8 -0
  35. package/src/icons/ast/InvitePeople.ts +1 -1
  36. package/src/icons/ast/Items.ts +1 -1
  37. package/src/icons/ast/Levels.ts +1 -1
  38. package/src/icons/ast/Lock.ts +1 -1
  39. package/src/icons/ast/MoreCompact.ts +1 -1
  40. package/src/icons/ast/MySpace.ts +1 -1
  41. package/src/icons/ast/OpenAsPage.ts +1 -1
  42. package/src/icons/ast/PageRegularMode.ts +1 -1
  43. package/src/icons/ast/PageWideMode.ts +1 -1
  44. package/src/icons/ast/Popup.ts +1 -1
  45. package/src/icons/ast/Posts.ts +1 -1
  46. package/src/icons/ast/RicheditorImageUpload.ts +1 -1
  47. package/src/icons/ast/Rows.ts +1 -1
  48. package/src/icons/ast/Search.ts +1 -1
  49. package/src/icons/ast/Settings.ts +1 -1
  50. package/src/icons/ast/Share.ts +1 -1
  51. package/src/icons/ast/Shared.ts +1 -1
  52. package/src/icons/ast/SidebarFields.ts +1 -1
  53. package/src/icons/ast/SidebarFieldsOpened.ts +1 -1
  54. package/src/icons/ast/Sort.ts +1 -1
  55. package/src/icons/ast/SortOnBottom.ts +1 -1
  56. package/src/icons/ast/SortOnTop.ts +1 -1
  57. package/src/icons/ast/TypeButton.ts +1 -1
  58. package/src/icons/ast/TypeEmoji.ts +1 -1
  59. package/src/icons/ast/Upgrade.ts +1 -1
  60. package/src/icons/ast/index.tsx +1 -0
  61. package/src/icons/react/ImageXmark.tsx +12 -0
  62. package/src/icons/react/index.tsx +1 -0
  63. 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.10.0",
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/*.ts*"
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.13.8",
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/babel-preset": "7.2.0",
97
- "@fibery/eslint-config": "8.3.0"
96
+ "@fibery/eslint-config": "8.3.0",
97
+ "@fibery/babel-preset": "7.2.0"
98
98
  },
99
99
  "jest": {
100
100
  "testEnvironment": "jsdom",
@@ -38,10 +38,10 @@ const HorizontalPaddings = {
38
38
  } as const;
39
39
 
40
40
  const IconSizes = {
41
- ":button-size/super-small": 16,
42
- ":button-size/small": 18,
43
- ":button-size/normal": 20,
44
- ":button-size/big": 22,
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
- return {iconSize, leftContainerSize, leftContainerMarginRight};
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 backgroundColor={spinnerBgColor} color={spinnerColor} size={iconSize} containerSize={leftContainerSize} />
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;
@@ -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
- (themeMode: ThemeMode, color: string) => {
546
- switch (themeMode) {
547
- case "dark":
548
- return makeChromaColor(color).darken(2.2).alpha(0.5).saturate(1).css();
549
- default:
550
- return color;
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
- export const pastelColors = cardTypeColors.map((color) => makeChromaColor(color).luminance(0.8).hex());
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 {EmojiMartWrapper, NimblePicker, PickerProps} from "./emoji-mart";
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 {getThemedUrl} from "../AppIconWithFallback";
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
- export type AppIconPickerProps = {borderless?: boolean} & PickerProps;
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 ref={ref} borderless={borderless} hideCategories>
38
- <NimblePicker
39
- data={EMPTY_DATA}
40
- theme={alignedTheme}
41
- showSkinTones={false}
42
- showPreview={false}
43
- title=""
44
- custom={customIcons}
45
- emojiSize={22}
46
- {...pickerProps}
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,4 @@
1
+ export const loadEmojiData = async () => {
2
+ const data = await import("emoji-mart/data/all.json");
3
+ return data;
4
+ };
@@ -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
+ };
@@ -0,0 +1,5 @@
1
+ import {NimbleEmojiIndex} from "emoji-mart";
2
+
3
+ import data from "./data/all.json";
4
+
5
+ export const emojiIndex = new NimbleEmojiIndex(data);
@@ -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 {border, space, textStyles, themeVars} from "../designSystem";
4
- import {cx, css} from "@linaria/core";
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
- export {emojiIndex, Picker, NimblePicker} from "emoji-mart";
8
- export type {BaseEmoji, PickerProps, EmojiSkin} from "emoji-mart";
7
+ import {NimblePickerProps, NimblePicker as Picker} from "emoji-mart";
8
+ import {alignTheme} from "../theme-settings";
9
9
 
10
- export const backgroundImageFn = () => "https://assets-temp.fibery.io/images/emoji-datasource-apple-5_0_1-64.png";
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-top: 1px solid ${themeVars.separatorColor};
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: 34px;
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: 50px;
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: 22px;
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
- type EmojiMartWrapperProps = React.PropsWithChildren<{borderless?: boolean; hideCategories?: boolean}>;
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(emojiMartCss, borderless && borderlessEmojiMartCss, hideCategories && hideCategoriesEmojiMartCss)}
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
- };