forked from CorentinTh/it-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(new tool): emoji picker (CorentinTh#551)
- Loading branch information
1 parent
dfa1ba8
commit 93f7cf0
Showing
11 changed files
with
192 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,14 @@ | ||
import { type MaybeRef, get, useClipboard } from '@vueuse/core'; | ||
import { useMessage } from 'naive-ui'; | ||
|
||
export function useCopy({ source, text = 'Copied to the clipboard' }: { source: MaybeRef<unknown>; text?: string }) { | ||
const { copy } = useClipboard({ source: computed(() => String(get(source))) }); | ||
export function useCopy({ source, text = 'Copied to the clipboard' }: { source?: MaybeRef<unknown>; text?: string } = {}) { | ||
const { copy } = useClipboard(source ? { source: computed(() => String(get(source))) } : {}); | ||
const message = useMessage(); | ||
|
||
return { | ||
async copy() { | ||
async copy(content?: string, { notificationMessage }: { notificationMessage?: string } = {}) { | ||
await copy(); | ||
message.success(text); | ||
message.success(notificationMessage ?? text); | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<script setup lang="ts"> | ||
import type { EmojiInfo } from './emoji.types'; | ||
import { useCopy } from '@/composable/copy'; | ||
const props = (defineProps<{ emojiInfo: EmojiInfo }>()); | ||
const { emojiInfo } = toRefs(props); | ||
const { copy } = useCopy(); | ||
</script> | ||
|
||
<template> | ||
<c-card flex items-center gap-3 important:py-8px important:pl-10px important:pr-5px> | ||
<div cursor-pointer text-30px @click="copy(emojiInfo.emoji, { notificationMessage: `Emoji ${emojiInfo.emoji} copied to the clipboard` })"> | ||
{{ emojiInfo.emoji }} | ||
</div> | ||
|
||
<div min-w-0 flex-1> | ||
<div truncate font-bold> | ||
{{ emojiInfo.title }} | ||
</div> | ||
|
||
<!-- <div> | ||
<c-link> | ||
{{ emojiInfo.codePoints }} | ||
</c-link> | ||
</div> | ||
<div /> | ||
<div rounded op-70> | ||
Unicode: <span border="1px solid current op-30" b-rd-xl px-12px py-4px>{{ emojiInfo.unicode }}</span> | ||
</div> --> | ||
|
||
<div flex gap-2 font-mono text-xs op-70> | ||
<span cursor-pointer transition hover:text-primary @click="copy(emojiInfo.codePoints, { notificationMessage: `Code points '${emojiInfo.codePoints}' copied to the clipboard` })"> | ||
{{ emojiInfo.codePoints }} | ||
</span> | ||
<span cursor-pointer truncate transition hover:text-primary @click="copy(emojiInfo.unicode, { notificationMessage: `Unicode '${emojiInfo.unicode}' copied to the clipboard` })"> | ||
{{ emojiInfo.unicode }} | ||
</span> | ||
</div> | ||
</div> | ||
</c-card> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<script setup lang="ts"> | ||
import type { EmojiInfo } from './emoji.types'; | ||
const props = withDefaults(defineProps<{ emojiInfos?: EmojiInfo[] }>(), { emojiInfos: () => [] }); | ||
const { emojiInfos } = toRefs(props); | ||
</script> | ||
|
||
<template> | ||
<div grid grid-cols-1 gap-2 lg:grid-cols-4 md:grid-cols-3 sm:grid-cols-2 xl:grid-cols-6> | ||
<emoji-card v-for="emojiInfo in emojiInfos" :key="emojiInfo.name" :emoji-info="emojiInfo" flex items-center gap-3 /> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<script setup lang="ts"> | ||
import emojiUnicodeData from 'unicode-emoji-json'; | ||
import emojiKeywords from 'emojilib'; | ||
import _ from 'lodash'; | ||
import type { EmojiInfo } from './emoji.types'; | ||
import { useFuzzySearch } from '@/composable/fuzzySearch'; | ||
const escapeUnicode = ({ emoji }: { emoji: string }) => emoji.split('').map(unit => `\\u${unit.charCodeAt(0).toString(16).padStart(4, '0')}`).join(''); | ||
const getEmojiCodePoints = ({ emoji }: { emoji: string }) => emoji.codePointAt(0) ? `0x${emoji.codePointAt(0)?.toString(16)}` : undefined; | ||
const emojis = _.map(emojiUnicodeData, (emojiInfo, emoji) => ({ | ||
...emojiInfo, | ||
emoji, | ||
title: _.capitalize(emojiInfo.name), | ||
keywords: emojiKeywords[emoji as keyof typeof emojiKeywords], | ||
codePoints: getEmojiCodePoints({ emoji }), | ||
unicode: escapeUnicode({ emoji }), | ||
})); | ||
const emojisGroups: { emojiInfos: EmojiInfo[]; group: string }[] = _ | ||
.chain(emojis) | ||
.groupBy('group') | ||
.map((emojiInfos, group) => ({ group, emojiInfos })) | ||
.value(); | ||
const searchQuery = ref(''); | ||
const { searchResult } = useFuzzySearch({ | ||
search: searchQuery, | ||
data: emojis, | ||
options: { | ||
keys: ['group', { name: 'name', weight: 3 }, 'keywords', 'unicode', 'codePoints', 'emoji'], | ||
threshold: 0.3, | ||
useExtendedSearch: true, | ||
isCaseSensitive: false, | ||
}, | ||
}); | ||
</script> | ||
|
||
<template> | ||
<div mx-auto max-w-2400px important:flex-1> | ||
<div flex items-center gap-3> | ||
<c-input-text | ||
v-model:value="searchQuery" | ||
placeholder="Search emojis (e.g. 'smile')..." | ||
mx-auto max-w-600px | ||
> | ||
<template #prefix> | ||
<icon-mdi-search mr-6px color-black op-70 dark:color-white /> | ||
</template> | ||
</c-input-text> | ||
</div> | ||
|
||
<div v-if="searchQuery.trim().length > 0"> | ||
<div | ||
v-if="searchResult.length === 0" | ||
mt-4 | ||
text-20px | ||
font-bold | ||
> | ||
No results | ||
</div> | ||
|
||
<div v-else> | ||
<div mt-4 text-20px font-bold> | ||
Search result | ||
</div> | ||
|
||
<emoji-grid :emoji-infos="searchResult" /> | ||
</div> | ||
</div> | ||
|
||
<div | ||
v-for="{ group, emojiInfos } in emojisGroups" | ||
v-else | ||
:key="group" | ||
> | ||
<div mt-4 text-20px font-bold> | ||
{{ group }} | ||
</div> | ||
|
||
<emoji-grid :emoji-infos="emojiInfos" /> | ||
</div> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import type emojiUnicodeData from 'unicode-emoji-json'; | ||
|
||
export type EmojiInfo = { | ||
title: string | ||
emoji: string | ||
codePoints: string | undefined | ||
unicode: string | ||
} & typeof emojiUnicodeData['\uD83E\uDD10']; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { MoodSmile } from '@vicons/tabler'; | ||
import { defineTool } from '../tool'; | ||
|
||
export const tool = defineTool({ | ||
name: 'Emoji picker', | ||
path: '/emoji-picker', | ||
description: 'Copy and paste emojis easily and get the unicode and code points value of each emoji.', | ||
keywords: ['emoji', 'picker', 'unicode', 'copy', 'paste'], | ||
component: () => import('./emoji-picker.vue'), | ||
icon: MoodSmile, | ||
createdAt: new Date('2023-08-07'), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters