diff --git a/site/package.json b/site/package.json index 639ab05281..815600222d 100644 --- a/site/package.json +++ b/site/package.json @@ -32,7 +32,7 @@ }, "dependencies": { "@emoji-mart/data": "1.1.2", - "@emoji-mart/react": "1.0.1", + "@emoji-mart/react": "1.1.1", "@emotion/css": "11.11.2", "@emotion/react": "11.11.1", "@emotion/styled": "11.11.0", diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml index 40ade685f6..f9f444beed 100644 --- a/site/pnpm-lock.yaml +++ b/site/pnpm-lock.yaml @@ -13,8 +13,8 @@ dependencies: specifier: 1.1.2 version: 1.1.2 '@emoji-mart/react': - specifier: 1.0.1 - version: 1.0.1(emoji-mart@5.4.0)(react@18.2.0) + specifier: 1.1.1 + version: 1.1.1(emoji-mart@5.4.0)(react@18.2.0) '@emotion/css': specifier: 11.11.2 version: 11.11.2 @@ -2234,8 +2234,8 @@ packages: resolution: {integrity: sha512-1HP8BxD2azjqWJvxIaWAMyTySeZY0Osr83ukYjltPVkNXeJvTz7yDrPLBtnrD5uqJ3tg4CcLuuBW09wahqL/fg==} dev: false - /@emoji-mart/react@1.0.1(emoji-mart@5.4.0)(react@18.2.0): - resolution: {integrity: sha512-ALhLD96BOL5w+a4NI5NpmfqfF1aVjjj2qJE0dLst/OhjBfVmpteWNgn/h8LZy9ulU6AnbeS+13KnPFzDjCvRRw==} + /@emoji-mart/react@1.1.1(emoji-mart@5.4.0)(react@18.2.0): + resolution: {integrity: sha512-NMlFNeWgv1//uPsvLxvGQoIerPuVdXwK/EUek8OOkJ6wVOWPUizRBJU0hDqWZCOROVpfBgCemaC3m6jDOXi03g==} peerDependencies: emoji-mart: ^5.2 react: ^16.8 || ^17 || ^18 diff --git a/site/src/@types/emoji-mart.d.ts b/site/src/@types/emoji-mart.d.ts index 07508bafcc..18c1d81eab 100644 --- a/site/src/@types/emoji-mart.d.ts +++ b/site/src/@types/emoji-mart.d.ts @@ -1,9 +1,42 @@ declare module "@emoji-mart/react" { - const Picker: React.FC<{ + interface CustomCategory { + id: string; + name: string; + emojis: CustomEmoji[]; + } + + interface CustomEmoji { + id: string; + name: string; + keywords: string[]; + skins: CustomEmojiSkin[]; + } + + interface CustomEmojiSkin { + src: string; + } + + type EmojiData = EmojiResource & { + id: string; + keywords: string[]; + name: string; + native?: string; + shortcodes: string; + }; + + type EmojiResource = + | { unified: undefined; src: string } + | { unified: string; src: undefined }; + + const EmojiPicker: React.FC<{ + set: "native" | "apple" | "facebook" | "google" | "twitter"; theme: "dark" | "light"; - data: Record; - onEmojiSelect: (emojiData: { unified: string }) => void; + data: unknown; + custom: CustomCategory[]; + emojiButtonSize?: number; + emojiSize?: number; + onEmojiSelect: (emoji: EmojiData) => void; }>; - export default Picker; + export default EmojiPicker; } diff --git a/site/src/components/IconField/IconField.stories.tsx b/site/src/components/IconField/IconField.stories.tsx new file mode 100644 index 0000000000..35b558d023 --- /dev/null +++ b/site/src/components/IconField/IconField.stories.tsx @@ -0,0 +1,28 @@ +import { action } from "@storybook/addon-actions"; +import IconField from "./IconField"; +import type { Meta, StoryObj } from "@storybook/react"; + +const meta: Meta = { + title: "components/IconField", + component: IconField, + args: { + onPickEmoji: action("onPickEmoji"), + }, +}; + +export default meta; +type Story = StoryObj; + +export const Example: Story = {}; + +export const EmojiSelected: Story = { + args: { + value: "/emojis/1f3f3-fe0f-200d-26a7-fe0f.png", + }, +}; + +export const IconSelected: Story = { + args: { + value: "/icon/fedora.svg", + }, +}; diff --git a/site/src/components/IconField/IconField.tsx b/site/src/components/IconField/IconField.tsx index 2e5e0ba606..ab6fd044a8 100644 --- a/site/src/components/IconField/IconField.tsx +++ b/site/src/components/IconField/IconField.tsx @@ -2,18 +2,40 @@ import Button from "@mui/material/Button"; import InputAdornment from "@mui/material/InputAdornment"; import Popover from "@mui/material/Popover"; import TextField, { TextFieldProps } from "@mui/material/TextField"; -import { DropdownArrow } from "components/DropdownArrow/DropdownArrow"; -import { useRef, FC, useState } from "react"; -import Picker from "@emoji-mart/react"; import { makeStyles } from "@mui/styles"; +import Picker from "@emoji-mart/react"; +import { useRef, FC, useState } from "react"; +import { DropdownArrow } from "components/DropdownArrow/DropdownArrow"; +import { Stack } from "components/Stack/Stack"; import { colors } from "theme/colors"; import data from "@emoji-mart/data/sets/14/twitter.json"; -import { Stack } from "components/Stack/Stack"; +import icons from "theme/icons.json"; + +// See: https://github.com/missive/emoji-mart/issues/51#issuecomment-287353222 +const urlFromUnifiedCode = (unified: string) => + `/emojis/${unified.replace(/-fe0f$/, "")}.png`; type IconFieldProps = TextFieldProps & { onPickEmoji: (value: string) => void; }; +const custom = [ + { + id: "icons", + name: "Icons", + emojis: icons.map((icon) => { + const id = icon.split(".")[0]; + + return { + id, + name: id, + keywords: id.split("-"), + skins: [{ src: `/icon/${icon}` }], + }; + }), + }, +]; + const IconField: FC = ({ onPickEmoji, ...textFieldProps }) => { if ( typeof textFieldProps.value !== "string" && @@ -69,14 +91,12 @@ const IconField: FC = ({ onPickEmoji, ...textFieldProps }) => { }} > { - // See: https://github.com/missive/emoji-mart/issues/51#issuecomment-287353222 - const value = `/emojis/${emojiData.unified.replace( - /-fe0f$/, - "", - )}.png`; + custom={custom} + onEmojiSelect={(emoji) => { + const value = emoji.src ?? urlFromUnifiedCode(emoji.unified); onPickEmoji(value); setIsEmojiPickerOpen(false); }} @@ -92,6 +112,9 @@ const useStyles = makeStyles((theme) => ({ "--rgb-background": theme.palette.background.paper, "--rgb-input": colors.gray[17], "--rgb-color": colors.gray[4], + + // Hack to prevent the right side from being cut off + width: 350, }, }, adornment: { @@ -103,6 +126,7 @@ const useStyles = makeStyles((theme) => ({ "& img": { maxWidth: "100%", + objectFit: "contain", }, }, })); diff --git a/site/src/components/IconField/LazyIconField.tsx b/site/src/components/IconField/LazyIconField.tsx index 35ca799f5b..be6b444f74 100644 --- a/site/src/components/IconField/LazyIconField.tsx +++ b/site/src/components/IconField/LazyIconField.tsx @@ -1,4 +1,4 @@ -import { lazy, Suspense, ComponentProps } from "react"; +import { lazy, Suspense, type ComponentProps } from "react"; const IconField = lazy(() => import("./IconField")); diff --git a/site/static/icon/android-studio.svg b/site/static/icon/android-studio.svg index 965cf72bc1..6681425b60 100644 --- a/site/static/icon/android-studio.svg +++ b/site/static/icon/android-studio.svg @@ -1 +1 @@ -android-studio \ No newline at end of file +android-studio diff --git a/site/static/icon/azure-devops.svg b/site/static/icon/azure-devops.svg index 478ff78c72..2a8c0366f8 100644 --- a/site/static/icon/azure-devops.svg +++ b/site/static/icon/azure-devops.svg @@ -1,4 +1,4 @@ - + + icon_CLion \ No newline at end of file +icon_CLion diff --git a/site/static/icon/code.svg b/site/static/icon/code.svg index c6ee366939..5ef5c3ec51 100644 --- a/site/static/icon/code.svg +++ b/site/static/icon/code.svg @@ -1,4 +1,4 @@ - + diff --git a/site/static/icon/conda.svg b/site/static/icon/conda.svg index cbc4286cec..dc442e1a99 100644 --- a/site/static/icon/conda.svg +++ b/site/static/icon/conda.svg @@ -1,6 +1,7 @@ @@ -37,4 +38,4 @@ c-1.146-0.437-2.237-0.972-3.252-1.553c-0.775,1.586-1.341,3.103-1.722,4.276c1.202,0.291,2.823,0.608,4.613,0.779 C11.214,33.341,11.324,32.161,11.541,30.983z"/> - \ No newline at end of file + diff --git a/site/static/icon/datagrip.svg b/site/static/icon/datagrip.svg index 2638fea784..83913d6e94 100644 --- a/site/static/icon/datagrip.svg +++ b/site/static/icon/datagrip.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/site/static/icon/dataspell.svg b/site/static/icon/dataspell.svg index 20fee0268c..f409148e92 100644 --- a/site/static/icon/dataspell.svg +++ b/site/static/icon/dataspell.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/site/static/icon/dotfiles.svg b/site/static/icon/dotfiles.svg index c57ef8596f..d7c5623cbe 100644 --- a/site/static/icon/dotfiles.svg +++ b/site/static/icon/dotfiles.svg @@ -1,4 +1,5 @@ \ No newline at end of file + diff --git a/site/static/icon/gitlab.svg b/site/static/icon/gitlab.svg index 20c615b3c0..657533853f 100644 --- a/site/static/icon/gitlab.svg +++ b/site/static/icon/gitlab.svg @@ -1,4 +1,4 @@ - + \ No newline at end of file + diff --git a/site/static/icon/intellij.svg b/site/static/icon/intellij.svg index 0b3efa53ee..016e1cdc49 100644 --- a/site/static/icon/intellij.svg +++ b/site/static/icon/intellij.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/site/static/icon/jax.svg b/site/static/icon/jax.svg index 707be21621..8c1b31b608 100644 --- a/site/static/icon/jax.svg +++ b/site/static/icon/jax.svg @@ -1 +1 @@ -JAX Light Stroke \ No newline at end of file +JAX Light Stroke diff --git a/site/static/icon/jupyter.svg b/site/static/icon/jupyter.svg index 6b25a34fe5..356361efc0 100644 --- a/site/static/icon/jupyter.svg +++ b/site/static/icon/jupyter.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/site/static/icon/kasmvnc.svg b/site/static/icon/kasmvnc.svg index 958f28326a..9ba3dc358f 100644 --- a/site/static/icon/kasmvnc.svg +++ b/site/static/icon/kasmvnc.svg @@ -1,7 +1,7 @@ - + - \ No newline at end of file + diff --git a/site/static/icon/personalize.svg b/site/static/icon/personalize.svg index 76bc67807c..e9fbf7228d 100644 --- a/site/static/icon/personalize.svg +++ b/site/static/icon/personalize.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/site/static/icon/phpstorm.svg b/site/static/icon/phpstorm.svg index 4c83b09240..4230fec6fa 100644 --- a/site/static/icon/phpstorm.svg +++ b/site/static/icon/phpstorm.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/site/static/icon/pycharm.svg b/site/static/icon/pycharm.svg index 88a3e3a3c2..39fd560993 100644 --- a/site/static/icon/pycharm.svg +++ b/site/static/icon/pycharm.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/site/static/icon/pytorch.svg b/site/static/icon/pytorch.svg index 575f6823e4..fbffcfecde 100644 --- a/site/static/icon/pytorch.svg +++ b/site/static/icon/pytorch.svg @@ -2,6 +2,7 @@ rider \ No newline at end of file +rider diff --git a/site/static/icon/rubymine.svg b/site/static/icon/rubymine.svg index 4f1cbac3df..b60f0be776 100644 --- a/site/static/icon/rubymine.svg +++ b/site/static/icon/rubymine.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/site/static/icon/theia.svg b/site/static/icon/theia.svg index 99320b7ea8..b0934fa4c8 100644 --- a/site/static/icon/theia.svg +++ b/site/static/icon/theia.svg @@ -1 +1,37 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + diff --git a/site/static/icon/ubuntu.svg b/site/static/icon/ubuntu.svg index f217bc8d5d..25b5db244d 100644 --- a/site/static/icon/ubuntu.svg +++ b/site/static/icon/ubuntu.svg @@ -1,8 +1,8 @@ - + - \ No newline at end of file + diff --git a/site/static/icon/webstorm.svg b/site/static/icon/webstorm.svg index 58da539353..bda53e1b37 100644 --- a/site/static/icon/webstorm.svg +++ b/site/static/icon/webstorm.svg @@ -1 +1 @@ - \ No newline at end of file +