@ckeditor/ckeditor5-emoji 0.0.1 → 44.2.0-alpha.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 (402) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/LICENSE.md +15 -5
  3. package/README.md +30 -3
  4. package/build/emoji.js +5 -0
  5. package/build/translations/af.js +1 -0
  6. package/build/translations/ar.js +1 -0
  7. package/build/translations/ast.js +1 -0
  8. package/build/translations/az.js +1 -0
  9. package/build/translations/bg.js +1 -0
  10. package/build/translations/bn.js +1 -0
  11. package/build/translations/bs.js +1 -0
  12. package/build/translations/ca.js +1 -0
  13. package/build/translations/cs.js +1 -0
  14. package/build/translations/da.js +1 -0
  15. package/build/translations/de-ch.js +1 -0
  16. package/build/translations/de.js +1 -0
  17. package/build/translations/el.js +1 -0
  18. package/build/translations/en-au.js +1 -0
  19. package/build/translations/en-gb.js +1 -0
  20. package/build/translations/eo.js +1 -0
  21. package/build/translations/es-co.js +1 -0
  22. package/build/translations/es.js +1 -0
  23. package/build/translations/et.js +1 -0
  24. package/build/translations/eu.js +1 -0
  25. package/build/translations/fa.js +1 -0
  26. package/build/translations/fi.js +1 -0
  27. package/build/translations/fr.js +1 -0
  28. package/build/translations/gl.js +1 -0
  29. package/build/translations/gu.js +1 -0
  30. package/build/translations/he.js +1 -0
  31. package/build/translations/hi.js +1 -0
  32. package/build/translations/hr.js +1 -0
  33. package/build/translations/hu.js +1 -0
  34. package/build/translations/hy.js +1 -0
  35. package/build/translations/id.js +1 -0
  36. package/build/translations/it.js +1 -0
  37. package/build/translations/ja.js +1 -0
  38. package/build/translations/jv.js +1 -0
  39. package/build/translations/kk.js +1 -0
  40. package/build/translations/km.js +1 -0
  41. package/build/translations/kn.js +1 -0
  42. package/build/translations/ko.js +1 -0
  43. package/build/translations/ku.js +1 -0
  44. package/build/translations/lt.js +1 -0
  45. package/build/translations/lv.js +1 -0
  46. package/build/translations/ms.js +1 -0
  47. package/build/translations/nb.js +1 -0
  48. package/build/translations/ne.js +1 -0
  49. package/build/translations/nl.js +1 -0
  50. package/build/translations/no.js +1 -0
  51. package/build/translations/oc.js +1 -0
  52. package/build/translations/pl.js +1 -0
  53. package/build/translations/pt-br.js +1 -0
  54. package/build/translations/pt.js +1 -0
  55. package/build/translations/ro.js +1 -0
  56. package/build/translations/ru.js +1 -0
  57. package/build/translations/si.js +1 -0
  58. package/build/translations/sk.js +1 -0
  59. package/build/translations/sl.js +1 -0
  60. package/build/translations/sq.js +1 -0
  61. package/build/translations/sr-latn.js +1 -0
  62. package/build/translations/sr.js +1 -0
  63. package/build/translations/sv.js +1 -0
  64. package/build/translations/th.js +1 -0
  65. package/build/translations/ti.js +1 -0
  66. package/build/translations/tk.js +1 -0
  67. package/build/translations/tr.js +1 -0
  68. package/build/translations/tt.js +1 -0
  69. package/build/translations/ug.js +1 -0
  70. package/build/translations/uk.js +1 -0
  71. package/build/translations/ur.js +1 -0
  72. package/build/translations/uz.js +1 -0
  73. package/build/translations/vi.js +1 -0
  74. package/build/translations/zh-cn.js +1 -0
  75. package/build/translations/zh.js +1 -0
  76. package/ckeditor5-metadata.json +32 -0
  77. package/dist/index-content.css +4 -0
  78. package/dist/index-editor.css +111 -0
  79. package/dist/index.css +143 -0
  80. package/dist/index.css.map +1 -0
  81. package/dist/index.js +1477 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/translations/af.d.ts +8 -0
  84. package/dist/translations/af.js +5 -0
  85. package/dist/translations/af.umd.js +11 -0
  86. package/dist/translations/ar.d.ts +8 -0
  87. package/dist/translations/ar.js +5 -0
  88. package/dist/translations/ar.umd.js +11 -0
  89. package/dist/translations/ast.d.ts +8 -0
  90. package/dist/translations/ast.js +5 -0
  91. package/dist/translations/ast.umd.js +11 -0
  92. package/dist/translations/az.d.ts +8 -0
  93. package/dist/translations/az.js +5 -0
  94. package/dist/translations/az.umd.js +11 -0
  95. package/dist/translations/bg.d.ts +8 -0
  96. package/dist/translations/bg.js +5 -0
  97. package/dist/translations/bg.umd.js +11 -0
  98. package/dist/translations/bn.d.ts +8 -0
  99. package/dist/translations/bn.js +5 -0
  100. package/dist/translations/bn.umd.js +11 -0
  101. package/dist/translations/bs.d.ts +8 -0
  102. package/dist/translations/bs.js +5 -0
  103. package/dist/translations/bs.umd.js +11 -0
  104. package/dist/translations/ca.d.ts +8 -0
  105. package/dist/translations/ca.js +5 -0
  106. package/dist/translations/ca.umd.js +11 -0
  107. package/dist/translations/cs.d.ts +8 -0
  108. package/dist/translations/cs.js +5 -0
  109. package/dist/translations/cs.umd.js +11 -0
  110. package/dist/translations/da.d.ts +8 -0
  111. package/dist/translations/da.js +5 -0
  112. package/dist/translations/da.umd.js +11 -0
  113. package/dist/translations/de-ch.d.ts +8 -0
  114. package/dist/translations/de-ch.js +5 -0
  115. package/dist/translations/de-ch.umd.js +11 -0
  116. package/dist/translations/de.d.ts +8 -0
  117. package/dist/translations/de.js +5 -0
  118. package/dist/translations/de.umd.js +11 -0
  119. package/dist/translations/el.d.ts +8 -0
  120. package/dist/translations/el.js +5 -0
  121. package/dist/translations/el.umd.js +11 -0
  122. package/dist/translations/en-au.d.ts +8 -0
  123. package/dist/translations/en-au.js +5 -0
  124. package/dist/translations/en-au.umd.js +11 -0
  125. package/dist/translations/en-gb.d.ts +8 -0
  126. package/dist/translations/en-gb.js +5 -0
  127. package/dist/translations/en-gb.umd.js +11 -0
  128. package/dist/translations/en.d.ts +8 -0
  129. package/dist/translations/en.js +5 -0
  130. package/dist/translations/en.umd.js +11 -0
  131. package/dist/translations/eo.d.ts +8 -0
  132. package/dist/translations/eo.js +5 -0
  133. package/dist/translations/eo.umd.js +11 -0
  134. package/dist/translations/es-co.d.ts +8 -0
  135. package/dist/translations/es-co.js +5 -0
  136. package/dist/translations/es-co.umd.js +11 -0
  137. package/dist/translations/es.d.ts +8 -0
  138. package/dist/translations/es.js +5 -0
  139. package/dist/translations/es.umd.js +11 -0
  140. package/dist/translations/et.d.ts +8 -0
  141. package/dist/translations/et.js +5 -0
  142. package/dist/translations/et.umd.js +11 -0
  143. package/dist/translations/eu.d.ts +8 -0
  144. package/dist/translations/eu.js +5 -0
  145. package/dist/translations/eu.umd.js +11 -0
  146. package/dist/translations/fa.d.ts +8 -0
  147. package/dist/translations/fa.js +5 -0
  148. package/dist/translations/fa.umd.js +11 -0
  149. package/dist/translations/fi.d.ts +8 -0
  150. package/dist/translations/fi.js +5 -0
  151. package/dist/translations/fi.umd.js +11 -0
  152. package/dist/translations/fr.d.ts +8 -0
  153. package/dist/translations/fr.js +5 -0
  154. package/dist/translations/fr.umd.js +11 -0
  155. package/dist/translations/gl.d.ts +8 -0
  156. package/dist/translations/gl.js +5 -0
  157. package/dist/translations/gl.umd.js +11 -0
  158. package/dist/translations/gu.d.ts +8 -0
  159. package/dist/translations/gu.js +5 -0
  160. package/dist/translations/gu.umd.js +11 -0
  161. package/dist/translations/he.d.ts +8 -0
  162. package/dist/translations/he.js +5 -0
  163. package/dist/translations/he.umd.js +11 -0
  164. package/dist/translations/hi.d.ts +8 -0
  165. package/dist/translations/hi.js +5 -0
  166. package/dist/translations/hi.umd.js +11 -0
  167. package/dist/translations/hr.d.ts +8 -0
  168. package/dist/translations/hr.js +5 -0
  169. package/dist/translations/hr.umd.js +11 -0
  170. package/dist/translations/hu.d.ts +8 -0
  171. package/dist/translations/hu.js +5 -0
  172. package/dist/translations/hu.umd.js +11 -0
  173. package/dist/translations/hy.d.ts +8 -0
  174. package/dist/translations/hy.js +5 -0
  175. package/dist/translations/hy.umd.js +11 -0
  176. package/dist/translations/id.d.ts +8 -0
  177. package/dist/translations/id.js +5 -0
  178. package/dist/translations/id.umd.js +11 -0
  179. package/dist/translations/it.d.ts +8 -0
  180. package/dist/translations/it.js +5 -0
  181. package/dist/translations/it.umd.js +11 -0
  182. package/dist/translations/ja.d.ts +8 -0
  183. package/dist/translations/ja.js +5 -0
  184. package/dist/translations/ja.umd.js +11 -0
  185. package/dist/translations/jv.d.ts +8 -0
  186. package/dist/translations/jv.js +5 -0
  187. package/dist/translations/jv.umd.js +11 -0
  188. package/dist/translations/kk.d.ts +8 -0
  189. package/dist/translations/kk.js +5 -0
  190. package/dist/translations/kk.umd.js +11 -0
  191. package/dist/translations/km.d.ts +8 -0
  192. package/dist/translations/km.js +5 -0
  193. package/dist/translations/km.umd.js +11 -0
  194. package/dist/translations/kn.d.ts +8 -0
  195. package/dist/translations/kn.js +5 -0
  196. package/dist/translations/kn.umd.js +11 -0
  197. package/dist/translations/ko.d.ts +8 -0
  198. package/dist/translations/ko.js +5 -0
  199. package/dist/translations/ko.umd.js +11 -0
  200. package/dist/translations/ku.d.ts +8 -0
  201. package/dist/translations/ku.js +5 -0
  202. package/dist/translations/ku.umd.js +11 -0
  203. package/dist/translations/lt.d.ts +8 -0
  204. package/dist/translations/lt.js +5 -0
  205. package/dist/translations/lt.umd.js +11 -0
  206. package/dist/translations/lv.d.ts +8 -0
  207. package/dist/translations/lv.js +5 -0
  208. package/dist/translations/lv.umd.js +11 -0
  209. package/dist/translations/ms.d.ts +8 -0
  210. package/dist/translations/ms.js +5 -0
  211. package/dist/translations/ms.umd.js +11 -0
  212. package/dist/translations/nb.d.ts +8 -0
  213. package/dist/translations/nb.js +5 -0
  214. package/dist/translations/nb.umd.js +11 -0
  215. package/dist/translations/ne.d.ts +8 -0
  216. package/dist/translations/ne.js +5 -0
  217. package/dist/translations/ne.umd.js +11 -0
  218. package/dist/translations/nl.d.ts +8 -0
  219. package/dist/translations/nl.js +5 -0
  220. package/dist/translations/nl.umd.js +11 -0
  221. package/dist/translations/no.d.ts +8 -0
  222. package/dist/translations/no.js +5 -0
  223. package/dist/translations/no.umd.js +11 -0
  224. package/dist/translations/oc.d.ts +8 -0
  225. package/dist/translations/oc.js +5 -0
  226. package/dist/translations/oc.umd.js +11 -0
  227. package/dist/translations/pl.d.ts +8 -0
  228. package/dist/translations/pl.js +5 -0
  229. package/dist/translations/pl.umd.js +11 -0
  230. package/dist/translations/pt-br.d.ts +8 -0
  231. package/dist/translations/pt-br.js +5 -0
  232. package/dist/translations/pt-br.umd.js +11 -0
  233. package/dist/translations/pt.d.ts +8 -0
  234. package/dist/translations/pt.js +5 -0
  235. package/dist/translations/pt.umd.js +11 -0
  236. package/dist/translations/ro.d.ts +8 -0
  237. package/dist/translations/ro.js +5 -0
  238. package/dist/translations/ro.umd.js +11 -0
  239. package/dist/translations/ru.d.ts +8 -0
  240. package/dist/translations/ru.js +5 -0
  241. package/dist/translations/ru.umd.js +11 -0
  242. package/dist/translations/si.d.ts +8 -0
  243. package/dist/translations/si.js +5 -0
  244. package/dist/translations/si.umd.js +11 -0
  245. package/dist/translations/sk.d.ts +8 -0
  246. package/dist/translations/sk.js +5 -0
  247. package/dist/translations/sk.umd.js +11 -0
  248. package/dist/translations/sl.d.ts +8 -0
  249. package/dist/translations/sl.js +5 -0
  250. package/dist/translations/sl.umd.js +11 -0
  251. package/dist/translations/sq.d.ts +8 -0
  252. package/dist/translations/sq.js +5 -0
  253. package/dist/translations/sq.umd.js +11 -0
  254. package/dist/translations/sr-latn.d.ts +8 -0
  255. package/dist/translations/sr-latn.js +5 -0
  256. package/dist/translations/sr-latn.umd.js +11 -0
  257. package/dist/translations/sr.d.ts +8 -0
  258. package/dist/translations/sr.js +5 -0
  259. package/dist/translations/sr.umd.js +11 -0
  260. package/dist/translations/sv.d.ts +8 -0
  261. package/dist/translations/sv.js +5 -0
  262. package/dist/translations/sv.umd.js +11 -0
  263. package/dist/translations/th.d.ts +8 -0
  264. package/dist/translations/th.js +5 -0
  265. package/dist/translations/th.umd.js +11 -0
  266. package/dist/translations/ti.d.ts +8 -0
  267. package/dist/translations/ti.js +5 -0
  268. package/dist/translations/ti.umd.js +11 -0
  269. package/dist/translations/tk.d.ts +8 -0
  270. package/dist/translations/tk.js +5 -0
  271. package/dist/translations/tk.umd.js +11 -0
  272. package/dist/translations/tr.d.ts +8 -0
  273. package/dist/translations/tr.js +5 -0
  274. package/dist/translations/tr.umd.js +11 -0
  275. package/dist/translations/tt.d.ts +8 -0
  276. package/dist/translations/tt.js +5 -0
  277. package/dist/translations/tt.umd.js +11 -0
  278. package/dist/translations/ug.d.ts +8 -0
  279. package/dist/translations/ug.js +5 -0
  280. package/dist/translations/ug.umd.js +11 -0
  281. package/dist/translations/uk.d.ts +8 -0
  282. package/dist/translations/uk.js +5 -0
  283. package/dist/translations/uk.umd.js +11 -0
  284. package/dist/translations/ur.d.ts +8 -0
  285. package/dist/translations/ur.js +5 -0
  286. package/dist/translations/ur.umd.js +11 -0
  287. package/dist/translations/uz.d.ts +8 -0
  288. package/dist/translations/uz.js +5 -0
  289. package/dist/translations/uz.umd.js +11 -0
  290. package/dist/translations/vi.d.ts +8 -0
  291. package/dist/translations/vi.js +5 -0
  292. package/dist/translations/vi.umd.js +11 -0
  293. package/dist/translations/zh-cn.d.ts +8 -0
  294. package/dist/translations/zh-cn.js +5 -0
  295. package/dist/translations/zh-cn.umd.js +11 -0
  296. package/dist/translations/zh.d.ts +8 -0
  297. package/dist/translations/zh.js +5 -0
  298. package/dist/translations/zh.umd.js +11 -0
  299. package/lang/contexts.json +24 -0
  300. package/lang/translations/af.po +100 -0
  301. package/lang/translations/ar.po +100 -0
  302. package/lang/translations/ast.po +100 -0
  303. package/lang/translations/az.po +100 -0
  304. package/lang/translations/bg.po +100 -0
  305. package/lang/translations/bn.po +100 -0
  306. package/lang/translations/bs.po +100 -0
  307. package/lang/translations/ca.po +100 -0
  308. package/lang/translations/cs.po +100 -0
  309. package/lang/translations/da.po +100 -0
  310. package/lang/translations/de-ch.po +100 -0
  311. package/lang/translations/de.po +100 -0
  312. package/lang/translations/el.po +100 -0
  313. package/lang/translations/en-au.po +100 -0
  314. package/lang/translations/en-gb.po +100 -0
  315. package/lang/translations/en.po +100 -0
  316. package/lang/translations/eo.po +100 -0
  317. package/lang/translations/es-co.po +100 -0
  318. package/lang/translations/es.po +100 -0
  319. package/lang/translations/et.po +100 -0
  320. package/lang/translations/eu.po +100 -0
  321. package/lang/translations/fa.po +100 -0
  322. package/lang/translations/fi.po +100 -0
  323. package/lang/translations/fr.po +100 -0
  324. package/lang/translations/gl.po +100 -0
  325. package/lang/translations/gu.po +100 -0
  326. package/lang/translations/he.po +100 -0
  327. package/lang/translations/hi.po +100 -0
  328. package/lang/translations/hr.po +100 -0
  329. package/lang/translations/hu.po +100 -0
  330. package/lang/translations/hy.po +100 -0
  331. package/lang/translations/id.po +100 -0
  332. package/lang/translations/it.po +100 -0
  333. package/lang/translations/ja.po +100 -0
  334. package/lang/translations/jv.po +100 -0
  335. package/lang/translations/kk.po +100 -0
  336. package/lang/translations/km.po +100 -0
  337. package/lang/translations/kn.po +100 -0
  338. package/lang/translations/ko.po +100 -0
  339. package/lang/translations/ku.po +100 -0
  340. package/lang/translations/lt.po +100 -0
  341. package/lang/translations/lv.po +100 -0
  342. package/lang/translations/ms.po +100 -0
  343. package/lang/translations/nb.po +100 -0
  344. package/lang/translations/ne.po +100 -0
  345. package/lang/translations/nl.po +100 -0
  346. package/lang/translations/no.po +100 -0
  347. package/lang/translations/oc.po +100 -0
  348. package/lang/translations/pl.po +100 -0
  349. package/lang/translations/pt-br.po +100 -0
  350. package/lang/translations/pt.po +100 -0
  351. package/lang/translations/ro.po +100 -0
  352. package/lang/translations/ru.po +100 -0
  353. package/lang/translations/si.po +100 -0
  354. package/lang/translations/sk.po +100 -0
  355. package/lang/translations/sl.po +100 -0
  356. package/lang/translations/sq.po +100 -0
  357. package/lang/translations/sr-latn.po +100 -0
  358. package/lang/translations/sr.po +100 -0
  359. package/lang/translations/sv.po +100 -0
  360. package/lang/translations/th.po +100 -0
  361. package/lang/translations/ti.po +100 -0
  362. package/lang/translations/tk.po +100 -0
  363. package/lang/translations/tr.po +100 -0
  364. package/lang/translations/tt.po +100 -0
  365. package/lang/translations/ug.po +100 -0
  366. package/lang/translations/uk.po +100 -0
  367. package/lang/translations/ur.po +100 -0
  368. package/lang/translations/uz.po +100 -0
  369. package/lang/translations/vi.po +100 -0
  370. package/lang/translations/zh-cn.po +100 -0
  371. package/lang/translations/zh.po +100 -0
  372. package/package.json +58 -5
  373. package/src/augmentation.d.ts +24 -0
  374. package/src/augmentation.js +5 -0
  375. package/src/emoji.d.ts +32 -0
  376. package/src/emoji.js +38 -0
  377. package/src/emojicommand.d.ts +24 -0
  378. package/src/emojicommand.js +33 -0
  379. package/src/emojiconfig.d.ts +80 -0
  380. package/src/emojiconfig.js +5 -0
  381. package/src/emojimention.d.ts +68 -0
  382. package/src/emojimention.js +193 -0
  383. package/src/emojipicker.d.ts +97 -0
  384. package/src/emojipicker.js +255 -0
  385. package/src/emojirepository.d.ts +139 -0
  386. package/src/emojirepository.js +267 -0
  387. package/src/index.d.ts +14 -0
  388. package/src/index.js +13 -0
  389. package/src/ui/emojicategoriesview.d.ts +68 -0
  390. package/src/ui/emojicategoriesview.js +131 -0
  391. package/src/ui/emojigridview.d.ts +140 -0
  392. package/src/ui/emojigridview.js +183 -0
  393. package/src/ui/emojipickerview.d.ts +91 -0
  394. package/src/ui/emojipickerview.js +172 -0
  395. package/src/ui/emojisearchview.d.ts +51 -0
  396. package/src/ui/emojisearchview.js +89 -0
  397. package/src/ui/emojitoneview.d.ts +46 -0
  398. package/src/ui/emojitoneview.js +89 -0
  399. package/theme/emojicategories.css +29 -0
  400. package/theme/emojigrid.css +55 -0
  401. package/theme/emojipicker.css +32 -0
  402. package/theme/emojitone.css +21 -0
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module emoji/ui/emojicategoriesview
7
+ */
8
+ import { ButtonView, View, FocusCycler, type ViewCollection } from 'ckeditor5/src/ui.js';
9
+ import { FocusTracker, KeystrokeHandler, type Locale } from 'ckeditor5/src/utils.js';
10
+ import type { EmojiCategory } from '../emojirepository.js';
11
+ import '../../theme/emojicategories.css';
12
+ /**
13
+ * A class representing the navigation part of the emoji UI.
14
+ * It is responsible allowing the user to select a particular emoji category.
15
+ */
16
+ export default class EmojiCategoriesView extends View {
17
+ /**
18
+ * Currently selected emoji category name.
19
+ */
20
+ categoryName: string;
21
+ /**
22
+ * Tracks information about the DOM focus in the grid.
23
+ */
24
+ readonly focusTracker: FocusTracker;
25
+ /**
26
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
27
+ */
28
+ readonly keystrokes: KeystrokeHandler;
29
+ /**
30
+ * Helps cycling over focusable children in the input view.
31
+ */
32
+ readonly focusCycler: FocusCycler;
33
+ /**
34
+ * A collection of the categories buttons.
35
+ */
36
+ readonly buttonViews: ViewCollection<ButtonView>;
37
+ /**
38
+ * @inheritDoc
39
+ */
40
+ constructor(locale: Locale, { emojiCategories, categoryName }: {
41
+ emojiCategories: Array<EmojiCategory>;
42
+ categoryName: string;
43
+ });
44
+ /**
45
+ * @inheritDoc
46
+ */
47
+ render(): void;
48
+ /**
49
+ * @inheritDoc
50
+ */
51
+ destroy(): void;
52
+ /**
53
+ * @inheritDoc
54
+ */
55
+ focus(): void;
56
+ /**
57
+ * Marks all categories buttons as enabled (clickable).
58
+ */
59
+ enableCategories(): void;
60
+ /**
61
+ * Marks all categories buttons as disabled (non-clickable).
62
+ */
63
+ disableCategories(): void;
64
+ /**
65
+ * Creates a button representing a category item.
66
+ */
67
+ private _createCategoryButton;
68
+ }
@@ -0,0 +1,131 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module emoji/ui/emojicategoriesview
7
+ */
8
+ import { ButtonView, View, FocusCycler } from 'ckeditor5/src/ui.js';
9
+ import { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils.js';
10
+ import '../../theme/emojicategories.css';
11
+ /**
12
+ * A class representing the navigation part of the emoji UI.
13
+ * It is responsible allowing the user to select a particular emoji category.
14
+ */
15
+ export default class EmojiCategoriesView extends View {
16
+ /**
17
+ * @inheritDoc
18
+ */
19
+ constructor(locale, { emojiCategories, categoryName }) {
20
+ super(locale);
21
+ this.buttonViews = this.createCollection(emojiCategories.map(emojiCategory => this._createCategoryButton(emojiCategory)));
22
+ this.focusTracker = new FocusTracker();
23
+ this.keystrokes = new KeystrokeHandler();
24
+ this.focusCycler = new FocusCycler({
25
+ focusables: this.buttonViews,
26
+ focusTracker: this.focusTracker,
27
+ keystrokeHandler: this.keystrokes,
28
+ actions: {
29
+ focusPrevious: 'arrowleft',
30
+ focusNext: 'arrowright'
31
+ }
32
+ });
33
+ this.setTemplate({
34
+ tag: 'div',
35
+ attributes: {
36
+ class: ['ck', 'ck-emoji__categories-list'],
37
+ role: 'tablist'
38
+ },
39
+ children: this.buttonViews
40
+ });
41
+ this.on('change:categoryName', (event, name, newValue, oldValue) => {
42
+ const oldCategoryButton = this.buttonViews.find(button => button.tooltip === oldValue);
43
+ if (oldCategoryButton) {
44
+ oldCategoryButton.isOn = false;
45
+ }
46
+ const newCategoryButton = this.buttonViews.find(button => button.tooltip === newValue);
47
+ newCategoryButton.isOn = true;
48
+ });
49
+ this.set('categoryName', categoryName);
50
+ }
51
+ /**
52
+ * @inheritDoc
53
+ */
54
+ render() {
55
+ super.render();
56
+ this.buttonViews.forEach(buttonView => {
57
+ this.focusTracker.add(buttonView);
58
+ });
59
+ this.keystrokes.listenTo(this.element);
60
+ }
61
+ /**
62
+ * @inheritDoc
63
+ */
64
+ destroy() {
65
+ super.destroy();
66
+ this.focusTracker.destroy();
67
+ this.keystrokes.destroy();
68
+ this.buttonViews.destroy();
69
+ }
70
+ /**
71
+ * @inheritDoc
72
+ */
73
+ focus() {
74
+ this.buttonViews.first.focus();
75
+ }
76
+ /**
77
+ * Marks all categories buttons as enabled (clickable).
78
+ */
79
+ enableCategories() {
80
+ this.buttonViews.forEach(buttonView => {
81
+ buttonView.isEnabled = true;
82
+ });
83
+ }
84
+ /**
85
+ * Marks all categories buttons as disabled (non-clickable).
86
+ */
87
+ disableCategories() {
88
+ this.buttonViews.forEach(buttonView => {
89
+ buttonView.set({
90
+ class: '',
91
+ isEnabled: false,
92
+ isOn: false
93
+ });
94
+ });
95
+ }
96
+ /**
97
+ * Creates a button representing a category item.
98
+ */
99
+ _createCategoryButton(emojiCategory) {
100
+ const buttonView = new ButtonView();
101
+ const bind = buttonView.bindTemplate;
102
+ // A `[role="tab"]` element requires also the `[aria-selected]` attribute with its state.
103
+ buttonView.extendTemplate({
104
+ attributes: {
105
+ 'aria-selected': bind.to('isOn', value => value.toString()),
106
+ class: [
107
+ 'ck-emoji__category-item'
108
+ ]
109
+ }
110
+ });
111
+ buttonView.set({
112
+ ariaLabel: emojiCategory.title,
113
+ label: emojiCategory.icon,
114
+ role: 'tab',
115
+ tooltip: emojiCategory.title,
116
+ withText: true,
117
+ // To improve accessibility, disconnect a button and its label connection so that screen
118
+ // readers can read the `[aria-label]` attribute directly from the more descriptive button.
119
+ ariaLabelledBy: undefined
120
+ });
121
+ buttonView.on('execute', () => {
122
+ this.categoryName = emojiCategory.title;
123
+ });
124
+ buttonView.on('change:isEnabled', () => {
125
+ if (buttonView.isEnabled && buttonView.tooltip === this.categoryName) {
126
+ buttonView.isOn = true;
127
+ }
128
+ });
129
+ return buttonView;
130
+ }
131
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module emoji/ui/emojigridview
7
+ */
8
+ import { ButtonView, type FilteredView, View, type ViewCollection } from 'ckeditor5/src/ui.js';
9
+ import { FocusTracker, KeystrokeHandler, type Locale } from 'ckeditor5/src/utils.js';
10
+ import type { EmojiCategory, EmojiEntry } from '../emojirepository.js';
11
+ import type { SkinToneId } from '../emojiconfig.js';
12
+ import '../../theme/emojigrid.css';
13
+ /**
14
+ * A grid of emoji tiles. It allows browsing emojis and selecting them to be inserted into the content.
15
+ */
16
+ export default class EmojiGridView extends View<HTMLDivElement> implements FilteredView {
17
+ /**
18
+ * Defines the active category name.
19
+ *
20
+ * @observable
21
+ */
22
+ categoryName: string;
23
+ /**
24
+ * Active skin tone.
25
+ *
26
+ * @observable
27
+ */
28
+ skinTone: SkinToneId;
29
+ /**
30
+ * Set to `true` when the {@link #tiles} collection does not contain items to display.
31
+ *
32
+ * @observable
33
+ */
34
+ isEmpty: boolean;
35
+ /**
36
+ * A collection of the child tile views. Each tile represents a particular emoji.
37
+ */
38
+ readonly tiles: ViewCollection<ButtonView>;
39
+ /**
40
+ * Tracks information about the DOM focus in the grid.
41
+ */
42
+ readonly focusTracker: FocusTracker;
43
+ /**
44
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
45
+ */
46
+ readonly keystrokes: KeystrokeHandler;
47
+ /**
48
+ * An array containing all emojis grouped by their categories.
49
+ */
50
+ readonly emojiCategories: Array<EmojiCategory>;
51
+ /**
52
+ * A collection of all already created tile views. Each tile represents a particular emoji.
53
+ * The cached tiles collection is used for efficiency purposes to avoid re-creating a particular
54
+ * tile again when the grid view has changed.
55
+ */
56
+ readonly cachedTiles: ViewCollection<ButtonView>;
57
+ /**
58
+ * A callback used to filter grid items by a specified query.
59
+ */
60
+ private readonly _getEmojiByQuery;
61
+ /**
62
+ * @inheritDoc
63
+ */
64
+ constructor(locale: Locale, { categoryName, emojiCategories, getEmojiByQuery, skinTone }: {
65
+ categoryName: string;
66
+ emojiCategories: Array<EmojiCategory>;
67
+ getEmojiByQuery: EmojiSearchQueryCallback;
68
+ skinTone: SkinToneId;
69
+ });
70
+ /**
71
+ * @inheritDoc
72
+ */
73
+ render(): void;
74
+ /**
75
+ * @inheritDoc
76
+ */
77
+ destroy(): void;
78
+ /**
79
+ * Focuses the first focusable in {@link ~EmojiGridView#tiles} if available.
80
+ */
81
+ focus(): void;
82
+ /**
83
+ * Filters the grid view by the given regular expression.
84
+ *
85
+ * It filters either by the pattern or an emoji category, but never both.
86
+ *
87
+ * @param pattern Expression to search or `null` when filter by category name.
88
+ */
89
+ filter(pattern: RegExp | null): {
90
+ resultsCount: number;
91
+ totalItemsCount: number;
92
+ };
93
+ /**
94
+ * Filters emojis to show based on the specified query phrase.
95
+ *
96
+ * @param query A query used to filter the grid.
97
+ */
98
+ private _getItemsByQuery;
99
+ /**
100
+ * Returns emojis that belong to the specified category.
101
+ */
102
+ private _getItemsByCategory;
103
+ /**
104
+ * Updates the grid by removing the existing items and insert the new ones.
105
+ *
106
+ * @param items An array of items to insert.
107
+ */
108
+ private _updateGrid;
109
+ /**
110
+ * Creates a new tile for the grid. Created tile is added to the {@link #cachedTiles} collection for further usage, if needed.
111
+ *
112
+ * @param emoji The emoji itself.
113
+ * @param name The name of the emoji (e.g. "Smiling Face with Smiling Eyes").
114
+ */
115
+ private _createTile;
116
+ }
117
+ /**
118
+ * A callback used to filter grid items by a specified query.
119
+ */
120
+ export type EmojiSearchQueryCallback = (query: string) => Array<EmojiEntry>;
121
+ /**
122
+ * Fired when any of {@link ~EmojiGridView#tiles grid tiles} is clicked.
123
+ *
124
+ * @eventName ~EmojiGridView#execute
125
+ * @param data Additional information about the event.
126
+ */
127
+ export type EmojiGridViewExecuteEvent = {
128
+ name: 'execute';
129
+ args: [data: EmojiGridViewEventData];
130
+ };
131
+ export type EmojiGridViewEventData = {
132
+ /**
133
+ * The name of the emoji (e.g. "Smiling Face with Smiling Eyes").
134
+ */
135
+ name: string;
136
+ /**
137
+ * The emoji itself.
138
+ */
139
+ emoji: string;
140
+ };
@@ -0,0 +1,183 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module emoji/ui/emojigridview
7
+ */
8
+ import { addKeyboardHandlingForGrid, ButtonView, View } from 'ckeditor5/src/ui.js';
9
+ import { FocusTracker, global, KeystrokeHandler } from 'ckeditor5/src/utils.js';
10
+ import '../../theme/emojigrid.css';
11
+ /**
12
+ * A grid of emoji tiles. It allows browsing emojis and selecting them to be inserted into the content.
13
+ */
14
+ export default class EmojiGridView extends View {
15
+ /**
16
+ * @inheritDoc
17
+ */
18
+ constructor(locale, { categoryName, emojiCategories, getEmojiByQuery, skinTone }) {
19
+ super(locale);
20
+ this.set('isEmpty', true);
21
+ this.set('categoryName', categoryName);
22
+ this.set('skinTone', skinTone);
23
+ this.tiles = this.createCollection();
24
+ this.cachedTiles = this.createCollection();
25
+ this.focusTracker = new FocusTracker();
26
+ this.keystrokes = new KeystrokeHandler();
27
+ this._getEmojiByQuery = getEmojiByQuery;
28
+ this.emojiCategories = emojiCategories;
29
+ const bind = this.bindTemplate;
30
+ this.setTemplate({
31
+ tag: 'div',
32
+ children: [
33
+ {
34
+ tag: 'div',
35
+ attributes: {
36
+ role: 'grid',
37
+ class: [
38
+ 'ck',
39
+ 'ck-emoji__grid'
40
+ ]
41
+ },
42
+ children: this.tiles
43
+ }
44
+ ],
45
+ attributes: {
46
+ role: 'tabpanel',
47
+ class: [
48
+ 'ck',
49
+ 'ck-emoji__tiles',
50
+ // To avoid issues with focus cycling, ignore a grid when it's empty.
51
+ bind.if('isEmpty', 'ck-hidden', value => value)
52
+ ]
53
+ }
54
+ });
55
+ addKeyboardHandlingForGrid({
56
+ keystrokeHandler: this.keystrokes,
57
+ focusTracker: this.focusTracker,
58
+ gridItems: this.tiles,
59
+ numberOfColumns: () => global.window
60
+ .getComputedStyle(this.element.firstChild) // Responsive `.ck-emoji-grid__tiles`.
61
+ .getPropertyValue('grid-template-columns')
62
+ .split(' ')
63
+ .length,
64
+ uiLanguageDirection: this.locale && this.locale.uiLanguageDirection
65
+ });
66
+ }
67
+ /**
68
+ * @inheritDoc
69
+ */
70
+ render() {
71
+ super.render();
72
+ this.keystrokes.listenTo(this.element);
73
+ }
74
+ /**
75
+ * @inheritDoc
76
+ */
77
+ destroy() {
78
+ super.destroy();
79
+ this.keystrokes.destroy();
80
+ this.focusTracker.destroy();
81
+ }
82
+ /**
83
+ * Focuses the first focusable in {@link ~EmojiGridView#tiles} if available.
84
+ */
85
+ focus() {
86
+ const firstTile = this.tiles.first;
87
+ if (firstTile) {
88
+ firstTile.focus();
89
+ }
90
+ }
91
+ /**
92
+ * Filters the grid view by the given regular expression.
93
+ *
94
+ * It filters either by the pattern or an emoji category, but never both.
95
+ *
96
+ * @param pattern Expression to search or `null` when filter by category name.
97
+ */
98
+ filter(pattern) {
99
+ const { matchingItems, allItems } = pattern ? this._getItemsByQuery(pattern.source) : this._getItemsByCategory();
100
+ this._updateGrid(matchingItems);
101
+ this.set('isEmpty', matchingItems.length === 0);
102
+ return {
103
+ resultsCount: matchingItems.length,
104
+ totalItemsCount: allItems.length
105
+ };
106
+ }
107
+ /**
108
+ * Filters emojis to show based on the specified query phrase.
109
+ *
110
+ * @param query A query used to filter the grid.
111
+ */
112
+ _getItemsByQuery(query) {
113
+ return {
114
+ matchingItems: this._getEmojiByQuery(query),
115
+ allItems: this.emojiCategories.flatMap(group => group.items)
116
+ };
117
+ }
118
+ /**
119
+ * Returns emojis that belong to the specified category.
120
+ */
121
+ _getItemsByCategory() {
122
+ const emojiCategory = this.emojiCategories.find(item => item.title === this.categoryName);
123
+ const { items } = emojiCategory;
124
+ return {
125
+ matchingItems: items,
126
+ allItems: items
127
+ };
128
+ }
129
+ /**
130
+ * Updates the grid by removing the existing items and insert the new ones.
131
+ *
132
+ * @param items An array of items to insert.
133
+ */
134
+ _updateGrid(items) {
135
+ // Clean-up.
136
+ [...this.tiles].forEach(item => {
137
+ this.focusTracker.remove(item);
138
+ this.tiles.remove(item);
139
+ });
140
+ items
141
+ // Create tiles from matching results.
142
+ .map(item => {
143
+ const emoji = item.skins[this.skinTone] || item.skins.default;
144
+ return this.cachedTiles.get(emoji) || this._createTile(emoji, item.annotation);
145
+ })
146
+ // Insert new elements.
147
+ .forEach(item => {
148
+ this.tiles.add(item);
149
+ this.focusTracker.add(item);
150
+ });
151
+ }
152
+ /**
153
+ * Creates a new tile for the grid. Created tile is added to the {@link #cachedTiles} collection for further usage, if needed.
154
+ *
155
+ * @param emoji The emoji itself.
156
+ * @param name The name of the emoji (e.g. "Smiling Face with Smiling Eyes").
157
+ */
158
+ _createTile(emoji, name) {
159
+ const tile = new ButtonView(this.locale);
160
+ tile.viewUid = emoji;
161
+ tile.extendTemplate({
162
+ attributes: {
163
+ class: [
164
+ 'ck-emoji__tile'
165
+ ]
166
+ }
167
+ });
168
+ tile.set({
169
+ label: emoji,
170
+ tooltip: name,
171
+ withText: true,
172
+ ariaLabel: name,
173
+ // To improve accessibility, disconnect a button and its label connection so that screen
174
+ // readers can read the `[aria-label]` attribute directly from the more descriptive button.
175
+ ariaLabelledBy: undefined
176
+ });
177
+ tile.on('execute', () => {
178
+ this.fire('execute', { name, emoji });
179
+ });
180
+ this.cachedTiles.add(tile);
181
+ return tile;
182
+ }
183
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module emoji/ui/emojipickerview
7
+ */
8
+ import { FocusCycler, SearchInfoView, View, type FocusableView, type ViewCollection } from 'ckeditor5/src/ui.js';
9
+ import { FocusTracker, KeystrokeHandler, type Locale } from 'ckeditor5/src/utils.js';
10
+ import EmojiGridView, { type EmojiSearchQueryCallback } from './emojigridview.js';
11
+ import EmojiCategoriesView from './emojicategoriesview.js';
12
+ import EmojiSearchView from './emojisearchview.js';
13
+ import EmojiToneView from './emojitoneview.js';
14
+ import type { SkinToneId } from '../emojiconfig.js';
15
+ import type { EmojiCategory, SkinTone } from '../emojirepository.js';
16
+ /**
17
+ * A view that glues pieces of the emoji panel together.
18
+ */
19
+ export default class EmojiPickerView extends View<HTMLDivElement> {
20
+ /**
21
+ * A collection of the focusable children of the view.
22
+ */
23
+ readonly items: ViewCollection<FocusableView>;
24
+ /**
25
+ * Tracks information about the DOM focus in the view.
26
+ */
27
+ readonly focusTracker: FocusTracker;
28
+ /**
29
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
30
+ */
31
+ readonly keystrokes: KeystrokeHandler;
32
+ /**
33
+ * Helps cycling over focusable {@link #items} in the view.
34
+ */
35
+ readonly focusCycler: FocusCycler;
36
+ /**
37
+ * An instance of the `EmojiSearchView`.
38
+ */
39
+ readonly searchView: EmojiSearchView;
40
+ /**
41
+ * An instance of the `EmojiToneView`.
42
+ */
43
+ readonly toneView: EmojiToneView;
44
+ /**
45
+ * An instance of the `EmojiCategoriesView`.
46
+ */
47
+ readonly categoriesView: EmojiCategoriesView;
48
+ /**
49
+ * An instance of the `EmojiGridView`.
50
+ */
51
+ readonly gridView: EmojiGridView;
52
+ /**
53
+ * An instance of the `EmojiGridView`.
54
+ */
55
+ readonly infoView: SearchInfoView;
56
+ /**
57
+ * @inheritDoc
58
+ */
59
+ constructor(locale: Locale, { emojiCategories, getEmojiByQuery, skinTone, skinTones }: {
60
+ emojiCategories: Array<EmojiCategory>;
61
+ getEmojiByQuery: EmojiSearchQueryCallback;
62
+ skinTone: SkinToneId;
63
+ skinTones: Array<SkinTone>;
64
+ });
65
+ /**
66
+ * @inheritDoc
67
+ */
68
+ render(): void;
69
+ /**
70
+ * @inheritDoc
71
+ */
72
+ destroy(): void;
73
+ /**
74
+ * Focuses the search input.
75
+ */
76
+ focus(): void;
77
+ /**
78
+ * Initializes interactions between sub-views.
79
+ */
80
+ private _setupEventListeners;
81
+ }
82
+ /**
83
+ * Fired when the {@link module:emoji/ui/emojipickerview~EmojiPickerView} layout is changed, either by filtering emoji tiles or
84
+ * showing a hint to a user regarding the provided query.
85
+ *
86
+ * @eventName ~EmojiPickerView#update
87
+ */
88
+ export type EmojiPickerViewUpdateEvent = {
89
+ name: 'update';
90
+ args: [];
91
+ };