@oiij/emoji-picker 0.0.13 → 0.0.15
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/README.md +82 -4
- package/dist/index.d.mts +172 -7
- package/dist/index.mjs +55 -20
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,12 +1,90 @@
|
|
|
1
|
-
# Use EmojiPicker
|
|
1
|
+
# Use EmojiPicker 🚀
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@oiij/emoji-picker)
|
|
4
|
-
[](https://github.com/
|
|
4
|
+
[](https://github.com/oiij/use/blob/main/packages/emoji-picker/LICENSE)
|
|
5
5
|
|
|
6
|
-
##
|
|
6
|
+
## 项目简介 📦
|
|
7
|
+
|
|
8
|
+
Use EmojiPicker 是一个功能完善的表情选择器组件,为 Vue 3 应用提供丰富的表情符号选择功能,帮助用户快速选择和插入表情。
|
|
9
|
+
|
|
10
|
+
## 功能特点 ✨
|
|
11
|
+
|
|
12
|
+
### 表情丰富 😊
|
|
13
|
+
|
|
14
|
+
- 🎭 提供大量表情符号
|
|
15
|
+
- 🔍 支持搜索和分类
|
|
16
|
+
- 🎨 可自定义主题和样式
|
|
17
|
+
|
|
18
|
+
### 模块化设计 🧩
|
|
19
|
+
|
|
20
|
+
- 📁 采用模块化架构,组件独立封装
|
|
21
|
+
- 📦 支持按需导入,减小打包体积
|
|
22
|
+
- 🔧 清晰的文件结构,易于维护和扩展
|
|
23
|
+
|
|
24
|
+
### 类型安全 🔒
|
|
25
|
+
|
|
26
|
+
- 📝 完整的 TypeScript 类型定义
|
|
27
|
+
- 💡 提供准确的类型推断和代码提示
|
|
28
|
+
- 🎯 支持 Vue 3 的 Composition API 类型系统
|
|
29
|
+
|
|
30
|
+
### 轻量高效 ⚡
|
|
31
|
+
|
|
32
|
+
- 🚀 核心代码精简,无额外依赖
|
|
33
|
+
- 🏃 优化的性能表现,最小化运行时开销
|
|
34
|
+
- 📦 支持 Tree Shaking,进一步减小打包体积
|
|
35
|
+
|
|
36
|
+
## 安装 📥
|
|
37
|
+
|
|
38
|
+
### 使用 pnpm 🐱
|
|
7
39
|
|
|
8
40
|
```bash
|
|
9
41
|
pnpm add @oiij/emoji-picker
|
|
10
42
|
```
|
|
11
43
|
|
|
12
|
-
|
|
44
|
+
### 使用 npm 📦
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install @oiij/emoji-picker
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 使用 yarn 🧶
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
yarn add @oiij/emoji-picker
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 快速开始 🌟
|
|
57
|
+
|
|
58
|
+
### 基础使用
|
|
59
|
+
|
|
60
|
+
```vue
|
|
61
|
+
<script setup>
|
|
62
|
+
import { UseEmojiPicker } from '@oiij/emoji-picker'
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<template>
|
|
66
|
+
<UseEmojiPicker />
|
|
67
|
+
</template>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 在线文档 📚
|
|
71
|
+
|
|
72
|
+
[在线文档](https://oiij-use.vercel.app/emoji-picker/emoji-picker) 📖
|
|
73
|
+
|
|
74
|
+
## 贡献指南 🤝
|
|
75
|
+
|
|
76
|
+
欢迎贡献代码、报告问题或提出新功能建议!
|
|
77
|
+
|
|
78
|
+
1. Fork 本仓库 🍴
|
|
79
|
+
2. 创建您的特性分支 (`git checkout -b feature/amazing-feature`) 🌿
|
|
80
|
+
3. 提交您的更改 (`git commit -m 'Add some amazing feature'`) 💾
|
|
81
|
+
4. 推送到分支 (`git push origin feature/amazing-feature`) 🚀
|
|
82
|
+
5. 打开一个 Pull Request 📥
|
|
83
|
+
|
|
84
|
+
## 许可证 📄
|
|
85
|
+
|
|
86
|
+
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情 📑
|
|
87
|
+
|
|
88
|
+
## 联系方式 📞
|
|
89
|
+
|
|
90
|
+
- GitHub: [https://github.com/Eiog/@oiij/emoji-picker](https://github.com/Eiog/@oiij/emoji-picker) 🌟
|
package/dist/index.d.mts
CHANGED
|
@@ -1,65 +1,230 @@
|
|
|
1
1
|
import * as _vueuse_core0 from "@vueuse/core";
|
|
2
2
|
import { Picker } from "emoji-mart";
|
|
3
|
-
import * as
|
|
3
|
+
import * as vue from "vue";
|
|
4
4
|
import { MaybeRefOrGetter, TemplateRef } from "vue";
|
|
5
5
|
|
|
6
6
|
//#region src/index.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* 表情结果类型
|
|
9
|
+
*/
|
|
7
10
|
type EmojiResult = {
|
|
11
|
+
/**
|
|
12
|
+
* 表情 ID
|
|
13
|
+
*/
|
|
8
14
|
id: string;
|
|
15
|
+
/**
|
|
16
|
+
* 表情名称
|
|
17
|
+
*/
|
|
9
18
|
name: string;
|
|
19
|
+
/**
|
|
20
|
+
* 原生表情
|
|
21
|
+
*/
|
|
10
22
|
native: string;
|
|
23
|
+
/**
|
|
24
|
+
* 统一编码
|
|
25
|
+
*/
|
|
11
26
|
unified: string;
|
|
27
|
+
/**
|
|
28
|
+
* 关键词
|
|
29
|
+
*/
|
|
12
30
|
keywords: string[];
|
|
31
|
+
/**
|
|
32
|
+
* 短代码
|
|
33
|
+
*/
|
|
13
34
|
shortcodes: string;
|
|
14
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* 表情选择器选项类型
|
|
38
|
+
*/
|
|
15
39
|
type EmojiPickerOptions = {
|
|
40
|
+
/**
|
|
41
|
+
* 父元素
|
|
42
|
+
*/
|
|
16
43
|
parent?: HTMLElement;
|
|
44
|
+
/**
|
|
45
|
+
* 表情数据
|
|
46
|
+
*/
|
|
17
47
|
data?: object;
|
|
48
|
+
/**
|
|
49
|
+
* 国际化配置
|
|
50
|
+
*/
|
|
18
51
|
i18n?: object;
|
|
52
|
+
/**
|
|
53
|
+
* 分类
|
|
54
|
+
*/
|
|
19
55
|
categories?: ('frequent' | 'people' | 'nature' | 'food' | 'activity' | 'places' | 'objects' | 'symbols' | 'flags')[];
|
|
56
|
+
/**
|
|
57
|
+
* 自定义表情
|
|
58
|
+
*/
|
|
20
59
|
custom?: [];
|
|
60
|
+
/**
|
|
61
|
+
* 选择表情回调
|
|
62
|
+
*/
|
|
21
63
|
onEmojiSelect?: (emoji: EmojiResult) => void;
|
|
64
|
+
/**
|
|
65
|
+
* 点击外部回调
|
|
66
|
+
*/
|
|
22
67
|
onClickOutside?: () => void;
|
|
68
|
+
/**
|
|
69
|
+
* 添加自定义表情回调
|
|
70
|
+
*/
|
|
23
71
|
onAddCustomEmoji?: (emoji: EmojiResult) => void;
|
|
72
|
+
/**
|
|
73
|
+
* 是否自动聚焦
|
|
74
|
+
*/
|
|
24
75
|
autoFocus?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* 分类图标
|
|
78
|
+
*/
|
|
25
79
|
categoryIcons?: object;
|
|
80
|
+
/**
|
|
81
|
+
* 动态宽度
|
|
82
|
+
*/
|
|
26
83
|
dynamicWidth?: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* 表情按钮颜色
|
|
86
|
+
*/
|
|
27
87
|
emojiButtonColors?: string[];
|
|
88
|
+
/**
|
|
89
|
+
* 表情按钮圆角
|
|
90
|
+
*/
|
|
28
91
|
emojiButtonRadius?: string;
|
|
92
|
+
/**
|
|
93
|
+
* 表情按钮大小
|
|
94
|
+
*/
|
|
29
95
|
emojiButtonSize?: number;
|
|
96
|
+
/**
|
|
97
|
+
* 表情大小
|
|
98
|
+
*/
|
|
30
99
|
emojiSize?: number;
|
|
100
|
+
/**
|
|
101
|
+
* 表情版本
|
|
102
|
+
*/
|
|
31
103
|
emojiVersion?: 1 | 2 | 3 | 4 | 5 | 11 | 12 | 12.1 | 13 | 13.1 | 14 | 15;
|
|
104
|
+
/**
|
|
105
|
+
* 排除表情
|
|
106
|
+
*/
|
|
32
107
|
exceptEmojis?: [];
|
|
108
|
+
/**
|
|
109
|
+
* 图标样式
|
|
110
|
+
*/
|
|
33
111
|
icons?: 'aut' | 'outline' | 'solid';
|
|
112
|
+
/**
|
|
113
|
+
* 语言
|
|
114
|
+
*/
|
|
34
115
|
locale?: 'en' | 'ar' | 'be' | 'cs' | 'de' | 'es' | 'fa' | 'fi' | 'fr' | 'hi' | 'it' | 'ja' | 'ko' | 'nl' | 'pl' | 'pt' | 'ru' | 'sa' | 'tr' | 'uk' | 'vi' | 'zh';
|
|
116
|
+
/**
|
|
117
|
+
* 最大常用行数
|
|
118
|
+
*/
|
|
35
119
|
maxFrequentRows?: number;
|
|
120
|
+
/**
|
|
121
|
+
* 导航位置
|
|
122
|
+
*/
|
|
36
123
|
navPosition?: 'top' | 'bottom' | 'none';
|
|
124
|
+
/**
|
|
125
|
+
* 无国家旗帜
|
|
126
|
+
*/
|
|
37
127
|
noCountryFlags?: boolean;
|
|
128
|
+
/**
|
|
129
|
+
* 无结果表情
|
|
130
|
+
*/
|
|
38
131
|
noResultsEmoji?: string;
|
|
132
|
+
/**
|
|
133
|
+
* 每行数量
|
|
134
|
+
*/
|
|
39
135
|
perLine?: number;
|
|
136
|
+
/**
|
|
137
|
+
* 预览表情
|
|
138
|
+
*/
|
|
40
139
|
previewEmoji?: 'point_up' | 'point_down';
|
|
140
|
+
/**
|
|
141
|
+
* 预览位置
|
|
142
|
+
*/
|
|
41
143
|
previewPosition?: 'top' | 'bottom' | 'none';
|
|
144
|
+
/**
|
|
145
|
+
* 搜索位置
|
|
146
|
+
*/
|
|
42
147
|
searchPosition?: 'sticky' | 'static' | 'none';
|
|
148
|
+
/**
|
|
149
|
+
* 表情集
|
|
150
|
+
*/
|
|
43
151
|
set?: 'native' | 'apple' | 'facebook' | 'google' | 'twitter';
|
|
152
|
+
/**
|
|
153
|
+
* 肤色
|
|
154
|
+
*/
|
|
44
155
|
skin?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
156
|
+
/**
|
|
157
|
+
* 肤色位置
|
|
158
|
+
*/
|
|
45
159
|
skinTonePosition?: 'preview' | 'search' | 'none';
|
|
160
|
+
/**
|
|
161
|
+
* 主题
|
|
162
|
+
*/
|
|
46
163
|
theme?: 'auto' | 'light' | 'dark';
|
|
164
|
+
/**
|
|
165
|
+
* 获取精灵图 URL
|
|
166
|
+
*/
|
|
47
167
|
getSpritesheetURL?: string;
|
|
48
168
|
};
|
|
169
|
+
/**
|
|
170
|
+
* 使用表情选择器选项类型
|
|
171
|
+
*/
|
|
49
172
|
type UseEmojiPickerOptions = {
|
|
173
|
+
/**
|
|
174
|
+
* 是否开启暗黑模式
|
|
175
|
+
*/
|
|
50
176
|
darkMode?: MaybeRefOrGetter<boolean>;
|
|
177
|
+
/**
|
|
178
|
+
* 语言
|
|
179
|
+
*/
|
|
51
180
|
language?: MaybeRefOrGetter<'zh' | 'en'>;
|
|
181
|
+
/**
|
|
182
|
+
* 表情选择器选项
|
|
183
|
+
*/
|
|
52
184
|
emojiPickerOptions?: EmojiPickerOptions;
|
|
53
185
|
};
|
|
186
|
+
/**
|
|
187
|
+
* 使用表情选择器
|
|
188
|
+
*
|
|
189
|
+
* @param templateRef - 表情选择器容器的模板引用
|
|
190
|
+
* @param options - 表情选择器选项
|
|
191
|
+
* @returns 表情选择器实例和工具方法
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```vue
|
|
195
|
+
* <script setup>
|
|
196
|
+
* import { ref } from 'vue'
|
|
197
|
+
* import { useEmojiPicker } from '@oiij/emoji-picker'
|
|
198
|
+
*
|
|
199
|
+
* const pickerRef = ref()
|
|
200
|
+
* const { emojiPickerInst, setDarkMode } = useEmojiPicker(pickerRef, {
|
|
201
|
+
* darkMode: false,
|
|
202
|
+
* language: 'zh',
|
|
203
|
+
* emojiPickerOptions: {
|
|
204
|
+
* onEmojiSelect: (emoji) => {
|
|
205
|
+
* console.log('选择了表情', emoji)
|
|
206
|
+
* }
|
|
207
|
+
* }
|
|
208
|
+
* })
|
|
209
|
+
* </script>
|
|
210
|
+
*
|
|
211
|
+
* <template>
|
|
212
|
+
* <div ref="pickerRef"></div>
|
|
213
|
+
* </template>
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
54
216
|
declare function useEmojiPicker(templateRef: TemplateRef<HTMLElement>, options?: UseEmojiPickerOptions): {
|
|
55
|
-
templateRef: Readonly<
|
|
56
|
-
darkMode:
|
|
57
|
-
language:
|
|
58
|
-
emojiPickerInst:
|
|
59
|
-
|
|
60
|
-
|
|
217
|
+
templateRef: Readonly<vue.ShallowRef<HTMLElement | null>>;
|
|
218
|
+
darkMode: vue.Ref<boolean | undefined, boolean | undefined>;
|
|
219
|
+
language: vue.Ref<"zh" | "en" | undefined, "zh" | "en" | undefined>;
|
|
220
|
+
emojiPickerInst: vue.ShallowRef<Picker | null, Picker | null>;
|
|
221
|
+
setDarkMode: (darkMode?: boolean) => void;
|
|
222
|
+
setLanguage: (language?: "zh" | "en") => void;
|
|
61
223
|
onRender: _vueuse_core0.EventHookOn<[Picker]>;
|
|
62
224
|
};
|
|
225
|
+
/**
|
|
226
|
+
* 使用表情选择器返回值类型
|
|
227
|
+
*/
|
|
63
228
|
type UseEmojiPickerReturns = ReturnType<typeof useEmojiPicker>;
|
|
64
229
|
//#endregion
|
|
65
230
|
export { EmojiPickerOptions, EmojiResult, UseEmojiPickerOptions, UseEmojiPickerReturns, useEmojiPicker };
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,6 @@ import data from "@emoji-mart/data";
|
|
|
2
2
|
import { createEventHook, watchOnce } from "@vueuse/core";
|
|
3
3
|
import { Picker } from "emoji-mart";
|
|
4
4
|
import { onUnmounted, ref, shallowRef, toValue, watch, watchEffect } from "vue";
|
|
5
|
-
|
|
6
5
|
//#region ../_utils/custom-watch.ts
|
|
7
6
|
function watchRefOrGetter(value, callback) {
|
|
8
7
|
const refValue = ref(toValue(value));
|
|
@@ -14,13 +13,42 @@ function watchRefOrGetter(value, callback) {
|
|
|
14
13
|
});
|
|
15
14
|
return refValue;
|
|
16
15
|
}
|
|
17
|
-
|
|
18
16
|
//#endregion
|
|
19
17
|
//#region src/index.ts
|
|
18
|
+
/**
|
|
19
|
+
* 使用表情选择器
|
|
20
|
+
*
|
|
21
|
+
* @param templateRef - 表情选择器容器的模板引用
|
|
22
|
+
* @param options - 表情选择器选项
|
|
23
|
+
* @returns 表情选择器实例和工具方法
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```vue
|
|
27
|
+
* <script setup>
|
|
28
|
+
* import { ref } from 'vue'
|
|
29
|
+
* import { useEmojiPicker } from '@oiij/emoji-picker'
|
|
30
|
+
*
|
|
31
|
+
* const pickerRef = ref()
|
|
32
|
+
* const { emojiPickerInst, setDarkMode } = useEmojiPicker(pickerRef, {
|
|
33
|
+
* darkMode: false,
|
|
34
|
+
* language: 'zh',
|
|
35
|
+
* emojiPickerOptions: {
|
|
36
|
+
* onEmojiSelect: (emoji) => {
|
|
37
|
+
* console.log('选择了表情', emoji)
|
|
38
|
+
* }
|
|
39
|
+
* }
|
|
40
|
+
* })
|
|
41
|
+
* <\/script>
|
|
42
|
+
*
|
|
43
|
+
* <template>
|
|
44
|
+
* <div ref="pickerRef"></div>
|
|
45
|
+
* </template>
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
20
48
|
function useEmojiPicker(templateRef, options) {
|
|
21
49
|
const { darkMode, language, emojiPickerOptions } = options ?? {};
|
|
22
|
-
const darkModeRef = watchRefOrGetter(darkMode,
|
|
23
|
-
const languageRef = watchRefOrGetter(language,
|
|
50
|
+
const darkModeRef = watchRefOrGetter(darkMode, () => setDarkMode());
|
|
51
|
+
const languageRef = watchRefOrGetter(language, () => setLanguage());
|
|
24
52
|
const _options = {
|
|
25
53
|
data,
|
|
26
54
|
emojiButtonRadius: "6px",
|
|
@@ -38,27 +66,35 @@ function useEmojiPicker(templateRef, options) {
|
|
|
38
66
|
};
|
|
39
67
|
const emojiPickerInst = shallowRef(null);
|
|
40
68
|
const onRenderEvent = createEventHook();
|
|
41
|
-
|
|
42
|
-
|
|
69
|
+
/**
|
|
70
|
+
* 更新主题
|
|
71
|
+
*
|
|
72
|
+
* @param darkMode - 是否开启暗黑模式
|
|
73
|
+
*/
|
|
74
|
+
function setDarkMode(darkMode) {
|
|
75
|
+
if (darkMode !== void 0) darkModeRef.value = darkMode;
|
|
43
76
|
_options.theme = darkModeRef.value ? "dark" : "light";
|
|
44
77
|
destroy();
|
|
45
78
|
render();
|
|
46
79
|
}
|
|
47
|
-
|
|
48
|
-
|
|
80
|
+
/**
|
|
81
|
+
* 更新语言
|
|
82
|
+
*
|
|
83
|
+
* @param language - 语言
|
|
84
|
+
*/
|
|
85
|
+
function setLanguage(language) {
|
|
86
|
+
if (language !== void 0) languageRef.value = language;
|
|
49
87
|
_options.locale = languageRef.value ?? "zh";
|
|
50
88
|
destroy();
|
|
51
89
|
render();
|
|
52
90
|
}
|
|
53
91
|
function render() {
|
|
54
|
-
if (templateRef.value) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
onRenderEvent.trigger(emojiPickerInst.value);
|
|
61
|
-
}
|
|
92
|
+
if (templateRef.value && !emojiPickerInst.value) {
|
|
93
|
+
emojiPickerInst.value = new Picker({
|
|
94
|
+
parent: templateRef.value,
|
|
95
|
+
..._options
|
|
96
|
+
});
|
|
97
|
+
onRenderEvent.trigger(emojiPickerInst.value);
|
|
62
98
|
}
|
|
63
99
|
}
|
|
64
100
|
function destroy() {
|
|
@@ -74,11 +110,10 @@ function useEmojiPicker(templateRef, options) {
|
|
|
74
110
|
darkMode: darkModeRef,
|
|
75
111
|
language: languageRef,
|
|
76
112
|
emojiPickerInst,
|
|
77
|
-
|
|
78
|
-
|
|
113
|
+
setDarkMode,
|
|
114
|
+
setLanguage,
|
|
79
115
|
onRender: onRenderEvent.on
|
|
80
116
|
};
|
|
81
117
|
}
|
|
82
|
-
|
|
83
118
|
//#endregion
|
|
84
|
-
export { useEmojiPicker };
|
|
119
|
+
export { useEmojiPicker };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oiij/emoji-picker",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.15",
|
|
5
5
|
"description": "A Vue Composable for emoji-picker",
|
|
6
6
|
"author": "oiij",
|
|
7
7
|
"license": "MIT",
|
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
],
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@emoji-mart/data": "^1.2.1",
|
|
29
|
-
"@vueuse/core": "^14.1
|
|
29
|
+
"@vueuse/core": "^14.2.1",
|
|
30
30
|
"emoji-mart": "^5.6.0",
|
|
31
|
-
"vue": "^3.5.
|
|
31
|
+
"vue": "^3.5.30"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@emoji-mart/data": "^1.2.1",
|
|
35
|
-
"@vueuse/core": "^14.1
|
|
35
|
+
"@vueuse/core": "^14.2.1",
|
|
36
36
|
"emoji-mart": "^5.6.0",
|
|
37
|
-
"vue": "^3.5.
|
|
37
|
+
"vue": "^3.5.30"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|