@liveblocks/react-ui 2.14.0 → 2.15.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.
- package/dist/_private/index.d.mts +24 -22
- package/dist/_private/index.d.ts +24 -22
- package/dist/_private/index.js +1 -0
- package/dist/_private/index.js.map +1 -1
- package/dist/_private/index.mjs +1 -0
- package/dist/_private/index.mjs.map +1 -1
- package/dist/components/Comment.js +358 -256
- package/dist/components/Comment.js.map +1 -1
- package/dist/components/Comment.mjs +334 -232
- package/dist/components/Comment.mjs.map +1 -1
- package/dist/components/Composer.js +308 -225
- package/dist/components/Composer.js.map +1 -1
- package/dist/components/Composer.mjs +288 -206
- package/dist/components/Composer.mjs.map +1 -1
- package/dist/components/HistoryVersionSummary.js +28 -32
- package/dist/components/HistoryVersionSummary.js.map +1 -1
- package/dist/components/HistoryVersionSummary.mjs +27 -31
- package/dist/components/HistoryVersionSummary.mjs.map +1 -1
- package/dist/components/HistoryVersionSummaryList.js +11 -9
- package/dist/components/HistoryVersionSummaryList.js.map +1 -1
- package/dist/components/HistoryVersionSummaryList.mjs +10 -8
- package/dist/components/HistoryVersionSummaryList.mjs.map +1 -1
- package/dist/components/InboxNotification.js +202 -143
- package/dist/components/InboxNotification.js.map +1 -1
- package/dist/components/InboxNotification.mjs +180 -121
- package/dist/components/InboxNotification.mjs.map +1 -1
- package/dist/components/InboxNotificationList.js +19 -14
- package/dist/components/InboxNotificationList.js.map +1 -1
- package/dist/components/InboxNotificationList.mjs +17 -12
- package/dist/components/InboxNotificationList.mjs.map +1 -1
- package/dist/components/Thread.js +104 -86
- package/dist/components/Thread.js.map +1 -1
- package/dist/components/Thread.mjs +93 -75
- package/dist/components/Thread.mjs.map +1 -1
- package/dist/components/internal/Attachment.js +161 -113
- package/dist/components/internal/Attachment.js.map +1 -1
- package/dist/components/internal/Attachment.mjs +150 -102
- package/dist/components/internal/Attachment.mjs.map +1 -1
- package/dist/components/internal/Attribution.js +15 -13
- package/dist/components/internal/Attribution.js.map +1 -1
- package/dist/components/internal/Attribution.mjs +15 -13
- package/dist/components/internal/Attribution.mjs.map +1 -1
- package/dist/components/internal/Avatar.js +27 -20
- package/dist/components/internal/Avatar.js.map +1 -1
- package/dist/components/internal/Avatar.mjs +23 -16
- package/dist/components/internal/Avatar.mjs.map +1 -1
- package/dist/components/internal/Button.js +5 -4
- package/dist/components/internal/Button.js.map +1 -1
- package/dist/components/internal/Button.mjs +4 -3
- package/dist/components/internal/Button.mjs.map +1 -1
- package/dist/components/internal/Dropdown.js +27 -19
- package/dist/components/internal/Dropdown.js.map +1 -1
- package/dist/components/internal/Dropdown.mjs +26 -18
- package/dist/components/internal/Dropdown.mjs.map +1 -1
- package/dist/components/internal/Emoji.js +4 -3
- package/dist/components/internal/Emoji.js.map +1 -1
- package/dist/components/internal/Emoji.mjs +3 -2
- package/dist/components/internal/Emoji.mjs.map +1 -1
- package/dist/components/internal/EmojiPicker.js +96 -72
- package/dist/components/internal/EmojiPicker.js.map +1 -1
- package/dist/components/internal/EmojiPicker.mjs +90 -66
- package/dist/components/internal/EmojiPicker.mjs.map +1 -1
- package/dist/components/internal/Icon.js +5 -4
- package/dist/components/internal/Icon.js.map +1 -1
- package/dist/components/internal/Icon.mjs +5 -4
- package/dist/components/internal/Icon.mjs.map +1 -1
- package/dist/components/internal/InboxNotificationThread.js +53 -38
- package/dist/components/internal/InboxNotificationThread.js.map +1 -1
- package/dist/components/internal/InboxNotificationThread.mjs +53 -38
- package/dist/components/internal/InboxNotificationThread.mjs.map +1 -1
- package/dist/components/internal/List.js +8 -6
- package/dist/components/internal/List.js.map +1 -1
- package/dist/components/internal/List.mjs +6 -4
- package/dist/components/internal/List.mjs.map +1 -1
- package/dist/components/internal/Room.js +8 -6
- package/dist/components/internal/Room.js.map +1 -1
- package/dist/components/internal/Room.mjs +7 -5
- package/dist/components/internal/Room.mjs.map +1 -1
- package/dist/components/internal/Tooltip.js +49 -33
- package/dist/components/internal/Tooltip.js.map +1 -1
- package/dist/components/internal/Tooltip.mjs +46 -30
- package/dist/components/internal/Tooltip.mjs.map +1 -1
- package/dist/components/internal/User.js +8 -6
- package/dist/components/internal/User.js.map +1 -1
- package/dist/components/internal/User.mjs +7 -5
- package/dist/components/internal/User.mjs.map +1 -1
- package/dist/components.js +12 -29
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +6 -5
- package/dist/components.mjs.map +1 -1
- package/dist/config.js +16 -12
- package/dist/config.js.map +1 -1
- package/dist/config.mjs +13 -9
- package/dist/config.mjs.map +1 -1
- package/dist/icons/ArrowDown.js +7 -6
- package/dist/icons/ArrowDown.js.map +1 -1
- package/dist/icons/ArrowDown.mjs +7 -6
- package/dist/icons/ArrowDown.mjs.map +1 -1
- package/dist/icons/ArrowUp.js +7 -6
- package/dist/icons/ArrowUp.js.map +1 -1
- package/dist/icons/ArrowUp.mjs +7 -6
- package/dist/icons/ArrowUp.mjs.map +1 -1
- package/dist/icons/Attachment.js +7 -6
- package/dist/icons/Attachment.js.map +1 -1
- package/dist/icons/Attachment.mjs +7 -6
- package/dist/icons/Attachment.mjs.map +1 -1
- package/dist/icons/Bold.js +7 -6
- package/dist/icons/Bold.js.map +1 -1
- package/dist/icons/Bold.mjs +7 -6
- package/dist/icons/Bold.mjs.map +1 -1
- package/dist/icons/Check.js +7 -6
- package/dist/icons/Check.js.map +1 -1
- package/dist/icons/Check.mjs +7 -6
- package/dist/icons/Check.mjs.map +1 -1
- package/dist/icons/Code.js +7 -6
- package/dist/icons/Code.js.map +1 -1
- package/dist/icons/Code.mjs +7 -6
- package/dist/icons/Code.mjs.map +1 -1
- package/dist/icons/Cross.js +12 -8
- package/dist/icons/Cross.js.map +1 -1
- package/dist/icons/Cross.mjs +12 -8
- package/dist/icons/Cross.mjs.map +1 -1
- package/dist/icons/Delete.js +7 -6
- package/dist/icons/Delete.js.map +1 -1
- package/dist/icons/Delete.mjs +7 -6
- package/dist/icons/Delete.mjs.map +1 -1
- package/dist/icons/Edit.js +7 -6
- package/dist/icons/Edit.js.map +1 -1
- package/dist/icons/Edit.mjs +7 -6
- package/dist/icons/Edit.mjs.map +1 -1
- package/dist/icons/Ellipsis.js +21 -16
- package/dist/icons/Ellipsis.js.map +1 -1
- package/dist/icons/Ellipsis.mjs +21 -16
- package/dist/icons/Ellipsis.mjs.map +1 -1
- package/dist/icons/Emoji.js +25 -18
- package/dist/icons/Emoji.js.map +1 -1
- package/dist/icons/Emoji.mjs +25 -18
- package/dist/icons/Emoji.mjs.map +1 -1
- package/dist/icons/EmojiAdd.js +28 -20
- package/dist/icons/EmojiAdd.js.map +1 -1
- package/dist/icons/EmojiAdd.mjs +28 -20
- package/dist/icons/EmojiAdd.mjs.map +1 -1
- package/dist/icons/Italic.js +7 -6
- package/dist/icons/Italic.js.map +1 -1
- package/dist/icons/Italic.mjs +7 -6
- package/dist/icons/Italic.mjs.map +1 -1
- package/dist/icons/Mention.js +12 -8
- package/dist/icons/Mention.js.map +1 -1
- package/dist/icons/Mention.mjs +12 -8
- package/dist/icons/Mention.mjs.map +1 -1
- package/dist/icons/Resolve.js +14 -10
- package/dist/icons/Resolve.js.map +1 -1
- package/dist/icons/Resolve.mjs +14 -10
- package/dist/icons/Resolve.mjs.map +1 -1
- package/dist/icons/Resolved.js +16 -12
- package/dist/icons/Resolved.js.map +1 -1
- package/dist/icons/Resolved.mjs +16 -12
- package/dist/icons/Resolved.mjs.map +1 -1
- package/dist/icons/Restore.js +12 -8
- package/dist/icons/Restore.js.map +1 -1
- package/dist/icons/Restore.mjs +12 -8
- package/dist/icons/Restore.mjs.map +1 -1
- package/dist/icons/Search.js +7 -6
- package/dist/icons/Search.js.map +1 -1
- package/dist/icons/Search.mjs +7 -6
- package/dist/icons/Search.mjs.map +1 -1
- package/dist/icons/Send.js +7 -6
- package/dist/icons/Send.js.map +1 -1
- package/dist/icons/Send.mjs +7 -6
- package/dist/icons/Send.mjs.map +1 -1
- package/dist/icons/Spinner.js +8 -7
- package/dist/icons/Spinner.js.map +1 -1
- package/dist/icons/Spinner.mjs +8 -7
- package/dist/icons/Spinner.mjs.map +1 -1
- package/dist/icons/Strikethrough.js +7 -6
- package/dist/icons/Strikethrough.js.map +1 -1
- package/dist/icons/Strikethrough.mjs +7 -6
- package/dist/icons/Strikethrough.mjs.map +1 -1
- package/dist/icons/Warning.js +14 -10
- package/dist/icons/Warning.js.map +1 -1
- package/dist/icons/Warning.mjs +14 -10
- package/dist/icons/Warning.mjs.map +1 -1
- package/dist/icons/index.js +42 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/icons/index.mjs +19 -0
- package/dist/icons/index.mjs.map +1 -0
- package/dist/index.d.mts +14 -12
- package/dist/index.d.ts +14 -12
- package/dist/overrides.js +65 -36
- package/dist/overrides.js.map +1 -1
- package/dist/overrides.mjs +59 -12
- package/dist/overrides.mjs.map +1 -1
- package/dist/primitives/Comment/index.js +75 -66
- package/dist/primitives/Comment/index.js.map +1 -1
- package/dist/primitives/Comment/index.mjs +71 -62
- package/dist/primitives/Comment/index.mjs.map +1 -1
- package/dist/primitives/Composer/contexts.js +11 -11
- package/dist/primitives/Composer/index.js +343 -284
- package/dist/primitives/Composer/index.js.map +1 -1
- package/dist/primitives/Composer/index.mjs +262 -203
- package/dist/primitives/Composer/index.mjs.map +1 -1
- package/dist/primitives/Composer/utils.js +20 -21
- package/dist/primitives/Composer/utils.js.map +1 -1
- package/dist/primitives/Composer/utils.mjs +4 -5
- package/dist/primitives/Composer/utils.mjs.map +1 -1
- package/dist/primitives/EmojiPicker/contexts.js +3 -3
- package/dist/primitives/EmojiPicker/index.js +160 -142
- package/dist/primitives/EmojiPicker/index.js.map +1 -1
- package/dist/primitives/EmojiPicker/index.mjs +122 -104
- package/dist/primitives/EmojiPicker/index.mjs.map +1 -1
- package/dist/primitives/FileSize.js +9 -7
- package/dist/primitives/FileSize.js.map +1 -1
- package/dist/primitives/FileSize.mjs +7 -5
- package/dist/primitives/FileSize.mjs.map +1 -1
- package/dist/primitives/Timestamp.js +12 -10
- package/dist/primitives/Timestamp.js.map +1 -1
- package/dist/primitives/Timestamp.mjs +7 -5
- package/dist/primitives/Timestamp.mjs.map +1 -1
- package/dist/primitives/index.d.mts +24 -23
- package/dist/primitives/index.d.ts +24 -23
- package/dist/primitives/internal/Emoji.js +7 -5
- package/dist/primitives/internal/Emoji.js.map +1 -1
- package/dist/primitives/internal/Emoji.mjs +6 -4
- package/dist/primitives/internal/Emoji.mjs.map +1 -1
- package/dist/shared.js +2 -7
- package/dist/shared.js.map +1 -1
- package/dist/shared.mjs +2 -7
- package/dist/shared.mjs.map +1 -1
- package/dist/slate/plugins/auto-links.mjs +1 -1
- package/dist/slate/plugins/custom-links.mjs +1 -1
- package/dist/slate/plugins/mentions.mjs +1 -1
- package/dist/utils/Persist.js +19 -18
- package/dist/utils/Persist.js.map +1 -1
- package/dist/utils/Persist.mjs +7 -6
- package/dist/utils/Persist.mjs.map +1 -1
- package/dist/utils/Portal.js +5 -4
- package/dist/utils/Portal.js.map +1 -1
- package/dist/utils/Portal.mjs +4 -3
- package/dist/utils/Portal.mjs.map +1 -1
- package/dist/utils/use-controllable-state.js +5 -5
- package/dist/utils/use-index.js +7 -7
- package/dist/utils/use-initial.js +2 -2
- package/dist/utils/use-interval.js +4 -4
- package/dist/utils/use-latest.js +3 -3
- package/dist/utils/use-observable.js +2 -2
- package/dist/utils/use-refs.js +2 -2
- package/dist/utils/use-rerender.js +2 -2
- package/dist/utils/use-visible.js +24 -2
- package/dist/utils/use-visible.js.map +1 -1
- package/dist/utils/use-visible.mjs +23 -2
- package/dist/utils/use-visible.mjs.map +1 -1
- package/dist/utils/use-window-focus.js +2 -2
- package/dist/utils/use-window-focus.js.map +1 -1
- package/dist/utils/use-window-focus.mjs +1 -1
- package/dist/utils/use-window-focus.mjs.map +1 -1
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/dist/version.mjs +2 -2
- package/dist/version.mjs.map +1 -1
- package/package.json +10 -25
- package/dist/utils/use-id.js +0 -29
- package/dist/utils/use-id.js.map +0 -1
- package/dist/utils/use-id.mjs +0 -27
- package/dist/utils/use-id.mjs.map +0 -1
- package/dist/utils/use-layout-effect.js +0 -8
- package/dist/utils/use-layout-effect.js.map +0 -1
- package/dist/utils/use-layout-effect.mjs +0 -6
- package/dist/utils/use-layout-effect.mjs.map +0 -1
- package/dist/utils/use-transition.js +0 -16
- package/dist/utils/use-transition.js.map +0 -1
- package/dist/utils/use-transition.mjs +0 -14
- package/dist/utils/use-transition.mjs.map +0 -1
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
'use client';
|
|
2
1
|
'use strict';
|
|
3
2
|
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var reactSlot = require('@radix-ui/react-slot');
|
|
5
|
-
var
|
|
5
|
+
var react = require('react');
|
|
6
6
|
var reactVirtuoso = require('react-virtuoso');
|
|
7
7
|
var isKey = require('../../utils/is-key.js');
|
|
8
8
|
var requestIdleCallback = require('../../utils/request-idle-callback.js');
|
|
9
|
-
var useLayoutEffect = require('../../utils/use-layout-effect.js');
|
|
10
|
-
var useTransition = require('../../utils/use-transition.js');
|
|
11
9
|
var visuallyHidden = require('../../utils/visually-hidden.js');
|
|
12
10
|
var Emoji = require('../internal/Emoji.js');
|
|
13
11
|
var contexts = require('./contexts.js');
|
|
14
12
|
var utils = require('./utils.js');
|
|
15
13
|
|
|
14
|
+
"use client";
|
|
16
15
|
const DEFAULT_COLUMNS = 10;
|
|
17
16
|
const DEFAULT_LOCALE = "en";
|
|
18
17
|
const LOADING_MINIMUM_TIMEOUT = 100;
|
|
@@ -25,15 +24,15 @@ function EmojiPickerRoot({
|
|
|
25
24
|
onEmojiSelect,
|
|
26
25
|
children
|
|
27
26
|
}) {
|
|
28
|
-
const emojiData =
|
|
29
|
-
const search =
|
|
30
|
-
const [, startEmojisTransition] =
|
|
31
|
-
const [data, setData] =
|
|
32
|
-
const [error, setError] =
|
|
33
|
-
const [selectedColumnIndex, setSelectedColumnIndex] =
|
|
34
|
-
const [selectedRowIndex, setSelectedRowIndex] =
|
|
35
|
-
const [interaction, setInteraction] =
|
|
36
|
-
const selectCurrentEmoji =
|
|
27
|
+
const emojiData = react.useRef();
|
|
28
|
+
const search = react.useRef("");
|
|
29
|
+
const [, startEmojisTransition] = react.useTransition();
|
|
30
|
+
const [data, setData] = react.useState();
|
|
31
|
+
const [error, setError] = react.useState();
|
|
32
|
+
const [selectedColumnIndex, setSelectedColumnIndex] = react.useState(0);
|
|
33
|
+
const [selectedRowIndex, setSelectedRowIndex] = react.useState(0);
|
|
34
|
+
const [interaction, setInteraction] = react.useState("none");
|
|
35
|
+
const selectCurrentEmoji = react.useCallback(() => {
|
|
37
36
|
if (onEmojiSelect) {
|
|
38
37
|
const emoji = data?.rows[selectedRowIndex]?.[selectedColumnIndex];
|
|
39
38
|
if (emoji) {
|
|
@@ -41,11 +40,11 @@ function EmojiPickerRoot({
|
|
|
41
40
|
}
|
|
42
41
|
}
|
|
43
42
|
}, [data?.rows, onEmojiSelect, selectedColumnIndex, selectedRowIndex]);
|
|
44
|
-
const resetSelection =
|
|
43
|
+
const resetSelection = react.useCallback(() => {
|
|
45
44
|
setSelectedColumnIndex(0);
|
|
46
45
|
setSelectedRowIndex(0);
|
|
47
46
|
}, []);
|
|
48
|
-
const setPointerSelection =
|
|
47
|
+
const setPointerSelection = react.useCallback(
|
|
49
48
|
(columnIndex, rowIndex) => {
|
|
50
49
|
setInteraction("pointer");
|
|
51
50
|
setSelectedColumnIndex(columnIndex);
|
|
@@ -53,7 +52,7 @@ function EmojiPickerRoot({
|
|
|
53
52
|
},
|
|
54
53
|
[]
|
|
55
54
|
);
|
|
56
|
-
const moveSelection =
|
|
55
|
+
const moveSelection = react.useCallback(
|
|
57
56
|
(direction, event) => {
|
|
58
57
|
if (!data) {
|
|
59
58
|
return;
|
|
@@ -119,7 +118,7 @@ function EmojiPickerRoot({
|
|
|
119
118
|
},
|
|
120
119
|
[data, interaction, selectedColumnIndex, selectedRowIndex]
|
|
121
120
|
);
|
|
122
|
-
const updateEmojis =
|
|
121
|
+
const updateEmojis = react.useCallback(() => {
|
|
123
122
|
if (!emojiData.current) {
|
|
124
123
|
return;
|
|
125
124
|
}
|
|
@@ -141,14 +140,14 @@ function EmojiPickerRoot({
|
|
|
141
140
|
resetSelection();
|
|
142
141
|
});
|
|
143
142
|
}, [columns, resetSelection]);
|
|
144
|
-
const handleSearch =
|
|
143
|
+
const handleSearch = react.useCallback(
|
|
145
144
|
(value) => {
|
|
146
145
|
search.current = value;
|
|
147
146
|
updateEmojis();
|
|
148
147
|
},
|
|
149
148
|
[updateEmojis]
|
|
150
149
|
);
|
|
151
|
-
const initializeEmojiData =
|
|
150
|
+
const initializeEmojiData = react.useCallback(
|
|
152
151
|
async (locale2) => {
|
|
153
152
|
try {
|
|
154
153
|
emojiData.current = await utils.getEmojiData(locale2);
|
|
@@ -159,7 +158,7 @@ function EmojiPickerRoot({
|
|
|
159
158
|
},
|
|
160
159
|
[updateEmojis]
|
|
161
160
|
);
|
|
162
|
-
|
|
161
|
+
react.useEffect(() => {
|
|
163
162
|
let idleCallbackId;
|
|
164
163
|
const timeoutId = setTimeout(() => {
|
|
165
164
|
idleCallbackId = requestIdleCallback.requestIdleCallback(() => {
|
|
@@ -171,12 +170,12 @@ function EmojiPickerRoot({
|
|
|
171
170
|
requestIdleCallback.cancelIdleCallback(idleCallbackId);
|
|
172
171
|
};
|
|
173
172
|
}, [locale]);
|
|
174
|
-
|
|
173
|
+
react.useEffect(() => {
|
|
175
174
|
if (interaction === "none") {
|
|
176
175
|
resetSelection();
|
|
177
176
|
}
|
|
178
177
|
}, [interaction]);
|
|
179
|
-
return /* @__PURE__ */
|
|
178
|
+
return /* @__PURE__ */ jsxRuntime.jsx(contexts.EmojiPickerContext.Provider, {
|
|
180
179
|
value: {
|
|
181
180
|
data,
|
|
182
181
|
error,
|
|
@@ -191,10 +190,11 @@ function EmojiPickerRoot({
|
|
|
191
190
|
setPointerSelection,
|
|
192
191
|
interaction,
|
|
193
192
|
setInteraction
|
|
194
|
-
}
|
|
195
|
-
|
|
193
|
+
},
|
|
194
|
+
children
|
|
195
|
+
});
|
|
196
196
|
}
|
|
197
|
-
const EmojiPickerSearch =
|
|
197
|
+
const EmojiPickerSearch = react.forwardRef(
|
|
198
198
|
({ asChild, value, defaultValue, onChange, ...props }, forwardedRef) => {
|
|
199
199
|
const Component = asChild ? reactSlot.Slot : "input";
|
|
200
200
|
const {
|
|
@@ -204,7 +204,7 @@ const EmojiPickerSearch = React.forwardRef(
|
|
|
204
204
|
interaction,
|
|
205
205
|
setInteraction
|
|
206
206
|
} = contexts.useEmojiPicker();
|
|
207
|
-
const handleChange =
|
|
207
|
+
const handleChange = react.useCallback(
|
|
208
208
|
(event) => {
|
|
209
209
|
onChange?.(event);
|
|
210
210
|
if (event.isDefaultPrevented()) {
|
|
@@ -216,7 +216,7 @@ const EmojiPickerSearch = React.forwardRef(
|
|
|
216
216
|
},
|
|
217
217
|
[onChange, onSearch, setInteraction]
|
|
218
218
|
);
|
|
219
|
-
const handleKeyDown =
|
|
219
|
+
const handleKeyDown = react.useCallback(
|
|
220
220
|
(event) => {
|
|
221
221
|
if (event.isDefaultPrevented()) {
|
|
222
222
|
return;
|
|
@@ -238,12 +238,12 @@ const EmojiPickerSearch = React.forwardRef(
|
|
|
238
238
|
},
|
|
239
239
|
[interaction, moveSelection, selectCurrentEmoji]
|
|
240
240
|
);
|
|
241
|
-
|
|
241
|
+
react.useEffect(() => {
|
|
242
242
|
onSearch(
|
|
243
243
|
value ? String(value) : defaultValue ? String(defaultValue) : ""
|
|
244
244
|
);
|
|
245
245
|
}, []);
|
|
246
|
-
return /* @__PURE__ */
|
|
246
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Component, {
|
|
247
247
|
type: "search",
|
|
248
248
|
value,
|
|
249
249
|
defaultValue,
|
|
@@ -255,27 +255,30 @@ const EmojiPickerSearch = React.forwardRef(
|
|
|
255
255
|
}
|
|
256
256
|
);
|
|
257
257
|
const defaultContentComponents = {
|
|
258
|
-
CategoryHeader: ({ category, ...props }) => /* @__PURE__ */
|
|
259
|
-
...props
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
258
|
+
CategoryHeader: ({ category, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
259
|
+
...props,
|
|
260
|
+
children: category
|
|
261
|
+
}),
|
|
262
|
+
Row: ({ children, attributes, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
263
|
+
...props,
|
|
264
|
+
children
|
|
265
|
+
}),
|
|
266
|
+
Emoji: ({ emoji, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("button", {
|
|
267
|
+
...props,
|
|
268
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Emoji.Emoji, {
|
|
269
|
+
emoji
|
|
270
|
+
})
|
|
271
|
+
}),
|
|
272
|
+
Loading: (props) => /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
270
273
|
...props
|
|
271
274
|
}),
|
|
272
|
-
Empty: (props) => /* @__PURE__ */
|
|
275
|
+
Empty: (props) => /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
273
276
|
...props
|
|
274
277
|
}),
|
|
275
|
-
Grid: (props) => /* @__PURE__ */
|
|
278
|
+
Grid: (props) => /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
276
279
|
...props
|
|
277
280
|
}),
|
|
278
|
-
Error: ({ error, ...props }) => /* @__PURE__ */
|
|
281
|
+
Error: ({ error, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
279
282
|
...props
|
|
280
283
|
})
|
|
281
284
|
};
|
|
@@ -284,33 +287,35 @@ const placeholderRowAttributes = {
|
|
|
284
287
|
categoryRowIndex: -1,
|
|
285
288
|
categoryRowsCount: 0
|
|
286
289
|
};
|
|
287
|
-
const VirtuosoScroller =
|
|
290
|
+
const VirtuosoScroller = react.forwardRef(
|
|
288
291
|
({ children, ...props }, forwardedRef) => {
|
|
289
|
-
return /* @__PURE__ */
|
|
292
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
290
293
|
...props,
|
|
291
294
|
tabIndex: -1,
|
|
292
295
|
"data-testid": void 0,
|
|
293
|
-
ref: forwardedRef
|
|
294
|
-
|
|
296
|
+
ref: forwardedRef,
|
|
297
|
+
children
|
|
298
|
+
});
|
|
295
299
|
}
|
|
296
300
|
);
|
|
297
|
-
const VirtuosoTopList =
|
|
301
|
+
const VirtuosoTopList = react.forwardRef(
|
|
298
302
|
({ children, ...props }, forwardedRef) => {
|
|
299
|
-
return /* @__PURE__ */
|
|
303
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
300
304
|
...props,
|
|
301
305
|
"data-testid": void 0,
|
|
302
|
-
ref: forwardedRef
|
|
303
|
-
|
|
306
|
+
ref: forwardedRef,
|
|
307
|
+
children
|
|
308
|
+
});
|
|
304
309
|
}
|
|
305
310
|
);
|
|
306
|
-
const EmojiPickerContent =
|
|
311
|
+
const EmojiPickerContent = react.forwardRef(
|
|
307
312
|
({ components, asChild, ...props }, forwardedRef) => {
|
|
308
313
|
const Component = asChild ? reactSlot.Slot : "div";
|
|
309
|
-
const virtuosoRef =
|
|
310
|
-
const placeholderContainerRef =
|
|
311
|
-
const rowScrollMarginTopRef =
|
|
312
|
-
const rowScrollMarginBottomRef =
|
|
313
|
-
const categoryHeaderHeightRef =
|
|
314
|
+
const virtuosoRef = react.useRef(null);
|
|
315
|
+
const placeholderContainerRef = react.useRef(null);
|
|
316
|
+
const rowScrollMarginTopRef = react.useRef(0);
|
|
317
|
+
const rowScrollMarginBottomRef = react.useRef(0);
|
|
318
|
+
const categoryHeaderHeightRef = react.useRef(0);
|
|
314
319
|
const {
|
|
315
320
|
data,
|
|
316
321
|
error,
|
|
@@ -323,41 +328,42 @@ const EmojiPickerContent = React.forwardRef(
|
|
|
323
328
|
interaction,
|
|
324
329
|
setInteraction
|
|
325
330
|
} = contexts.useEmojiPicker();
|
|
326
|
-
const selectedEmoji =
|
|
331
|
+
const selectedEmoji = react.useMemo(
|
|
327
332
|
() => data?.rows[selectedRowIndex]?.[selectedColumnIndex],
|
|
328
333
|
[data?.rows, selectedColumnIndex, selectedRowIndex]
|
|
329
334
|
);
|
|
330
|
-
const { Loading, Empty, Error, CategoryHeader, Grid, Row, Emoji } =
|
|
335
|
+
const { Loading, Empty, Error, CategoryHeader, Grid, Row, Emoji } = react.useMemo(
|
|
331
336
|
() => ({ ...defaultContentComponents, ...components }),
|
|
332
337
|
[components]
|
|
333
338
|
);
|
|
334
|
-
const VirtuosoList =
|
|
335
|
-
() =>
|
|
339
|
+
const VirtuosoList = react.useMemo(
|
|
340
|
+
() => react.forwardRef(
|
|
336
341
|
({ children, ...props2 }, forwardedRef2) => {
|
|
337
|
-
return /* @__PURE__ */
|
|
342
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
338
343
|
role: "grid",
|
|
339
344
|
"aria-colcount": columns,
|
|
340
345
|
...props2,
|
|
341
346
|
"data-testid": void 0,
|
|
342
|
-
ref: forwardedRef2
|
|
343
|
-
|
|
347
|
+
ref: forwardedRef2,
|
|
348
|
+
children
|
|
349
|
+
});
|
|
344
350
|
}
|
|
345
351
|
),
|
|
346
352
|
[columns]
|
|
347
353
|
);
|
|
348
|
-
const placeholderColumns =
|
|
354
|
+
const placeholderColumns = react.useMemo(
|
|
349
355
|
() => Array(columns).fill("\u{1F32B}\uFE0F"),
|
|
350
356
|
[columns]
|
|
351
357
|
);
|
|
352
|
-
const preventDefault =
|
|
358
|
+
const preventDefault = react.useCallback((event) => {
|
|
353
359
|
event.preventDefault();
|
|
354
360
|
}, []);
|
|
355
|
-
const handleEmojiPointerLeave =
|
|
361
|
+
const handleEmojiPointerLeave = react.useCallback(() => {
|
|
356
362
|
if (interaction === "pointer") {
|
|
357
363
|
setInteraction("none");
|
|
358
364
|
}
|
|
359
365
|
}, [interaction, setInteraction]);
|
|
360
|
-
|
|
366
|
+
react.useLayoutEffect(() => {
|
|
361
367
|
if (!placeholderContainerRef.current) {
|
|
362
368
|
return;
|
|
363
369
|
}
|
|
@@ -372,7 +378,7 @@ const EmojiPickerContent = React.forwardRef(
|
|
|
372
378
|
categoryHeaderHeightRef.current = categoryHeader.offsetHeight;
|
|
373
379
|
}
|
|
374
380
|
}, []);
|
|
375
|
-
const calculateViewLocation =
|
|
381
|
+
const calculateViewLocation = react.useCallback(
|
|
376
382
|
({
|
|
377
383
|
itemTop,
|
|
378
384
|
itemBottom,
|
|
@@ -399,7 +405,7 @@ const EmojiPickerContent = React.forwardRef(
|
|
|
399
405
|
},
|
|
400
406
|
[]
|
|
401
407
|
);
|
|
402
|
-
|
|
408
|
+
react.useEffect(() => {
|
|
403
409
|
if (interaction === "keyboard") {
|
|
404
410
|
virtuosoRef.current?.scrollIntoView({
|
|
405
411
|
index: selectedRowIndex,
|
|
@@ -408,80 +414,92 @@ const EmojiPickerContent = React.forwardRef(
|
|
|
408
414
|
});
|
|
409
415
|
}
|
|
410
416
|
}, [interaction, selectedRowIndex, calculateViewLocation]);
|
|
411
|
-
return /* @__PURE__ */
|
|
417
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Component, {
|
|
412
418
|
...props,
|
|
413
|
-
ref: forwardedRef
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
return /* @__PURE__ */ React.createElement(CategoryHeader, {
|
|
443
|
-
category
|
|
444
|
-
});
|
|
445
|
-
},
|
|
446
|
-
itemContent: (rowIndex, groupIndex) => {
|
|
447
|
-
const categoryRow = data.rows[rowIndex];
|
|
448
|
-
const categoryRowIndex = data.categoriesRowIndices[groupIndex]?.indexOf(rowIndex);
|
|
449
|
-
const categoryRowsCount = data.categoriesRowCounts[groupIndex];
|
|
450
|
-
if (categoryRow === void 0 || categoryRowIndex === void 0 || categoryRowsCount === void 0) {
|
|
451
|
-
return null;
|
|
452
|
-
}
|
|
453
|
-
return /* @__PURE__ */ React.createElement(Row, {
|
|
454
|
-
attributes: {
|
|
455
|
-
rowIndex,
|
|
456
|
-
categoryRowIndex,
|
|
457
|
-
categoryRowsCount
|
|
458
|
-
}
|
|
459
|
-
}, categoryRow.map((emoji, columnIndex) => {
|
|
460
|
-
const isSelected = interaction !== "none" && selectedColumnIndex === columnIndex && selectedRowIndex === rowIndex;
|
|
461
|
-
return /* @__PURE__ */ React.createElement(Emoji, {
|
|
462
|
-
key: emoji.emoji,
|
|
463
|
-
role: "gridcell",
|
|
464
|
-
"aria-colindex": columnIndex,
|
|
465
|
-
"aria-selected": isSelected || void 0,
|
|
466
|
-
"data-selected": isSelected || void 0,
|
|
467
|
-
onMouseDown: preventDefault,
|
|
468
|
-
tabIndex: -1,
|
|
469
|
-
onPointerEnter: () => {
|
|
470
|
-
setPointerSelection(columnIndex, rowIndex);
|
|
419
|
+
ref: forwardedRef,
|
|
420
|
+
children: [
|
|
421
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
422
|
+
style: {
|
|
423
|
+
visibility: "hidden",
|
|
424
|
+
height: 0
|
|
425
|
+
},
|
|
426
|
+
ref: placeholderContainerRef,
|
|
427
|
+
children: [
|
|
428
|
+
/* @__PURE__ */ jsxRuntime.jsx(Row, {
|
|
429
|
+
attributes: placeholderRowAttributes,
|
|
430
|
+
children: placeholderColumns.map((placeholder, index) => /* @__PURE__ */ jsxRuntime.jsx(Emoji, {
|
|
431
|
+
emoji: placeholder
|
|
432
|
+
}, index))
|
|
433
|
+
}),
|
|
434
|
+
/* @__PURE__ */ jsxRuntime.jsx(CategoryHeader, {
|
|
435
|
+
category: "Category"
|
|
436
|
+
})
|
|
437
|
+
]
|
|
438
|
+
}),
|
|
439
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Loading, {}) : error ? /* @__PURE__ */ jsxRuntime.jsx(Error, {
|
|
440
|
+
error
|
|
441
|
+
}) : data.count === 0 ? /* @__PURE__ */ jsxRuntime.jsx(Empty, {}) : /* @__PURE__ */ jsxRuntime.jsx(Grid, {
|
|
442
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactVirtuoso.GroupedVirtuoso, {
|
|
443
|
+
ref: virtuosoRef,
|
|
444
|
+
components: {
|
|
445
|
+
Scroller: VirtuosoScroller,
|
|
446
|
+
List: VirtuosoList,
|
|
447
|
+
TopItemList: VirtuosoTopList
|
|
471
448
|
},
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
449
|
+
groupCounts: data.categoriesRowCounts,
|
|
450
|
+
groupContent: (groupIndex) => {
|
|
451
|
+
const category = data.categories[groupIndex];
|
|
452
|
+
if (!category) {
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CategoryHeader, {
|
|
456
|
+
category
|
|
457
|
+
});
|
|
476
458
|
},
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
459
|
+
itemContent: (rowIndex, groupIndex) => {
|
|
460
|
+
const categoryRow = data.rows[rowIndex];
|
|
461
|
+
const categoryRowIndex = data.categoriesRowIndices[groupIndex]?.indexOf(rowIndex);
|
|
462
|
+
const categoryRowsCount = data.categoriesRowCounts[groupIndex];
|
|
463
|
+
if (categoryRow === void 0 || categoryRowIndex === void 0 || categoryRowsCount === void 0) {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Row, {
|
|
467
|
+
attributes: {
|
|
468
|
+
rowIndex,
|
|
469
|
+
categoryRowIndex,
|
|
470
|
+
categoryRowsCount
|
|
471
|
+
},
|
|
472
|
+
children: categoryRow.map((emoji, columnIndex) => {
|
|
473
|
+
const isSelected = interaction !== "none" && selectedColumnIndex === columnIndex && selectedRowIndex === rowIndex;
|
|
474
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Emoji, {
|
|
475
|
+
role: "gridcell",
|
|
476
|
+
"aria-colindex": columnIndex,
|
|
477
|
+
"aria-selected": isSelected || void 0,
|
|
478
|
+
"data-selected": isSelected || void 0,
|
|
479
|
+
onMouseDown: preventDefault,
|
|
480
|
+
tabIndex: -1,
|
|
481
|
+
onPointerEnter: () => {
|
|
482
|
+
setPointerSelection(columnIndex, rowIndex);
|
|
483
|
+
},
|
|
484
|
+
onPointerLeave: handleEmojiPointerLeave,
|
|
485
|
+
onClick: (event) => {
|
|
486
|
+
onEmojiSelect?.(emoji.emoji);
|
|
487
|
+
event.stopPropagation();
|
|
488
|
+
},
|
|
489
|
+
emoji: emoji.emoji
|
|
490
|
+
}, emoji.emoji);
|
|
491
|
+
})
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
})
|
|
495
|
+
}),
|
|
496
|
+
selectedEmoji && interaction !== "none" && /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
497
|
+
"aria-live": "polite",
|
|
498
|
+
style: visuallyHidden.visuallyHidden,
|
|
499
|
+
children: selectedEmoji.name
|
|
500
|
+
})
|
|
501
|
+
]
|
|
502
|
+
});
|
|
485
503
|
}
|
|
486
504
|
);
|
|
487
505
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/primitives/EmojiPicker/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { ChangeEvent, KeyboardEvent, SyntheticEvent } from \"react\";\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n CalculateViewLocationParams,\n GroupedVirtuosoHandle,\n ListProps as VirtuosoListProps,\n ScrollerProps,\n TopItemListProps,\n} from \"react-virtuoso\";\nimport { GroupedVirtuoso } from \"react-virtuoso\";\n\nimport { isKey } from \"../../utils/is-key\";\nimport {\n cancelIdleCallback,\n requestIdleCallback,\n} from \"../../utils/request-idle-callback\";\nimport { useLayoutEffect } from \"../../utils/use-layout-effect\";\nimport { useTransition } from \"../../utils/use-transition\";\nimport { visuallyHidden } from \"../../utils/visually-hidden\";\nimport { Emoji as EmojiPrimitive } from \"../internal/Emoji\";\nimport { EmojiPickerContext, useEmojiPicker } from \"./contexts\";\nimport type {\n EmojiData,\n EmojiPickerContentComponents,\n EmojiPickerContentEmojiRowAttributes,\n EmojiPickerContentProps,\n EmojiPickerData,\n EmojiPickerRootProps,\n EmojiPickerSearchProps,\n EmojiPickerSelectionDirection,\n} from \"./types\";\nimport { filterEmojis, generateEmojiPickerData, getEmojiData } from \"./utils\";\n\nconst DEFAULT_COLUMNS = 10;\nconst DEFAULT_LOCALE = \"en\";\nconst LOADING_MINIMUM_TIMEOUT = 100;\n\nconst EMOJIPICKER_ROOT_NAME = \"EmojiPickerRoot\";\nconst EMOJIPICKER_CONTENT_NAME = \"EmojiPickerContent\";\nconst EMOJIPICKER_SEARCH_NAME = \"EmojiPickerSearch\";\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * Surrounds the emoji picker, it handles emoji data and coordinates\n * `EmojiPicker.Search` and `EmojiPicker.Content`.\n *\n * @example\n * <EmojiPicker.Root>\n * <EmojiPicker.Search />\n * <EmojiPicker.Content />\n * </EmojiPicker.Root>\n */\nfunction EmojiPickerRoot({\n columns = DEFAULT_COLUMNS,\n locale = DEFAULT_LOCALE,\n onEmojiSelect,\n children,\n}: EmojiPickerRootProps) {\n const emojiData = useRef<EmojiData>();\n const search = useRef(\"\");\n const [, startEmojisTransition] = useTransition();\n const [data, setData] = useState<EmojiPickerData>();\n const [error, setError] = useState<Error>();\n const [selectedColumnIndex, setSelectedColumnIndex] = useState(0);\n const [selectedRowIndex, setSelectedRowIndex] = useState(0);\n const [interaction, setInteraction] = useState<\n \"keyboard\" | \"pointer\" | \"none\"\n >(\"none\");\n\n const selectCurrentEmoji = useCallback(() => {\n if (onEmojiSelect) {\n const emoji = data?.rows[selectedRowIndex]?.[selectedColumnIndex];\n\n if (emoji) {\n onEmojiSelect(emoji.emoji);\n }\n }\n }, [data?.rows, onEmojiSelect, selectedColumnIndex, selectedRowIndex]);\n\n const resetSelection = useCallback(() => {\n setSelectedColumnIndex(0);\n setSelectedRowIndex(0);\n }, []);\n\n const setPointerSelection = useCallback(\n (columnIndex: number, rowIndex: number) => {\n setInteraction(\"pointer\");\n setSelectedColumnIndex(columnIndex);\n setSelectedRowIndex(rowIndex);\n },\n []\n );\n\n const moveSelection = useCallback(\n (\n direction: EmojiPickerSelectionDirection,\n event: KeyboardEvent<HTMLInputElement>\n ) => {\n if (!data) {\n return;\n }\n\n event.preventDefault();\n\n if (interaction === \"none\") {\n setInteraction(\"keyboard\");\n return;\n }\n\n setInteraction(\"keyboard\");\n\n switch (direction) {\n // If first column, move to last column of previous row (if available)\n // Otherwise, move to previous column\n case \"left\": {\n if (selectedColumnIndex === 0) {\n const previousRowIndex = selectedRowIndex - 1;\n const previousRow = data.rows[previousRowIndex];\n\n if (previousRow) {\n setSelectedRowIndex(previousRowIndex);\n setSelectedColumnIndex(previousRow.length - 1);\n }\n } else {\n setSelectedColumnIndex(selectedColumnIndex - 1);\n }\n\n break;\n }\n\n // If last column, move to first column of next row (if available)\n // Otherwise, move to next column\n case \"right\": {\n const currentRow = data.rows[selectedRowIndex];\n\n if (!currentRow) {\n return;\n }\n\n if (selectedColumnIndex === currentRow.length - 1) {\n const nextRowIndex = selectedRowIndex + 1;\n const nextRow = data.rows[nextRowIndex];\n\n if (nextRow) {\n setSelectedRowIndex(nextRowIndex);\n setSelectedColumnIndex(0);\n }\n } else {\n setSelectedColumnIndex(selectedColumnIndex + 1);\n }\n\n break;\n }\n\n // Move to same column of previous row\n // If same column is not available, move to last column of previous row\n case \"up\": {\n const previousRow = data.rows[selectedRowIndex - 1];\n\n if (previousRow) {\n setSelectedRowIndex(selectedRowIndex - 1);\n\n if (!previousRow[selectedColumnIndex]) {\n setSelectedColumnIndex(previousRow.length - 1);\n }\n }\n\n break;\n }\n\n // Move to same column of next row\n // If same column is not available, move to last column of next row\n case \"down\": {\n const nextRow = data.rows[selectedRowIndex + 1];\n\n if (nextRow) {\n setSelectedRowIndex(selectedRowIndex + 1);\n\n if (!nextRow[selectedColumnIndex]) {\n setSelectedColumnIndex(nextRow.length - 1);\n }\n }\n\n break;\n }\n }\n },\n [data, interaction, selectedColumnIndex, selectedRowIndex]\n );\n\n const updateEmojis = useCallback(() => {\n if (!emojiData.current) {\n return;\n }\n\n startEmojisTransition(() => {\n setData(() => {\n if (!emojiData.current) {\n return;\n }\n\n const filteredEmojis = filterEmojis(\n emojiData.current.emojis,\n search.current\n );\n\n return generateEmojiPickerData(\n filteredEmojis,\n emojiData.current.categories,\n columns\n );\n });\n resetSelection();\n });\n }, [columns, resetSelection]);\n\n const handleSearch = useCallback(\n (value: string) => {\n search.current = value;\n updateEmojis();\n },\n [updateEmojis]\n );\n\n const initializeEmojiData = useCallback(\n async (locale: string) => {\n try {\n emojiData.current = await getEmojiData(locale);\n updateEmojis();\n } catch (error) {\n setError(error as Error);\n }\n },\n [updateEmojis]\n );\n\n useEffect(() => {\n let idleCallbackId: number;\n const timeoutId = setTimeout(() => {\n idleCallbackId = requestIdleCallback(() => {\n initializeEmojiData(locale);\n });\n }, LOADING_MINIMUM_TIMEOUT);\n\n return () => {\n clearTimeout(timeoutId);\n cancelIdleCallback(idleCallbackId);\n };\n }, [locale]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n if (interaction === \"none\") {\n resetSelection();\n }\n }, [interaction]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <EmojiPickerContext.Provider\n value={{\n data: data as EmojiPickerData,\n error: error as undefined,\n isLoading: (!data && !error) as false,\n columns,\n onSearch: handleSearch,\n onEmojiSelect,\n selectCurrentEmoji,\n selectedRowIndex,\n selectedColumnIndex,\n moveSelection,\n setPointerSelection,\n interaction,\n setInteraction,\n }}\n >\n {children}\n </EmojiPickerContext.Provider>\n );\n}\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * The search input of the emoji picker. It also affects the focus and selection\n * within `EmojiPicker.Content`.\n *\n * @example\n * <EmojiPicker.Search />\n */\nconst EmojiPickerSearch = forwardRef<HTMLInputElement, EmojiPickerSearchProps>(\n ({ asChild, value, defaultValue, onChange, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"input\";\n const {\n onSearch,\n selectCurrentEmoji,\n moveSelection,\n interaction,\n setInteraction,\n } = useEmojiPicker();\n\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n onChange?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n const value = event.target.value;\n setInteraction(value ? \"keyboard\" : \"none\");\n onSearch(value);\n },\n [onChange, onSearch, setInteraction]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.isDefaultPrevented()) {\n return;\n }\n\n if (isKey(event, \"ArrowLeft\")) {\n moveSelection(\"left\", event);\n } else if (isKey(event, \"ArrowRight\")) {\n moveSelection(\"right\", event);\n } else if (isKey(event, \"ArrowUp\")) {\n moveSelection(\"up\", event);\n } else if (isKey(event, \"ArrowDown\")) {\n moveSelection(\"down\", event);\n } else if (isKey(event, \"Enter\")) {\n if (interaction !== \"none\") {\n event.preventDefault();\n selectCurrentEmoji();\n }\n }\n },\n [interaction, moveSelection, selectCurrentEmoji]\n );\n\n useEffect(() => {\n onSearch(\n value ? String(value) : defaultValue ? String(defaultValue) : \"\"\n );\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <Component\n type=\"search\"\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n);\n\nconst defaultContentComponents: EmojiPickerContentComponents = {\n CategoryHeader: ({ category, ...props }) => <div {...props}>{category}</div>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Row: ({ children, attributes, ...props }) => <div {...props}>{children}</div>,\n Emoji: ({ emoji, ...props }) => (\n <button {...props}>\n <EmojiPrimitive emoji={emoji} />\n </button>\n ),\n Loading: (props) => <div {...props} />,\n Empty: (props) => <div {...props} />,\n Grid: (props) => <div {...props} />,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Error: ({ error, ...props }) => <div {...props} />,\n};\n\nconst placeholderRowAttributes: EmojiPickerContentEmojiRowAttributes = {\n rowIndex: -1,\n categoryRowIndex: -1,\n categoryRowsCount: 0,\n};\n\n// About `data-testid={undefined}`: Virtuoso bakes test IDs into the components we pass\n// to it, so we manually remove them.\n\nconst VirtuosoScroller = forwardRef<HTMLDivElement, ScrollerProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div {...props} tabIndex={-1} data-testid={undefined} ref={forwardedRef}>\n {children}\n </div>\n );\n }\n);\n\nconst VirtuosoTopList = forwardRef<HTMLDivElement, TopItemListProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div {...props} data-testid={undefined} ref={forwardedRef}>\n {children}\n </div>\n );\n }\n);\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * The main content of the emoji picker, either displaying the emoji grid or various\n * alternative states (loading, empty, and error).\n *\n * @example\n * <EmojiPicker.Content\n * components={{\n * Loading: EmojiPickerLoading,\n * Empty: EmojiPickerEmpty,\n * Error: EmojiPickerError,\n * CategoryHeader: EmojiPickerCategoryHeader,\n * Grid: EmojiPickerGrid,\n * Row: EmojiPickerRow,\n * Emoji: EmojiPickerEmoji,\n * }}\n * />\n */\nconst EmojiPickerContent = forwardRef<HTMLDivElement, EmojiPickerContentProps>(\n ({ components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const virtuosoRef = useRef<GroupedVirtuosoHandle>(null);\n const placeholderContainerRef = useRef<HTMLDivElement>(null);\n const rowScrollMarginTopRef = useRef<number>(0);\n const rowScrollMarginBottomRef = useRef<number>(0);\n const categoryHeaderHeightRef = useRef<number>(0);\n const {\n data,\n error,\n isLoading,\n columns,\n onEmojiSelect,\n selectedColumnIndex,\n selectedRowIndex,\n setPointerSelection,\n interaction,\n setInteraction,\n } = useEmojiPicker();\n const selectedEmoji = useMemo(\n () => data?.rows[selectedRowIndex]?.[selectedColumnIndex],\n [data?.rows, selectedColumnIndex, selectedRowIndex]\n );\n const { Loading, Empty, Error, CategoryHeader, Grid, Row, Emoji } = useMemo(\n () => ({ ...defaultContentComponents, ...components }),\n [components]\n );\n const VirtuosoList = useMemo(\n () =>\n forwardRef<HTMLDivElement, VirtuosoListProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div\n role=\"grid\"\n aria-colcount={columns}\n {...props}\n data-testid={undefined}\n ref={forwardedRef}\n >\n {children}\n </div>\n );\n }\n ),\n [columns]\n );\n const placeholderColumns = useMemo(\n () => Array<string>(columns).fill(\"🌫️\"),\n [columns]\n );\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const handleEmojiPointerLeave = useCallback(() => {\n if (interaction === \"pointer\") {\n setInteraction(\"none\");\n }\n }, [interaction, setInteraction]);\n\n useLayoutEffect(() => {\n if (!placeholderContainerRef.current) {\n return;\n }\n\n const row = placeholderContainerRef.current.childNodes[0];\n const categoryHeader = placeholderContainerRef.current.childNodes[1];\n\n if (row instanceof HTMLElement) {\n const style = window.getComputedStyle(row);\n\n rowScrollMarginTopRef.current = parseFloat(style.scrollMarginTop);\n rowScrollMarginBottomRef.current = parseFloat(style.scrollMarginBottom);\n }\n\n if (categoryHeader instanceof HTMLElement) {\n categoryHeaderHeightRef.current = categoryHeader.offsetHeight;\n }\n }, []);\n\n // Customize `scrollIntoView` behavior to take into account category headers and margins\n const calculateViewLocation = useCallback(\n ({\n itemTop,\n itemBottom,\n viewportTop,\n viewportBottom,\n locationParams: { behavior, align, ...params },\n }: CalculateViewLocationParams) => {\n if (\n itemTop -\n (categoryHeaderHeightRef.current + rowScrollMarginTopRef.current) <\n viewportTop\n ) {\n return {\n ...params,\n behavior,\n align: align ?? \"start\",\n };\n }\n\n if (itemBottom > viewportBottom) {\n return {\n ...params,\n behavior,\n align: align ?? \"end\",\n offset: rowScrollMarginBottomRef.current,\n };\n }\n\n return null;\n },\n []\n );\n\n useEffect(() => {\n if (interaction === \"keyboard\") {\n virtuosoRef.current?.scrollIntoView({\n index: selectedRowIndex,\n behavior: \"auto\",\n calculateViewLocation,\n });\n }\n }, [interaction, selectedRowIndex, calculateViewLocation]);\n\n return (\n <Component {...props} ref={forwardedRef}>\n <div\n style={{\n visibility: \"hidden\",\n height: 0,\n }}\n ref={placeholderContainerRef}\n >\n {/* Virtualized rows are absolutely positioned so they won't make\n the container automatically pick up their width. To achieve\n an automatic width, we add a relative (but hidden) full row. */}\n <Row attributes={placeholderRowAttributes}>\n {placeholderColumns.map((placeholder, index) => (\n <Emoji emoji={placeholder} key={index} />\n ))}\n </Row>\n {/* We also add a hidden category header to get its computed height. */}\n <CategoryHeader category=\"Category\" />\n </div>\n {isLoading ? (\n <Loading />\n ) : error ? (\n <Error error={error} />\n ) : data.count === 0 ? (\n <Empty />\n ) : (\n <Grid>\n <GroupedVirtuoso\n ref={virtuosoRef}\n components={{\n Scroller: VirtuosoScroller,\n List: VirtuosoList,\n TopItemList: VirtuosoTopList,\n }}\n groupCounts={data.categoriesRowCounts}\n groupContent={(groupIndex) => {\n const category = data.categories[groupIndex];\n\n if (!category) {\n return null;\n }\n\n return <CategoryHeader category={category} />;\n }}\n itemContent={(rowIndex, groupIndex) => {\n const categoryRow = data.rows[rowIndex];\n const categoryRowIndex =\n data.categoriesRowIndices[groupIndex]?.indexOf(rowIndex);\n const categoryRowsCount = data.categoriesRowCounts[groupIndex];\n\n if (\n categoryRow === undefined ||\n categoryRowIndex === undefined ||\n categoryRowsCount === undefined\n ) {\n return null;\n }\n\n return (\n <Row\n attributes={{\n rowIndex,\n categoryRowIndex,\n categoryRowsCount,\n }}\n >\n {categoryRow.map((emoji, columnIndex) => {\n const isSelected =\n interaction !== \"none\" &&\n selectedColumnIndex === columnIndex &&\n selectedRowIndex === rowIndex;\n\n return (\n <Emoji\n key={emoji.emoji}\n role=\"gridcell\"\n aria-colindex={columnIndex}\n aria-selected={isSelected || undefined}\n data-selected={isSelected || undefined}\n onMouseDown={preventDefault}\n tabIndex={-1}\n onPointerEnter={() => {\n setPointerSelection(columnIndex, rowIndex);\n }}\n onPointerLeave={handleEmojiPointerLeave}\n onClick={(event) => {\n onEmojiSelect?.(emoji.emoji);\n event.stopPropagation();\n }}\n emoji={emoji.emoji}\n />\n );\n })}\n </Row>\n );\n }}\n />\n </Grid>\n )}\n {selectedEmoji && interaction !== \"none\" && (\n <div aria-live=\"polite\" style={visuallyHidden}>\n {selectedEmoji.name}\n </div>\n )}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n EmojiPickerRoot.displayName = EMOJIPICKER_ROOT_NAME;\n EmojiPickerContent.displayName = EMOJIPICKER_CONTENT_NAME;\n EmojiPickerSearch.displayName = EMOJIPICKER_SEARCH_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as EmojiPicker.*\nexport {\n EmojiPickerContent as Content,\n EmojiPickerRoot as Root,\n EmojiPickerSearch as Search,\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA2CA;AACA;AACA;AAEA;AACA;AACA;AAkBA;AAAyB;AACb;AACD;AACT;AAEF;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACE;AACE;AAEA;AACE;AAAyB;AAC3B;AACF;AAGF;AACE;AACA;AAAqB;AAGvB;AAA4B;AAExB;AACA;AACA;AAA4B;AAC9B;AACC;AAGH;AAAsB;AAKlB;AACE;AAAA;AAGF;AAEA;AACE;AACA;AAAA;AAGF;AAEA;AAAmB;AAIf;AACE;AACA;AAEA;AACE;AACA;AAA6C;AAC/C;AAEA;AAA8C;AAGhD;AAAA;AACF;AAKE;AAEA;AACE;AAAA;AAGF;AACE;AACA;AAEA;AACE;AACA;AAAwB;AAC1B;AAEA;AAA8C;AAGhD;AAAA;AACF;AAKE;AAEA;AACE;AAEA;AACE;AAA6C;AAC/C;AAGF;AAAA;AACF;AAKE;AAEA;AACE;AAEA;AACE;AAAyC;AAC3C;AAGF;AAAA;AACF;AACF;AACF;AACyD;AAG3D;AACE;AACE;AAAA;AAGF;AACE;AACE;AACE;AAAA;AAGF;AAAuB;AACH;AACX;AAGT;AAAO;AACL;AACkB;AAClB;AACF;AAEF;AAAe;AAChB;AAGH;AAAqB;AAEjB;AACA;AAAa;AACf;AACa;AAGf;AAA4B;AAExB;AACE;AACA;AAAa;AAEb;AAAuB;AACzB;AACF;AACa;AAGf;AACE;AACA;AACE;AACE;AAA0B;AAC3B;AAGH;AACE;AACA;AAAiC;AACnC;AAGF;AACE;AACE;AAAe;AACjB;AAGF;AACG;AACQ;AACL;AACA;AACsB;AACtB;AACU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF;AAKN;AAeA;AAA0B;AAEtB;AACA;AAAM;AACJ;AACA;AACA;AACA;AACA;AAGF;AAAqB;AAEjB;AAEA;AACE;AAAA;AAGF;AACA;AACA;AAAc;AAChB;AACmC;AAGrC;AAAsB;AAElB;AACE;AAAA;AAGF;AACE;AAA2B;AAE3B;AAA4B;AAE5B;AAAyB;AAEzB;AAA2B;AAE3B;AACE;AACA;AAAmB;AACrB;AACF;AACF;AAC+C;AAGjD;AACE;AAAA;AACgE;AAChE;AAGF;AACG;AACM;AACL;AACA;AACU;AACC;AACP;AACC;AACP;AAGN;AAEA;AAA+D;AAChB;AAAQ;AAAiB;AAExB;AAAQ;AAAiB;AAEpE;AAAW;AACT;AAAe;AAClB;AAEmB;AAAQ;AAAO;AACjB;AAAQ;AAAO;AAChB;AAAQ;AAAO;AAEA;AAAQ;AAC3C;AAEA;AAAuE;AAC3D;AACQ;AAEpB;AAKA;AAAyB;AAErB;AACG;AAAQ;AAAiB;AAAiB;AAAgB;AAE3D;AAGN;AAEA;AAAwB;AAEpB;AACG;AAAQ;AAAoB;AAAgB;AAE7C;AAGN;AAyBA;AAA2B;AAEvB;AACA;AACA;AACA;AACA;AACA;AACA;AAAM;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEF;AAAsB;AACiB;AACa;AAEpD;AAAoE;AACd;AACzC;AAEb;AAAqB;AAEjB;AAEI;AACG;AACM;AACU;AACX;AACS;AACR;AAGP;AAEJ;AACF;AACM;AAEV;AAA2B;AACc;AAC/B;AAGV;AACE;AAAqB;AAGvB;AACE;AACE;AAAqB;AACvB;AAGF;AACE;AACE;AAAA;AAGF;AACA;AAEA;AACE;AAEA;AACA;AAAsE;AAGxE;AACE;AAAiD;AACnD;AAIF;AAA8B;AAC3B;AACC;AACA;AACA;AACA;AAC6C;AAE7C;AAKE;AAAO;AACF;AACH;AACgB;AAClB;AAGF;AACE;AAAO;AACF;AACH;AACgB;AACiB;AACnC;AAGF;AAAO;AACT;AACC;AAGH;AACE;AACE;AAAoC;AAC3B;AACG;AACV;AACD;AACH;AAGF;AACG;AAAc;AAAY;AACxB;AACQ;AACO;AACJ;AACV;AACK;AAKJ;AAAgB;AAEZ;AAAa;AAAkB;AAInC;AAAwB;AAKxB;AAAM;AAKJ;AACM;AACO;AACA;AACJ;AACO;AACf;AACkB;AAEhB;AAEA;AACE;AAAO;AAGT;AAAQ;AAAe;AAAoB;AAC7C;AAEE;AACA;AAEA;AAEA;AAKE;AAAO;AAGT;AACG;AACa;AACV;AACA;AACA;AACF;AAGE;AAKA;AACG;AACY;AACN;AACU;AACc;AACA;AAChB;AACH;AAER;AAAyC;AAC3C;AACgB;AAEd;AACA;AAAsB;AACxB;AACa;AACf;AAGN;AAEJ;AAKH;AAAc;AAAgB;AAInC;AAGN;AAEA;AACE;AACA;AACA;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/primitives/EmojiPicker/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { ChangeEvent, KeyboardEvent, SyntheticEvent } from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n useTransition,\n} from \"react\";\nimport type {\n CalculateViewLocationParams,\n GroupedVirtuosoHandle,\n ListProps as VirtuosoListProps,\n ScrollerProps,\n TopItemListProps,\n} from \"react-virtuoso\";\nimport { GroupedVirtuoso } from \"react-virtuoso\";\n\nimport { isKey } from \"../../utils/is-key\";\nimport {\n cancelIdleCallback,\n requestIdleCallback,\n} from \"../../utils/request-idle-callback\";\nimport { visuallyHidden } from \"../../utils/visually-hidden\";\nimport { Emoji as EmojiPrimitive } from \"../internal/Emoji\";\nimport { EmojiPickerContext, useEmojiPicker } from \"./contexts\";\nimport type {\n EmojiData,\n EmojiPickerContentComponents,\n EmojiPickerContentEmojiRowAttributes,\n EmojiPickerContentProps,\n EmojiPickerData,\n EmojiPickerRootProps,\n EmojiPickerSearchProps,\n EmojiPickerSelectionDirection,\n} from \"./types\";\nimport { filterEmojis, generateEmojiPickerData, getEmojiData } from \"./utils\";\n\nconst DEFAULT_COLUMNS = 10;\nconst DEFAULT_LOCALE = \"en\";\nconst LOADING_MINIMUM_TIMEOUT = 100;\n\nconst EMOJIPICKER_ROOT_NAME = \"EmojiPickerRoot\";\nconst EMOJIPICKER_CONTENT_NAME = \"EmojiPickerContent\";\nconst EMOJIPICKER_SEARCH_NAME = \"EmojiPickerSearch\";\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * Surrounds the emoji picker, it handles emoji data and coordinates\n * `EmojiPicker.Search` and `EmojiPicker.Content`.\n *\n * @example\n * <EmojiPicker.Root>\n * <EmojiPicker.Search />\n * <EmojiPicker.Content />\n * </EmojiPicker.Root>\n */\nfunction EmojiPickerRoot({\n columns = DEFAULT_COLUMNS,\n locale = DEFAULT_LOCALE,\n onEmojiSelect,\n children,\n}: EmojiPickerRootProps) {\n const emojiData = useRef<EmojiData>();\n const search = useRef(\"\");\n const [, startEmojisTransition] = useTransition();\n const [data, setData] = useState<EmojiPickerData>();\n const [error, setError] = useState<Error>();\n const [selectedColumnIndex, setSelectedColumnIndex] = useState(0);\n const [selectedRowIndex, setSelectedRowIndex] = useState(0);\n const [interaction, setInteraction] = useState<\n \"keyboard\" | \"pointer\" | \"none\"\n >(\"none\");\n\n const selectCurrentEmoji = useCallback(() => {\n if (onEmojiSelect) {\n const emoji = data?.rows[selectedRowIndex]?.[selectedColumnIndex];\n\n if (emoji) {\n onEmojiSelect(emoji.emoji);\n }\n }\n }, [data?.rows, onEmojiSelect, selectedColumnIndex, selectedRowIndex]);\n\n const resetSelection = useCallback(() => {\n setSelectedColumnIndex(0);\n setSelectedRowIndex(0);\n }, []);\n\n const setPointerSelection = useCallback(\n (columnIndex: number, rowIndex: number) => {\n setInteraction(\"pointer\");\n setSelectedColumnIndex(columnIndex);\n setSelectedRowIndex(rowIndex);\n },\n []\n );\n\n const moveSelection = useCallback(\n (\n direction: EmojiPickerSelectionDirection,\n event: KeyboardEvent<HTMLInputElement>\n ) => {\n if (!data) {\n return;\n }\n\n event.preventDefault();\n\n if (interaction === \"none\") {\n setInteraction(\"keyboard\");\n return;\n }\n\n setInteraction(\"keyboard\");\n\n switch (direction) {\n // If first column, move to last column of previous row (if available)\n // Otherwise, move to previous column\n case \"left\": {\n if (selectedColumnIndex === 0) {\n const previousRowIndex = selectedRowIndex - 1;\n const previousRow = data.rows[previousRowIndex];\n\n if (previousRow) {\n setSelectedRowIndex(previousRowIndex);\n setSelectedColumnIndex(previousRow.length - 1);\n }\n } else {\n setSelectedColumnIndex(selectedColumnIndex - 1);\n }\n\n break;\n }\n\n // If last column, move to first column of next row (if available)\n // Otherwise, move to next column\n case \"right\": {\n const currentRow = data.rows[selectedRowIndex];\n\n if (!currentRow) {\n return;\n }\n\n if (selectedColumnIndex === currentRow.length - 1) {\n const nextRowIndex = selectedRowIndex + 1;\n const nextRow = data.rows[nextRowIndex];\n\n if (nextRow) {\n setSelectedRowIndex(nextRowIndex);\n setSelectedColumnIndex(0);\n }\n } else {\n setSelectedColumnIndex(selectedColumnIndex + 1);\n }\n\n break;\n }\n\n // Move to same column of previous row\n // If same column is not available, move to last column of previous row\n case \"up\": {\n const previousRow = data.rows[selectedRowIndex - 1];\n\n if (previousRow) {\n setSelectedRowIndex(selectedRowIndex - 1);\n\n if (!previousRow[selectedColumnIndex]) {\n setSelectedColumnIndex(previousRow.length - 1);\n }\n }\n\n break;\n }\n\n // Move to same column of next row\n // If same column is not available, move to last column of next row\n case \"down\": {\n const nextRow = data.rows[selectedRowIndex + 1];\n\n if (nextRow) {\n setSelectedRowIndex(selectedRowIndex + 1);\n\n if (!nextRow[selectedColumnIndex]) {\n setSelectedColumnIndex(nextRow.length - 1);\n }\n }\n\n break;\n }\n }\n },\n [data, interaction, selectedColumnIndex, selectedRowIndex]\n );\n\n const updateEmojis = useCallback(() => {\n if (!emojiData.current) {\n return;\n }\n\n startEmojisTransition(() => {\n setData(() => {\n if (!emojiData.current) {\n return;\n }\n\n const filteredEmojis = filterEmojis(\n emojiData.current.emojis,\n search.current\n );\n\n return generateEmojiPickerData(\n filteredEmojis,\n emojiData.current.categories,\n columns\n );\n });\n resetSelection();\n });\n }, [columns, resetSelection]);\n\n const handleSearch = useCallback(\n (value: string) => {\n search.current = value;\n updateEmojis();\n },\n [updateEmojis]\n );\n\n const initializeEmojiData = useCallback(\n async (locale: string) => {\n try {\n emojiData.current = await getEmojiData(locale);\n updateEmojis();\n } catch (error) {\n setError(error as Error);\n }\n },\n [updateEmojis]\n );\n\n useEffect(() => {\n let idleCallbackId: number;\n const timeoutId = setTimeout(() => {\n idleCallbackId = requestIdleCallback(() => {\n initializeEmojiData(locale);\n });\n }, LOADING_MINIMUM_TIMEOUT);\n\n return () => {\n clearTimeout(timeoutId);\n cancelIdleCallback(idleCallbackId);\n };\n }, [locale]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n if (interaction === \"none\") {\n resetSelection();\n }\n }, [interaction]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <EmojiPickerContext.Provider\n value={{\n data: data as EmojiPickerData,\n error: error as undefined,\n isLoading: (!data && !error) as false,\n columns,\n onSearch: handleSearch,\n onEmojiSelect,\n selectCurrentEmoji,\n selectedRowIndex,\n selectedColumnIndex,\n moveSelection,\n setPointerSelection,\n interaction,\n setInteraction,\n }}\n >\n {children}\n </EmojiPickerContext.Provider>\n );\n}\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * The search input of the emoji picker. It also affects the focus and selection\n * within `EmojiPicker.Content`.\n *\n * @example\n * <EmojiPicker.Search />\n */\nconst EmojiPickerSearch = forwardRef<HTMLInputElement, EmojiPickerSearchProps>(\n ({ asChild, value, defaultValue, onChange, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"input\";\n const {\n onSearch,\n selectCurrentEmoji,\n moveSelection,\n interaction,\n setInteraction,\n } = useEmojiPicker();\n\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n onChange?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n const value = event.target.value;\n setInteraction(value ? \"keyboard\" : \"none\");\n onSearch(value);\n },\n [onChange, onSearch, setInteraction]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.isDefaultPrevented()) {\n return;\n }\n\n if (isKey(event, \"ArrowLeft\")) {\n moveSelection(\"left\", event);\n } else if (isKey(event, \"ArrowRight\")) {\n moveSelection(\"right\", event);\n } else if (isKey(event, \"ArrowUp\")) {\n moveSelection(\"up\", event);\n } else if (isKey(event, \"ArrowDown\")) {\n moveSelection(\"down\", event);\n } else if (isKey(event, \"Enter\")) {\n if (interaction !== \"none\") {\n event.preventDefault();\n selectCurrentEmoji();\n }\n }\n },\n [interaction, moveSelection, selectCurrentEmoji]\n );\n\n useEffect(() => {\n onSearch(\n value ? String(value) : defaultValue ? String(defaultValue) : \"\"\n );\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <Component\n type=\"search\"\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n);\n\nconst defaultContentComponents: EmojiPickerContentComponents = {\n CategoryHeader: ({ category, ...props }) => <div {...props}>{category}</div>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Row: ({ children, attributes, ...props }) => <div {...props}>{children}</div>,\n Emoji: ({ emoji, ...props }) => (\n <button {...props}>\n <EmojiPrimitive emoji={emoji} />\n </button>\n ),\n Loading: (props) => <div {...props} />,\n Empty: (props) => <div {...props} />,\n Grid: (props) => <div {...props} />,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Error: ({ error, ...props }) => <div {...props} />,\n};\n\nconst placeholderRowAttributes: EmojiPickerContentEmojiRowAttributes = {\n rowIndex: -1,\n categoryRowIndex: -1,\n categoryRowsCount: 0,\n};\n\n// About `data-testid={undefined}`: Virtuoso bakes test IDs into the components we pass\n// to it, so we manually remove them.\n\nconst VirtuosoScroller = forwardRef<HTMLDivElement, ScrollerProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div {...props} tabIndex={-1} data-testid={undefined} ref={forwardedRef}>\n {children}\n </div>\n );\n }\n);\n\nconst VirtuosoTopList = forwardRef<HTMLDivElement, TopItemListProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div {...props} data-testid={undefined} ref={forwardedRef}>\n {children}\n </div>\n );\n }\n);\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * The main content of the emoji picker, either displaying the emoji grid or various\n * alternative states (loading, empty, and error).\n *\n * @example\n * <EmojiPicker.Content\n * components={{\n * Loading: EmojiPickerLoading,\n * Empty: EmojiPickerEmpty,\n * Error: EmojiPickerError,\n * CategoryHeader: EmojiPickerCategoryHeader,\n * Grid: EmojiPickerGrid,\n * Row: EmojiPickerRow,\n * Emoji: EmojiPickerEmoji,\n * }}\n * />\n */\nconst EmojiPickerContent = forwardRef<HTMLDivElement, EmojiPickerContentProps>(\n ({ components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const virtuosoRef = useRef<GroupedVirtuosoHandle>(null);\n const placeholderContainerRef = useRef<HTMLDivElement>(null);\n const rowScrollMarginTopRef = useRef<number>(0);\n const rowScrollMarginBottomRef = useRef<number>(0);\n const categoryHeaderHeightRef = useRef<number>(0);\n const {\n data,\n error,\n isLoading,\n columns,\n onEmojiSelect,\n selectedColumnIndex,\n selectedRowIndex,\n setPointerSelection,\n interaction,\n setInteraction,\n } = useEmojiPicker();\n const selectedEmoji = useMemo(\n () => data?.rows[selectedRowIndex]?.[selectedColumnIndex],\n [data?.rows, selectedColumnIndex, selectedRowIndex]\n );\n const { Loading, Empty, Error, CategoryHeader, Grid, Row, Emoji } = useMemo(\n () => ({ ...defaultContentComponents, ...components }),\n [components]\n );\n const VirtuosoList = useMemo(\n () =>\n forwardRef<HTMLDivElement, VirtuosoListProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div\n role=\"grid\"\n aria-colcount={columns}\n {...props}\n data-testid={undefined}\n ref={forwardedRef}\n >\n {children}\n </div>\n );\n }\n ),\n [columns]\n );\n const placeholderColumns = useMemo(\n () => Array<string>(columns).fill(\"🌫️\"),\n [columns]\n );\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const handleEmojiPointerLeave = useCallback(() => {\n if (interaction === \"pointer\") {\n setInteraction(\"none\");\n }\n }, [interaction, setInteraction]);\n\n useLayoutEffect(() => {\n if (!placeholderContainerRef.current) {\n return;\n }\n\n const row = placeholderContainerRef.current.childNodes[0];\n const categoryHeader = placeholderContainerRef.current.childNodes[1];\n\n if (row instanceof HTMLElement) {\n const style = window.getComputedStyle(row);\n\n rowScrollMarginTopRef.current = parseFloat(style.scrollMarginTop);\n rowScrollMarginBottomRef.current = parseFloat(style.scrollMarginBottom);\n }\n\n if (categoryHeader instanceof HTMLElement) {\n categoryHeaderHeightRef.current = categoryHeader.offsetHeight;\n }\n }, []);\n\n // Customize `scrollIntoView` behavior to take into account category headers and margins\n const calculateViewLocation = useCallback(\n ({\n itemTop,\n itemBottom,\n viewportTop,\n viewportBottom,\n locationParams: { behavior, align, ...params },\n }: CalculateViewLocationParams) => {\n if (\n itemTop -\n (categoryHeaderHeightRef.current + rowScrollMarginTopRef.current) <\n viewportTop\n ) {\n return {\n ...params,\n behavior,\n align: align ?? \"start\",\n };\n }\n\n if (itemBottom > viewportBottom) {\n return {\n ...params,\n behavior,\n align: align ?? \"end\",\n offset: rowScrollMarginBottomRef.current,\n };\n }\n\n return null;\n },\n []\n );\n\n useEffect(() => {\n if (interaction === \"keyboard\") {\n virtuosoRef.current?.scrollIntoView({\n index: selectedRowIndex,\n behavior: \"auto\",\n calculateViewLocation,\n });\n }\n }, [interaction, selectedRowIndex, calculateViewLocation]);\n\n return (\n <Component {...props} ref={forwardedRef}>\n <div\n style={{\n visibility: \"hidden\",\n height: 0,\n }}\n ref={placeholderContainerRef}\n >\n {/* Virtualized rows are absolutely positioned so they won't make\n the container automatically pick up their width. To achieve\n an automatic width, we add a relative (but hidden) full row. */}\n <Row attributes={placeholderRowAttributes}>\n {placeholderColumns.map((placeholder, index) => (\n <Emoji emoji={placeholder} key={index} />\n ))}\n </Row>\n {/* We also add a hidden category header to get its computed height. */}\n <CategoryHeader category=\"Category\" />\n </div>\n {isLoading ? (\n <Loading />\n ) : error ? (\n <Error error={error} />\n ) : data.count === 0 ? (\n <Empty />\n ) : (\n <Grid>\n <GroupedVirtuoso\n ref={virtuosoRef}\n components={{\n Scroller: VirtuosoScroller,\n List: VirtuosoList,\n TopItemList: VirtuosoTopList,\n }}\n groupCounts={data.categoriesRowCounts}\n groupContent={(groupIndex) => {\n const category = data.categories[groupIndex];\n\n if (!category) {\n return null;\n }\n\n return <CategoryHeader category={category} />;\n }}\n itemContent={(rowIndex, groupIndex) => {\n const categoryRow = data.rows[rowIndex];\n const categoryRowIndex =\n data.categoriesRowIndices[groupIndex]?.indexOf(rowIndex);\n const categoryRowsCount = data.categoriesRowCounts[groupIndex];\n\n if (\n categoryRow === undefined ||\n categoryRowIndex === undefined ||\n categoryRowsCount === undefined\n ) {\n return null;\n }\n\n return (\n <Row\n attributes={{\n rowIndex,\n categoryRowIndex,\n categoryRowsCount,\n }}\n >\n {categoryRow.map((emoji, columnIndex) => {\n const isSelected =\n interaction !== \"none\" &&\n selectedColumnIndex === columnIndex &&\n selectedRowIndex === rowIndex;\n\n return (\n <Emoji\n key={emoji.emoji}\n role=\"gridcell\"\n aria-colindex={columnIndex}\n aria-selected={isSelected || undefined}\n data-selected={isSelected || undefined}\n onMouseDown={preventDefault}\n tabIndex={-1}\n onPointerEnter={() => {\n setPointerSelection(columnIndex, rowIndex);\n }}\n onPointerLeave={handleEmojiPointerLeave}\n onClick={(event) => {\n onEmojiSelect?.(emoji.emoji);\n event.stopPropagation();\n }}\n emoji={emoji.emoji}\n />\n );\n })}\n </Row>\n );\n }}\n />\n </Grid>\n )}\n {selectedEmoji && interaction !== \"none\" && (\n <div aria-live=\"polite\" style={visuallyHidden}>\n {selectedEmoji.name}\n </div>\n )}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n EmojiPickerRoot.displayName = EMOJIPICKER_ROOT_NAME;\n EmojiPickerContent.displayName = EMOJIPICKER_CONTENT_NAME;\n EmojiPickerSearch.displayName = EMOJIPICKER_SEARCH_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as EmojiPicker.*\nexport {\n EmojiPickerContent as Content,\n EmojiPickerRoot as Root,\n EmojiPickerSearch as Search,\n};\n"],"names":["useRef","useTransition","useState","useCallback","filterEmojis","generateEmojiPickerData","locale","getEmojiData","error","useEffect","requestIdleCallback","cancelIdleCallback","jsx","EmojiPickerContext","forwardRef","Slot","useEmojiPicker","value","isKey","EmojiPrimitive","useMemo","props","forwardedRef","useLayoutEffect","jsxs","GroupedVirtuoso","visuallyHidden"],"mappings":"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"}
|