Use Joypixels instead of native emojis (#176)

* fist test

* Use a font

* Cleanup

* Use right fallbacks for fonts

* Lint

* Cleanup and comment

* Add visual test
This commit is contained in:
Samy Pessé
2024-02-20 13:54:57 +01:00
committed by GitHub
parent 258ef413b1
commit a2d967e98e
14 changed files with 127 additions and 16 deletions
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
index.ts
+26
View File
@@ -0,0 +1,26 @@
import fs from 'fs';
import emojisRaws from 'emoji-assets/emoji.json';
interface EmojiData {
code_points: {
base: string;
fully_qualified: string;
};
}
const emojis = emojisRaws as Record<string, EmojiData>;
const output: Record<string, string> = {};
Object.entries(emojis).forEach(([key, value]) => {
const emoji = value.code_points?.fully_qualified;
if (emoji && key !== emoji) {
output[key] = emoji;
} else if (!emoji) {
console.log('No emoji for', key);
}
});
fs.writeFileSync(
'index.ts',
`export const emojiCodepoints: Record<string, string> = ${JSON.stringify(output, null, 4)};`,
);
+13
View File
@@ -0,0 +1,13 @@
{
"name": "@gitbook/emoji-codepoints",
"description": "Optimized mapping of codepoints to the fully qualified emoji codepoints",
"private": true,
"main": "./index.ts",
"dependencies": {},
"devDependencies": {
"emoji-assets": "^8.0.0"
},
"scripts": {
"postinstall": "bun ./build.ts"
}
}
+2
View File
@@ -7,6 +7,7 @@ import {
import assertNever from 'assert-never';
import colors from 'tailwindcss/colors';
import { emojiFontClassName } from '@/components/primitives';
import { fonts, ibmPlexMono } from '@/fonts';
import { getSpaceLanguage } from '@/intl/server';
import { getSpaceContent } from '@/lib/api';
@@ -103,6 +104,7 @@ export default async function SpaceRootLayout(props: {
</head>
<body
className={tcls(
emojiFontClassName,
`${fonts[customization.styling.font].className}`,
`${ibmPlexMono.variable}`,
'bg-light',
@@ -15,9 +15,7 @@ export async function BlockContentRef(props: BlockProps<DocumentBlockContentRef>
return (
<Card
leadingIcon={
resolved.emoji ? <Emoji code={resolved.emoji} style={['text-xl']} /> : null
}
leadingIcon={resolved.emoji ? <Emoji code={resolved.emoji} /> : null}
href={resolved.href}
preTitle={kind}
title={resolved.text}
-13
View File
@@ -1,13 +0,0 @@
import { ClassValue, tcls } from '@/lib/tailwind';
/**
* Render an emoji by its UTF-8 codepoint.
*/
export async function Emoji(props: { code: string; style?: ClassValue }) {
const { code, style } = props;
const emojiCodepointDecimal = parseInt(code, 16);
const emoji = String.fromCodePoint(emojiCodepointDecimal);
return <span className={tcls(style)}>{emoji}</span>;
}
+55
View File
@@ -0,0 +1,55 @@
import { emojiCodepoints } from '@gitbook/emoji-codepoints';
import localFont from 'next/font/local';
import { ClassValue, tcls } from '@/lib/tailwind';
import './emoji.css';
/* Load the 3 variants of the font as CSS variables and let the emoji.css decide on the best one to use */
const svgFont = localFont({
src: './svg.woff2',
preload: false,
variable: '--font-emojis-svg',
});
const sbixFont = localFont({
src: './sbix.woff2',
preload: false,
variable: '--font-emojis-sbix',
});
const cbdtFont = localFont({
src: './cbdt.woff2',
preload: false,
variable: '--font-emojis-cbdt',
});
/**
* Class name to set on the <html> tag to use the emoji font.
*/
export const emojiFontClassName = [svgFont.variable, sbixFont.variable, cbdtFont.variable].join(
' ',
);
/**
* Render an emoji by its codepoint.
* It renders the UTF-8 character and use the emojione font to display it (fallbacking to default browser font).
*/
export async function Emoji(props: { code: string; style?: ClassValue }) {
const { code, style } = props;
const fullCode = emojiCodepoints[code] ?? code;
const fallback = getEmojiForCodepoint(fullCode);
return <span className={'emoji ' + tcls(style)}>{fallback}</span>;
}
function getEmojiForCodepoint(unicode: string): string {
if (!unicode) {
return '';
}
const codePoints = unicode.split('-').map((elt) => parseInt(elt, 16));
return String.fromCodePoint(...codePoints);
}
Binary file not shown.
+24
View File
@@ -0,0 +1,24 @@
[class*='emoji'] {
font-family: var(--font-emojis-cbdt);
}
/* Safari Only CSS here */
_::-webkit-full-page-media,
_:future,
:root [class*='emoji'] {
font-family: var(--font-emojis-sbix);
}
/* Chrome Only CSS here */
@media screen and (-webkit-min-device-pixel-ratio: 0) {
.emoji {
font-family: var(--font-emojis-svg);
}
}
/* Firefox Only CSS here */
@-moz-document url-prefix() {
.emoji {
font-family: var(--font-emojis-svg);
}
}
+1
View File
@@ -0,0 +1 @@
export * from './Emoji';
Binary file not shown.
Binary file not shown.
+4
View File
@@ -213,6 +213,10 @@ const testCases: TestsCase[] = [
name: 'Marks',
url: 'blocks/marks',
},
{
name: 'Emojis',
url: 'blocks/emojis',
},
],
},
];