doclific 0.2.1 → 0.2.2

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 (220) hide show
  1. package/LICENSE +17 -0
  2. package/dist/bin/doclific.js +36 -8
  3. package/package.json +10 -3
  4. package/readme.md +77 -0
  5. package/.gitattributes +0 -2
  6. package/.prettierignore +0 -5
  7. package/.prettierrc +0 -9
  8. package/.vscode/settings.json +0 -13
  9. package/frontend/components.json +0 -24
  10. package/frontend/eslint.config.js +0 -23
  11. package/frontend/index.html +0 -25
  12. package/frontend/package-lock.json +0 -15754
  13. package/frontend/public/logo.svg +0 -1
  14. package/frontend/src/App.tsx +0 -21
  15. package/frontend/src/components/app-sidebar.tsx +0 -393
  16. package/frontend/src/components/editor/editor-base-kit.tsx +0 -43
  17. package/frontend/src/components/editor/editor-kit.tsx +0 -93
  18. package/frontend/src/components/editor/plugins/align-base-kit.tsx +0 -16
  19. package/frontend/src/components/editor/plugins/align-kit.tsx +0 -18
  20. package/frontend/src/components/editor/plugins/autoformat-kit.tsx +0 -236
  21. package/frontend/src/components/editor/plugins/basic-blocks-base-kit.tsx +0 -35
  22. package/frontend/src/components/editor/plugins/basic-blocks-kit.tsx +0 -88
  23. package/frontend/src/components/editor/plugins/basic-marks-base-kit.tsx +0 -27
  24. package/frontend/src/components/editor/plugins/basic-marks-kit.tsx +0 -41
  25. package/frontend/src/components/editor/plugins/basic-nodes-kit.tsx +0 -6
  26. package/frontend/src/components/editor/plugins/block-menu-kit.tsx +0 -14
  27. package/frontend/src/components/editor/plugins/block-placeholder-kit.tsx +0 -17
  28. package/frontend/src/components/editor/plugins/block-selection-kit.tsx +0 -32
  29. package/frontend/src/components/editor/plugins/callout-base-kit.tsx +0 -7
  30. package/frontend/src/components/editor/plugins/callout-kit.tsx +0 -7
  31. package/frontend/src/components/editor/plugins/code-block-base-kit.tsx +0 -23
  32. package/frontend/src/components/editor/plugins/code-block-kit.tsx +0 -26
  33. package/frontend/src/components/editor/plugins/codebase-kit.tsx +0 -23
  34. package/frontend/src/components/editor/plugins/column-base-kit.tsx +0 -11
  35. package/frontend/src/components/editor/plugins/column-kit.tsx +0 -10
  36. package/frontend/src/components/editor/plugins/comment-base-kit.tsx +0 -7
  37. package/frontend/src/components/editor/plugins/comment-kit.tsx +0 -97
  38. package/frontend/src/components/editor/plugins/cursor-overlay-kit.tsx +0 -13
  39. package/frontend/src/components/editor/plugins/date-base-kit.tsx +0 -5
  40. package/frontend/src/components/editor/plugins/date-kit.tsx +0 -7
  41. package/frontend/src/components/editor/plugins/discussion-kit.tsx +0 -148
  42. package/frontend/src/components/editor/plugins/dnd-kit.tsx +0 -28
  43. package/frontend/src/components/editor/plugins/docx-kit.tsx +0 -6
  44. package/frontend/src/components/editor/plugins/emoji-kit.tsx +0 -13
  45. package/frontend/src/components/editor/plugins/excalidraw-kit.tsx +0 -9
  46. package/frontend/src/components/editor/plugins/exit-break-kit.tsx +0 -12
  47. package/frontend/src/components/editor/plugins/floating-toolbar-kit.tsx +0 -19
  48. package/frontend/src/components/editor/plugins/font-base-kit.tsx +0 -20
  49. package/frontend/src/components/editor/plugins/font-kit.tsx +0 -29
  50. package/frontend/src/components/editor/plugins/indent-base-kit.tsx +0 -19
  51. package/frontend/src/components/editor/plugins/indent-kit.tsx +0 -22
  52. package/frontend/src/components/editor/plugins/line-height-base-kit.tsx +0 -14
  53. package/frontend/src/components/editor/plugins/line-height-kit.tsx +0 -16
  54. package/frontend/src/components/editor/plugins/link-base-kit.tsx +0 -5
  55. package/frontend/src/components/editor/plugins/link-kit.tsx +0 -15
  56. package/frontend/src/components/editor/plugins/list-base-kit.tsx +0 -23
  57. package/frontend/src/components/editor/plugins/list-kit.tsx +0 -26
  58. package/frontend/src/components/editor/plugins/markdown-kit.tsx +0 -46
  59. package/frontend/src/components/editor/plugins/math-base-kit.tsx +0 -11
  60. package/frontend/src/components/editor/plugins/math-kit.tsx +0 -13
  61. package/frontend/src/components/editor/plugins/media-base-kit.tsx +0 -31
  62. package/frontend/src/components/editor/plugins/media-kit.tsx +0 -43
  63. package/frontend/src/components/editor/plugins/mention-base-kit.tsx +0 -7
  64. package/frontend/src/components/editor/plugins/mention-kit.tsx +0 -15
  65. package/frontend/src/components/editor/plugins/slash-kit.tsx +0 -18
  66. package/frontend/src/components/editor/plugins/suggestion-base-kit.tsx +0 -7
  67. package/frontend/src/components/editor/plugins/suggestion-kit.tsx +0 -90
  68. package/frontend/src/components/editor/plugins/table-base-kit.tsx +0 -20
  69. package/frontend/src/components/editor/plugins/table-kit.tsx +0 -22
  70. package/frontend/src/components/editor/plugins/toc-base-kit.tsx +0 -5
  71. package/frontend/src/components/editor/plugins/toc-kit.tsx +0 -14
  72. package/frontend/src/components/editor/plugins/toggle-base-kit.tsx +0 -7
  73. package/frontend/src/components/editor/plugins/toggle-kit.tsx +0 -11
  74. package/frontend/src/components/editor/transforms.ts +0 -194
  75. package/frontend/src/components/markdown-to-slate-demo.tsx +0 -50
  76. package/frontend/src/components/mode-toggle.tsx +0 -15
  77. package/frontend/src/components/theme-provider.tsx +0 -73
  78. package/frontend/src/components/ui/alert-dialog.tsx +0 -155
  79. package/frontend/src/components/ui/align-toolbar-button.tsx +0 -84
  80. package/frontend/src/components/ui/avatar.tsx +0 -51
  81. package/frontend/src/components/ui/block-context-menu.tsx +0 -199
  82. package/frontend/src/components/ui/block-discussion.tsx +0 -365
  83. package/frontend/src/components/ui/block-draggable.tsx +0 -512
  84. package/frontend/src/components/ui/block-list-static.tsx +0 -80
  85. package/frontend/src/components/ui/block-list.tsx +0 -87
  86. package/frontend/src/components/ui/block-selection.tsx +0 -42
  87. package/frontend/src/components/ui/block-suggestion.tsx +0 -473
  88. package/frontend/src/components/ui/blockquote-node-static.tsx +0 -11
  89. package/frontend/src/components/ui/blockquote-node.tsx +0 -13
  90. package/frontend/src/components/ui/button.tsx +0 -62
  91. package/frontend/src/components/ui/calendar.tsx +0 -218
  92. package/frontend/src/components/ui/callout-node-static.tsx +0 -36
  93. package/frontend/src/components/ui/callout-node.tsx +0 -63
  94. package/frontend/src/components/ui/caption.tsx +0 -63
  95. package/frontend/src/components/ui/checkbox.tsx +0 -30
  96. package/frontend/src/components/ui/code-block-node-static.tsx +0 -35
  97. package/frontend/src/components/ui/code-block-node.tsx +0 -287
  98. package/frontend/src/components/ui/code-node-static.tsx +0 -15
  99. package/frontend/src/components/ui/code-node.tsx +0 -17
  100. package/frontend/src/components/ui/codebase-snippet-node.tsx +0 -237
  101. package/frontend/src/components/ui/column-node-static.tsx +0 -29
  102. package/frontend/src/components/ui/column-node.tsx +0 -317
  103. package/frontend/src/components/ui/command.tsx +0 -182
  104. package/frontend/src/components/ui/comment-node-static.tsx +0 -15
  105. package/frontend/src/components/ui/comment-node.tsx +0 -45
  106. package/frontend/src/components/ui/comment-toolbar-button.tsx +0 -24
  107. package/frontend/src/components/ui/comment.tsx +0 -618
  108. package/frontend/src/components/ui/context-menu.tsx +0 -250
  109. package/frontend/src/components/ui/cursor-overlay.tsx +0 -66
  110. package/frontend/src/components/ui/date-node-static.tsx +0 -45
  111. package/frontend/src/components/ui/date-node.tsx +0 -93
  112. package/frontend/src/components/ui/dialog.tsx +0 -143
  113. package/frontend/src/components/ui/dropdown-menu.tsx +0 -255
  114. package/frontend/src/components/ui/dynamic-icon.tsx +0 -12
  115. package/frontend/src/components/ui/editor-static.tsx +0 -53
  116. package/frontend/src/components/ui/editor.tsx +0 -130
  117. package/frontend/src/components/ui/emoji-node.tsx +0 -69
  118. package/frontend/src/components/ui/emoji-toolbar-button.tsx +0 -628
  119. package/frontend/src/components/ui/equation-node-static.tsx +0 -98
  120. package/frontend/src/components/ui/equation-node.tsx +0 -235
  121. package/frontend/src/components/ui/equation-toolbar-button.tsx +0 -25
  122. package/frontend/src/components/ui/excalidraw-node.tsx +0 -36
  123. package/frontend/src/components/ui/export-toolbar-button.tsx +0 -174
  124. package/frontend/src/components/ui/file-selector.tsx +0 -339
  125. package/frontend/src/components/ui/floating-toolbar-buttons.tsx +0 -73
  126. package/frontend/src/components/ui/floating-toolbar.tsx +0 -85
  127. package/frontend/src/components/ui/font-color-toolbar-button.tsx +0 -831
  128. package/frontend/src/components/ui/font-size-toolbar-button.tsx +0 -152
  129. package/frontend/src/components/ui/heading-node-static.tsx +0 -68
  130. package/frontend/src/components/ui/heading-node.tsx +0 -58
  131. package/frontend/src/components/ui/highlight-node-static.tsx +0 -11
  132. package/frontend/src/components/ui/highlight-node.tsx +0 -13
  133. package/frontend/src/components/ui/history-toolbar-button.tsx +0 -50
  134. package/frontend/src/components/ui/hr-node-static.tsx +0 -20
  135. package/frontend/src/components/ui/hr-node.tsx +0 -33
  136. package/frontend/src/components/ui/import-toolbar-button.tsx +0 -97
  137. package/frontend/src/components/ui/indent-toolbar-button.tsx +0 -30
  138. package/frontend/src/components/ui/inline-combobox.tsx +0 -414
  139. package/frontend/src/components/ui/input.tsx +0 -21
  140. package/frontend/src/components/ui/insert-toolbar-button.tsx +0 -254
  141. package/frontend/src/components/ui/kbd-node-static.tsx +0 -15
  142. package/frontend/src/components/ui/kbd-node.tsx +0 -17
  143. package/frontend/src/components/ui/layout-header.tsx +0 -35
  144. package/frontend/src/components/ui/line-height-toolbar-button.tsx +0 -68
  145. package/frontend/src/components/ui/link-node-static.tsx +0 -21
  146. package/frontend/src/components/ui/link-node.tsx +0 -39
  147. package/frontend/src/components/ui/link-toolbar-button.tsx +0 -22
  148. package/frontend/src/components/ui/link-toolbar.tsx +0 -206
  149. package/frontend/src/components/ui/list-toolbar-button.tsx +0 -204
  150. package/frontend/src/components/ui/mark-toolbar-button.tsx +0 -19
  151. package/frontend/src/components/ui/media-audio-node-static.tsx +0 -17
  152. package/frontend/src/components/ui/media-audio-node.tsx +0 -39
  153. package/frontend/src/components/ui/media-embed-node.tsx +0 -136
  154. package/frontend/src/components/ui/media-file-node-static.tsx +0 -29
  155. package/frontend/src/components/ui/media-file-node.tsx +0 -47
  156. package/frontend/src/components/ui/media-image-node-static.tsx +0 -39
  157. package/frontend/src/components/ui/media-image-node.tsx +0 -80
  158. package/frontend/src/components/ui/media-placeholder-node.tsx +0 -249
  159. package/frontend/src/components/ui/media-preview-dialog.tsx +0 -152
  160. package/frontend/src/components/ui/media-toolbar-button.tsx +0 -225
  161. package/frontend/src/components/ui/media-toolbar.tsx +0 -115
  162. package/frontend/src/components/ui/media-upload-toast.tsx +0 -66
  163. package/frontend/src/components/ui/media-video-node-static.tsx +0 -30
  164. package/frontend/src/components/ui/media-video-node.tsx +0 -121
  165. package/frontend/src/components/ui/mention-node-static.tsx +0 -36
  166. package/frontend/src/components/ui/mention-node.tsx +0 -194
  167. package/frontend/src/components/ui/mode-toolbar-button.tsx +0 -123
  168. package/frontend/src/components/ui/more-toolbar-button.tsx +0 -80
  169. package/frontend/src/components/ui/paragraph-node-static.tsx +0 -13
  170. package/frontend/src/components/ui/paragraph-node.tsx +0 -15
  171. package/frontend/src/components/ui/popover.tsx +0 -46
  172. package/frontend/src/components/ui/resize-handle.tsx +0 -87
  173. package/frontend/src/components/ui/separator.tsx +0 -28
  174. package/frontend/src/components/ui/sheet.tsx +0 -139
  175. package/frontend/src/components/ui/sidebar.tsx +0 -726
  176. package/frontend/src/components/ui/skeleton.tsx +0 -13
  177. package/frontend/src/components/ui/slash-node.tsx +0 -233
  178. package/frontend/src/components/ui/sonner.tsx +0 -38
  179. package/frontend/src/components/ui/suggestion-node-static.tsx +0 -35
  180. package/frontend/src/components/ui/suggestion-node.tsx +0 -162
  181. package/frontend/src/components/ui/suggestion-toolbar-button.tsx +0 -25
  182. package/frontend/src/components/ui/table-icons.tsx +0 -862
  183. package/frontend/src/components/ui/table-node-static.tsx +0 -98
  184. package/frontend/src/components/ui/table-node.tsx +0 -656
  185. package/frontend/src/components/ui/table-toolbar-button.tsx +0 -264
  186. package/frontend/src/components/ui/toc-node-static.tsx +0 -92
  187. package/frontend/src/components/ui/toc-node.tsx +0 -55
  188. package/frontend/src/components/ui/toggle-node-static.tsx +0 -18
  189. package/frontend/src/components/ui/toggle-node.tsx +0 -36
  190. package/frontend/src/components/ui/toggle-toolbar-button.tsx +0 -22
  191. package/frontend/src/components/ui/toolbar.tsx +0 -387
  192. package/frontend/src/components/ui/tooltip.tsx +0 -59
  193. package/frontend/src/components/ui/turn-into-toolbar-button.tsx +0 -188
  194. package/frontend/src/hooks/use-debounce.ts +0 -18
  195. package/frontend/src/hooks/use-is-touch-device.ts +0 -24
  196. package/frontend/src/hooks/use-mobile.ts +0 -19
  197. package/frontend/src/hooks/use-mounted.ts +0 -11
  198. package/frontend/src/hooks/use-upload-file.ts +0 -128
  199. package/frontend/src/index.css +0 -128
  200. package/frontend/src/layout.tsx +0 -42
  201. package/frontend/src/lib/markdown-joiner-transform.ts +0 -239
  202. package/frontend/src/lib/orpc.ts +0 -13
  203. package/frontend/src/lib/uploadthing.ts +0 -19
  204. package/frontend/src/lib/utils.ts +0 -6
  205. package/frontend/src/main.tsx +0 -13
  206. package/frontend/src/pages/editor.tsx +0 -44
  207. package/frontend/src/types/docs.d.ts +0 -6
  208. package/frontend/src/types/global.d.ts +0 -9
  209. package/frontend/src/types/router.d.ts +0 -4
  210. package/frontend/tsconfig.app.json +0 -33
  211. package/frontend/tsconfig.json +0 -10
  212. package/frontend/tsconfig.node.json +0 -26
  213. package/frontend/vite.config.ts +0 -14
  214. package/src/bin/doclific.ts +0 -47
  215. package/src/core/codebase.ts +0 -39
  216. package/src/core/docs.ts +0 -90
  217. package/src/core/git.ts +0 -48
  218. package/src/server/index.ts +0 -55
  219. package/src/server/router.ts +0 -65
  220. package/tsconfig.json +0 -15
@@ -1,628 +0,0 @@
1
- 'use client';
2
- /* eslint-disable react-hooks/refs */
3
-
4
- import * as React from 'react';
5
-
6
- import type { Emoji } from '@emoji-mart/data';
7
-
8
- import {
9
- type EmojiCategoryList,
10
- type EmojiIconList,
11
- type GridRow,
12
- EmojiSettings,
13
- } from '@platejs/emoji';
14
- import {
15
- type EmojiDropdownMenuOptions,
16
- type UseEmojiPickerType,
17
- useEmojiDropdownMenuState,
18
- } from '@platejs/emoji/react';
19
- import * as Popover from '@radix-ui/react-popover';
20
- import {
21
- AppleIcon,
22
- ClockIcon,
23
- CompassIcon,
24
- FlagIcon,
25
- LeafIcon,
26
- LightbulbIcon,
27
- MusicIcon,
28
- SearchIcon,
29
- SmileIcon,
30
- StarIcon,
31
- XIcon,
32
- } from 'lucide-react';
33
-
34
- import { Button } from '@/components/ui/button';
35
- import {
36
- Tooltip,
37
- TooltipContent,
38
- TooltipProvider,
39
- TooltipTrigger,
40
- } from '@/components/ui/tooltip';
41
- import { cn } from '@/lib/utils';
42
- import { ToolbarButton } from '@/components/ui/toolbar';
43
-
44
- export function EmojiToolbarButton({
45
- options,
46
- ...props
47
- }: {
48
- options?: EmojiDropdownMenuOptions;
49
- } & React.ComponentPropsWithoutRef<typeof ToolbarButton>) {
50
- const { emojiPickerState, isOpen, setIsOpen } =
51
- useEmojiDropdownMenuState(options);
52
-
53
- return (
54
- <EmojiPopover
55
- control={
56
- <ToolbarButton pressed={isOpen} tooltip="Emoji" isDropdown {...props}>
57
- <SmileIcon />
58
- </ToolbarButton>
59
- }
60
- isOpen={isOpen}
61
- setIsOpen={setIsOpen}
62
- >
63
- <EmojiPicker
64
- {...emojiPickerState}
65
- isOpen={isOpen}
66
- setIsOpen={setIsOpen}
67
- settings={options?.settings}
68
- />
69
- </EmojiPopover>
70
- );
71
- }
72
-
73
- export function EmojiPopover({
74
- children,
75
- control,
76
- isOpen,
77
- setIsOpen,
78
- }: {
79
- children: React.ReactNode;
80
- control: React.ReactNode;
81
- isOpen: boolean;
82
- setIsOpen: (open: boolean) => void;
83
- }) {
84
- return (
85
- <Popover.Root open={isOpen} onOpenChange={setIsOpen}>
86
- <Popover.Trigger asChild>{control}</Popover.Trigger>
87
-
88
- <Popover.Portal>
89
- <Popover.Content className="z-100">{children}</Popover.Content>
90
- </Popover.Portal>
91
- </Popover.Root>
92
- );
93
- }
94
-
95
- export function EmojiPicker({
96
- clearSearch,
97
- emoji,
98
- emojiLibrary,
99
- focusedCategory,
100
- hasFound,
101
- i18n,
102
- icons = {
103
- categories: emojiCategoryIcons,
104
- search: emojiSearchIcons,
105
- },
106
- isSearching,
107
- refs,
108
- searchResult,
109
- searchValue,
110
- setSearch,
111
- settings = EmojiSettings,
112
- visibleCategories,
113
- handleCategoryClick,
114
- onMouseOver,
115
- onSelectEmoji,
116
- }: Omit<UseEmojiPickerType, 'icons'> & {
117
- icons?: EmojiIconList<React.ReactElement>;
118
- }) {
119
- return (
120
- <div
121
- className={cn(
122
- 'flex flex-col rounded-xl bg-popover text-popover-foreground',
123
- 'h-[23rem] w-80 border shadow-md'
124
- )}
125
- >
126
- <EmojiPickerNavigation
127
- onClick={handleCategoryClick}
128
- emojiLibrary={emojiLibrary}
129
- focusedCategory={focusedCategory}
130
- i18n={i18n}
131
- icons={icons}
132
- />
133
- <EmojiPickerSearchBar
134
- i18n={i18n}
135
- searchValue={searchValue}
136
- setSearch={setSearch}
137
- >
138
- <EmojiPickerSearchAndClear
139
- clearSearch={clearSearch}
140
- i18n={i18n}
141
- searchValue={searchValue}
142
- />
143
- </EmojiPickerSearchBar>
144
- <EmojiPickerContent
145
- onMouseOver={onMouseOver}
146
- onSelectEmoji={onSelectEmoji}
147
- emojiLibrary={emojiLibrary}
148
- i18n={i18n}
149
- isSearching={isSearching}
150
- refs={refs}
151
- searchResult={searchResult}
152
- settings={settings}
153
- visibleCategories={visibleCategories}
154
- />
155
- <EmojiPickerPreview
156
- emoji={emoji}
157
- hasFound={hasFound}
158
- i18n={i18n}
159
- isSearching={isSearching}
160
- />
161
- </div>
162
- );
163
- }
164
-
165
- const EmojiButton = React.memo(function EmojiButton({
166
- emoji,
167
- index,
168
- onMouseOver,
169
- onSelect,
170
- }: {
171
- emoji: Emoji;
172
- index: number;
173
- onMouseOver: (emoji?: Emoji) => void;
174
- onSelect: (emoji: Emoji) => void;
175
- }) {
176
- return (
177
- <button
178
- className="group relative flex size-9 cursor-pointer items-center justify-center border-none bg-transparent text-2xl leading-none"
179
- onClick={() => onSelect(emoji)}
180
- onMouseEnter={() => onMouseOver(emoji)}
181
- onMouseLeave={() => onMouseOver()}
182
- aria-label={emoji.skins[0].native}
183
- data-index={index}
184
- tabIndex={-1}
185
- type="button"
186
- >
187
- <div
188
- className="absolute inset-0 rounded-full opacity-0 group-hover:opacity-100"
189
- aria-hidden="true"
190
- />
191
- <span
192
- className="relative"
193
- style={{
194
- fontFamily:
195
- '"Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Noto Color Emoji", "Segoe UI Symbol", "Android Emoji", EmojiSymbols',
196
- }}
197
- data-emoji-set="native"
198
- >
199
- {emoji.skins[0].native}
200
- </span>
201
- </button>
202
- );
203
- });
204
-
205
- const RowOfButtons = React.memo(function RowOfButtons({
206
- emojiLibrary,
207
- row,
208
- onMouseOver,
209
- onSelectEmoji,
210
- }: {
211
- row: GridRow;
212
- } & Pick<
213
- UseEmojiPickerType,
214
- 'emojiLibrary' | 'onMouseOver' | 'onSelectEmoji'
215
- >) {
216
- return (
217
- <div key={row.id} className="flex" data-index={row.id}>
218
- {row.elements.map((emojiId, index) => (
219
- <EmojiButton
220
- key={emojiId}
221
- onMouseOver={onMouseOver}
222
- onSelect={onSelectEmoji}
223
- emoji={emojiLibrary.getEmoji(emojiId)}
224
- index={index}
225
- />
226
- ))}
227
- </div>
228
- );
229
- });
230
-
231
- function EmojiPickerContent({
232
- emojiLibrary,
233
- i18n,
234
- isSearching = false,
235
- refs,
236
- searchResult,
237
- settings = EmojiSettings,
238
- visibleCategories,
239
- onMouseOver,
240
- onSelectEmoji,
241
- }: Pick<
242
- UseEmojiPickerType,
243
- | 'emojiLibrary'
244
- | 'i18n'
245
- | 'isSearching'
246
- | 'onMouseOver'
247
- | 'onSelectEmoji'
248
- | 'refs'
249
- | 'searchResult'
250
- | 'settings'
251
- | 'visibleCategories'
252
- >) {
253
- const getRowWidth = settings.perLine.value * settings.buttonSize.value;
254
-
255
- const isCategoryVisible = React.useCallback(
256
- (categoryId: any) =>
257
- visibleCategories.has(categoryId)
258
- ? visibleCategories.get(categoryId)
259
- : false,
260
- [visibleCategories]
261
- );
262
-
263
- const EmojiList = React.useCallback(
264
- () =>
265
- emojiLibrary
266
- .getGrid()
267
- .sections()
268
- .map(({ id: categoryId }) => {
269
- const section = emojiLibrary.getGrid().section(categoryId);
270
- const { buttonSize } = settings;
271
-
272
- return (
273
- <div
274
- key={categoryId}
275
- ref={section.root}
276
- style={{ width: getRowWidth }}
277
- data-id={categoryId}
278
- >
279
- <div className="-top-px sticky z-1 bg-popover/90 p-1 py-2 font-semibold text-sm backdrop-blur-xs">
280
- {i18n.categories[categoryId]}
281
- </div>
282
- <div
283
- className="relative flex flex-wrap"
284
- style={{ height: section.getRows().length * buttonSize.value }}
285
- >
286
- {isCategoryVisible(categoryId) &&
287
- section
288
- .getRows()
289
- .map((row: GridRow) => (
290
- <RowOfButtons
291
- key={row.id}
292
- onMouseOver={onMouseOver}
293
- onSelectEmoji={onSelectEmoji}
294
- emojiLibrary={emojiLibrary}
295
- row={row}
296
- />
297
- ))}
298
- </div>
299
- </div>
300
- );
301
- }),
302
- [
303
- emojiLibrary,
304
- getRowWidth,
305
- i18n.categories,
306
- isCategoryVisible,
307
- onSelectEmoji,
308
- onMouseOver,
309
- settings,
310
- ]
311
- );
312
-
313
- const SearchList = React.useCallback(
314
- () => (
315
- <div style={{ width: getRowWidth }} data-id="search">
316
- <div className="-top-px sticky z-1 bg-popover/90 p-1 py-2 font-semibold text-card-foreground text-sm backdrop-blur-xs">
317
- {i18n.searchResult}
318
- </div>
319
- <div className="relative flex flex-wrap">
320
- {searchResult.map((emoji: Emoji, index: number) => (
321
- <EmojiButton
322
- key={emoji.id}
323
- onMouseOver={onMouseOver}
324
- onSelect={onSelectEmoji}
325
- emoji={emojiLibrary.getEmoji(emoji.id)}
326
- index={index}
327
- />
328
- ))}
329
- </div>
330
- </div>
331
- ),
332
- [
333
- emojiLibrary,
334
- getRowWidth,
335
- i18n.searchResult,
336
- searchResult,
337
- onSelectEmoji,
338
- onMouseOver,
339
- ]
340
- );
341
-
342
- return (
343
- <div
344
- ref={refs.current.contentRoot}
345
- className={cn(
346
- 'h-full min-h-[50%] overflow-y-auto overflow-x-hidden px-2',
347
- '[&::-webkit-scrollbar]:w-4',
348
- '[&::-webkit-scrollbar-button]:hidden [&::-webkit-scrollbar-button]:size-0',
349
- '[&::-webkit-scrollbar-thumb]:min-h-11 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-muted [&::-webkit-scrollbar-thumb]:hover:bg-muted-foreground/25',
350
- '[&::-webkit-scrollbar-thumb]:border-4 [&::-webkit-scrollbar-thumb]:border-popover [&::-webkit-scrollbar-thumb]:border-solid [&::-webkit-scrollbar-thumb]:bg-clip-padding'
351
- )}
352
- data-id="scroll"
353
- >
354
- <div ref={refs.current.content} className="h-full">
355
- {isSearching ? SearchList() : EmojiList()}
356
- </div>
357
- </div>
358
- );
359
- }
360
-
361
- function EmojiPickerSearchBar({
362
- children,
363
- i18n,
364
- searchValue,
365
- setSearch,
366
- }: {
367
- children: React.ReactNode;
368
- } & Pick<UseEmojiPickerType, 'i18n' | 'searchValue' | 'setSearch'>) {
369
- return (
370
- <div className="flex items-center px-2">
371
- <div className="relative flex grow items-center">
372
- <input
373
- className="block w-full appearance-none rounded-full border-0 bg-muted px-10 py-2 text-sm outline-none placeholder:text-muted-foreground focus-visible:outline-none"
374
- value={searchValue}
375
- onChange={(event) => setSearch(event.target.value)}
376
- placeholder={i18n.search}
377
- aria-label="Search"
378
- autoComplete="off"
379
- type="text"
380
- autoFocus
381
- />
382
- {children}
383
- </div>
384
- </div>
385
- );
386
- }
387
-
388
- function EmojiPickerSearchAndClear({
389
- clearSearch,
390
- i18n,
391
- searchValue,
392
- }: Pick<UseEmojiPickerType, 'clearSearch' | 'i18n' | 'searchValue'>) {
393
- return (
394
- <div className="flex items-center text-foreground">
395
- <div
396
- className={cn(
397
- '-translate-y-1/2 absolute top-1/2 left-2.5 z-10 flex size-5 items-center justify-center text-foreground'
398
- )}
399
- >
400
- {emojiSearchIcons.loupe}
401
- </div>
402
- {searchValue && (
403
- <Button
404
- size="icon"
405
- variant="ghost"
406
- className={cn(
407
- '-translate-y-1/2 absolute top-1/2 right-0.5 flex size-8 cursor-pointer items-center justify-center rounded-full border-none bg-transparent text-popover-foreground hover:bg-transparent'
408
- )}
409
- onClick={clearSearch}
410
- title={i18n.clear}
411
- aria-label="Clear"
412
- type="button"
413
- >
414
- {emojiSearchIcons.delete}
415
- </Button>
416
- )}
417
- </div>
418
- );
419
- }
420
-
421
- function EmojiPreview({ emoji }: Pick<UseEmojiPickerType, 'emoji'>) {
422
- return (
423
- <div className="flex h-14 max-h-14 min-h-14 items-center border-muted border-t p-2">
424
- <div className="flex items-center justify-center text-2xl">
425
- {emoji?.skins[0].native}
426
- </div>
427
- <div className="overflow-hidden pl-2">
428
- <div className="truncate font-semibold text-sm">{emoji?.name}</div>
429
- <div className="truncate text-sm">{`:${emoji?.id}:`}</div>
430
- </div>
431
- </div>
432
- );
433
- }
434
-
435
- function NoEmoji({ i18n }: Pick<UseEmojiPickerType, 'i18n'>) {
436
- return (
437
- <div className="flex h-14 max-h-14 min-h-14 items-center border-muted border-t p-2">
438
- <div className="flex items-center justify-center text-2xl">😢</div>
439
- <div className="overflow-hidden pl-2">
440
- <div className="truncate font-bold text-sm">
441
- {i18n.searchNoResultsTitle}
442
- </div>
443
- <div className="truncate text-sm">{i18n.searchNoResultsSubtitle}</div>
444
- </div>
445
- </div>
446
- );
447
- }
448
-
449
- function PickAnEmoji({ i18n }: Pick<UseEmojiPickerType, 'i18n'>) {
450
- return (
451
- <div className="flex h-14 max-h-14 min-h-14 items-center border-muted border-t p-2">
452
- <div className="flex items-center justify-center text-2xl">☝️</div>
453
- <div className="overflow-hidden pl-2">
454
- <div className="truncate font-semibold text-sm">{i18n.pick}</div>
455
- </div>
456
- </div>
457
- );
458
- }
459
-
460
- function EmojiPickerPreview({
461
- emoji,
462
- hasFound = true,
463
- i18n,
464
- isSearching = false,
465
- ...props
466
- }: Pick<UseEmojiPickerType, 'emoji' | 'hasFound' | 'i18n' | 'isSearching'>) {
467
- const showPickEmoji = !emoji && (!isSearching || hasFound);
468
- const showNoEmoji = isSearching && !hasFound;
469
- const showPreview = emoji && !showNoEmoji && !showNoEmoji;
470
-
471
- return (
472
- <>
473
- {showPreview && <EmojiPreview emoji={emoji} {...props} />}
474
- {showPickEmoji && <PickAnEmoji i18n={i18n} {...props} />}
475
- {showNoEmoji && <NoEmoji i18n={i18n} {...props} />}
476
- </>
477
- );
478
- }
479
-
480
- function EmojiPickerNavigation({
481
- emojiLibrary,
482
- focusedCategory,
483
- i18n,
484
- icons,
485
- onClick,
486
- }: {
487
- onClick: (id: EmojiCategoryList) => void;
488
- } & Pick<
489
- UseEmojiPickerType,
490
- 'emojiLibrary' | 'focusedCategory' | 'i18n' | 'icons'
491
- >) {
492
- return (
493
- <TooltipProvider delayDuration={500}>
494
- <nav
495
- id="emoji-nav"
496
- className="mb-2.5 border-0 border-b border-b-border border-solid p-1.5"
497
- >
498
- <div className="relative flex items-center justify-evenly">
499
- {emojiLibrary
500
- .getGrid()
501
- .sections()
502
- .map(({ id }) => (
503
- <Tooltip key={id}>
504
- <TooltipTrigger asChild>
505
- <Button
506
- size="sm"
507
- variant="ghost"
508
- className={cn(
509
- 'h-fit rounded-full fill-current p-1.5 text-muted-foreground hover:bg-muted hover:text-muted-foreground',
510
- id === focusedCategory &&
511
- 'pointer-events-none bg-accent fill-current text-accent-foreground'
512
- )}
513
- onClick={() => {
514
- onClick(id);
515
- }}
516
- aria-label={i18n.categories[id]}
517
- type="button"
518
- >
519
- <span className="inline-flex size-5 items-center justify-center">
520
- {icons.categories[id].outline}
521
- </span>
522
- </Button>
523
- </TooltipTrigger>
524
- <TooltipContent side="bottom">
525
- {i18n.categories[id]}
526
- </TooltipContent>
527
- </Tooltip>
528
- ))}
529
- </div>
530
- </nav>
531
- </TooltipProvider>
532
- );
533
- }
534
-
535
- const emojiCategoryIcons: Record<
536
- EmojiCategoryList,
537
- {
538
- outline: React.ReactElement;
539
- solid: React.ReactElement; // Needed to add another solid variant - outline will be used for now
540
- }
541
- > = {
542
- activity: {
543
- outline: (
544
- <svg
545
- className="size-full"
546
- fill="none"
547
- stroke="currentColor"
548
- strokeLinecap="round"
549
- strokeLinejoin="round"
550
- strokeWidth="2"
551
- viewBox="0 0 24 24"
552
- xmlns="http://www.w3.org/2000/svg"
553
- >
554
- <circle cx="12" cy="12" r="10" />
555
- <path d="M2.1 13.4A10.1 10.1 0 0 0 13.4 2.1" />
556
- <path d="m5 4.9 14 14.2" />
557
- <path d="M21.9 10.6a10.1 10.1 0 0 0-11.3 11.3" />
558
- </svg>
559
- ),
560
- solid: (
561
- <svg
562
- className="size-full"
563
- fill="none"
564
- stroke="currentColor"
565
- strokeLinecap="round"
566
- strokeLinejoin="round"
567
- strokeWidth="2"
568
- viewBox="0 0 24 24"
569
- xmlns="http://www.w3.org/2000/svg"
570
- >
571
- <circle cx="12" cy="12" r="10" />
572
- <path d="M2.1 13.4A10.1 10.1 0 0 0 13.4 2.1" />
573
- <path d="m5 4.9 14 14.2" />
574
- <path d="M21.9 10.6a10.1 10.1 0 0 0-11.3 11.3" />
575
- </svg>
576
- ),
577
- },
578
-
579
- custom: {
580
- outline: <StarIcon className="size-full" />,
581
- solid: <StarIcon className="size-full" />,
582
- },
583
-
584
- flags: {
585
- outline: <FlagIcon className="size-full" />,
586
- solid: <FlagIcon className="size-full" />,
587
- },
588
-
589
- foods: {
590
- outline: <AppleIcon className="size-full" />,
591
- solid: <AppleIcon className="size-full" />,
592
- },
593
-
594
- frequent: {
595
- outline: <ClockIcon className="size-full" />,
596
- solid: <ClockIcon className="size-full" />,
597
- },
598
-
599
- nature: {
600
- outline: <LeafIcon className="size-full" />,
601
- solid: <LeafIcon className="size-full" />,
602
- },
603
-
604
- objects: {
605
- outline: <LightbulbIcon className="size-full" />,
606
- solid: <LightbulbIcon className="size-full" />,
607
- },
608
-
609
- people: {
610
- outline: <SmileIcon className="size-full" />,
611
- solid: <SmileIcon className="size-full" />,
612
- },
613
-
614
- places: {
615
- outline: <CompassIcon className="size-full" />,
616
- solid: <CompassIcon className="size-full" />,
617
- },
618
-
619
- symbols: {
620
- outline: <MusicIcon className="size-full" />,
621
- solid: <MusicIcon className="size-full" />,
622
- },
623
- };
624
-
625
- const emojiSearchIcons = {
626
- delete: <XIcon className="size-4 text-current" />,
627
- loupe: <SearchIcon className="size-4 text-current" />,
628
- };