beez-ui 0.6.2 → 0.8.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/CHANGELOG.md +150 -96
- package/README.md +33 -6
- package/dist/components/account-menu.d.ts +53 -0
- package/dist/components/account-menu.js +405 -0
- package/dist/components/alert.js +1 -1
- package/dist/components/animated-collapse.d.ts +19 -0
- package/dist/components/animated-collapse.js +81 -0
- package/dist/components/animated-count.d.ts +13 -0
- package/dist/components/animated-count.js +105 -0
- package/dist/components/animated-list-item.d.ts +25 -0
- package/dist/components/animated-list-item.js +132 -0
- package/dist/components/avatar.d.ts +2 -1
- package/dist/components/avatar.js +4 -3
- package/dist/components/bouncing-dots-loader.d.ts +19 -0
- package/dist/components/bouncing-dots-loader.js +47 -0
- package/dist/components/calendar.js +102 -0
- package/dist/components/carousel.js +61 -48
- package/dist/components/checkbox.js +1 -1
- package/dist/components/confirm-delete-button.d.ts +29 -0
- package/dist/components/confirm-delete-button.js +254 -0
- package/dist/components/data-table.js +34 -4
- package/dist/components/dropdown-menu.js +5 -2
- package/dist/components/empty-state.d.ts +24 -0
- package/dist/components/empty-state.js +37 -0
- package/dist/components/error-state.d.ts +20 -0
- package/dist/components/error-state.js +145 -0
- package/dist/components/external-browser-handoff.d.ts +27 -0
- package/dist/components/external-browser-handoff.js +306 -0
- package/dist/components/file-upload.d.ts +78 -0
- package/dist/components/file-upload.js +678 -0
- package/dist/components/filter-query-bar.js +11 -6
- package/dist/components/form.d.ts +5 -0
- package/dist/components/form.js +11 -9
- package/dist/components/info-popover.d.ts +23 -0
- package/dist/components/info-popover.js +158 -0
- package/dist/components/input-group.js +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/month-calendar-header.d.ts +65 -0
- package/dist/components/month-calendar-header.js +337 -0
- package/dist/components/month-grid.d.ts +59 -0
- package/dist/components/month-grid.js +301 -0
- package/dist/components/notification-bell.d.ts +50 -0
- package/dist/components/notification-bell.js +338 -0
- package/dist/components/notification-panel.d.ts +56 -0
- package/dist/components/notification-panel.js +281 -0
- package/dist/components/open-in-browser-cta.d.ts +22 -0
- package/dist/components/open-in-browser-cta.js +61 -0
- package/dist/components/pagination.d.ts +1 -0
- package/dist/components/pagination.js +9 -4
- package/dist/components/presence-swap.d.ts +22 -0
- package/dist/components/presence-swap.js +162 -0
- package/dist/components/progress-ring.d.ts +20 -0
- package/dist/components/progress-ring.js +53 -0
- package/dist/components/pwa-update-control.d.ts +18 -0
- package/dist/components/pwa-update-control.js +119 -0
- package/dist/components/radio-group.js +1 -1
- package/dist/components/reaction-button.d.ts +26 -0
- package/dist/components/reaction-button.js +114 -0
- package/dist/components/rich-link-editor.d.ts +25 -0
- package/dist/components/rich-link-editor.js +320 -0
- package/dist/components/rich-markdown-content.d.ts +10 -0
- package/dist/components/rich-markdown-content.js +56 -0
- package/dist/components/rich-text-content.d.ts +19 -0
- package/dist/components/rich-text-content.js +26 -0
- package/dist/components/select.js +1 -1
- package/dist/components/sheet.js +12 -9
- package/dist/components/sidebar.js +9 -5
- package/dist/components/skeleton.d.ts +6 -0
- package/dist/components/skeleton.js +7 -1
- package/dist/components/switch.js +1 -1
- package/dist/components/textarea.js +1 -1
- package/dist/components/typing-animation.js +42 -15
- package/dist/emoji-picker.d.ts +27 -0
- package/dist/emoji-picker.js +283 -0
- package/dist/hooks/use-horizontal-swipe.d.ts +23 -0
- package/dist/hooks/use-horizontal-swipe.js +80 -0
- package/dist/hooks/use-is-hydrated.d.ts +6 -0
- package/dist/hooks/use-is-hydrated.js +20 -0
- package/dist/hooks/use-minute-clock.d.ts +23 -0
- package/dist/hooks/use-minute-clock.js +147 -0
- package/dist/hooks/use-month-transition-direction.d.ts +21 -0
- package/dist/hooks/use-month-transition-direction.js +110 -0
- package/dist/hooks/use-rich-link-editor.d.ts +55 -0
- package/dist/hooks/use-rich-link-editor.js +515 -0
- package/dist/hooks/use-viewer-time-zone.d.ts +6 -0
- package/dist/hooks/use-viewer-time-zone.js +20 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +43 -0
- package/dist/lib/browser-clipboard.d.ts +13 -0
- package/dist/lib/browser-clipboard.js +48 -0
- package/dist/lib/browser-navigation.d.ts +21 -0
- package/dist/lib/browser-navigation.js +42 -0
- package/dist/lib/column-filter-value.d.ts +12 -0
- package/dist/lib/column-filter-value.js +52 -0
- package/dist/lib/file-acceptance.d.ts +43 -0
- package/dist/lib/file-acceptance.js +107 -0
- package/dist/lib/format-file-size.d.ts +16 -0
- package/dist/lib/format-file-size.js +34 -0
- package/dist/lib/fuzzy-search.d.ts +17 -0
- package/dist/lib/fuzzy-search.js +183 -0
- package/dist/lib/horizontal-swipe.d.ts +23 -0
- package/dist/lib/horizontal-swipe.js +29 -0
- package/dist/lib/in-app-browser.d.ts +35 -0
- package/dist/lib/in-app-browser.js +80 -0
- package/dist/lib/month-grid.d.ts +42 -0
- package/dist/lib/month-grid.js +74 -0
- package/dist/lib/name-initials.d.ts +7 -0
- package/dist/lib/name-initials.js +11 -0
- package/dist/lib/rich-text/link-markdown-constants.d.ts +147 -0
- package/dist/lib/rich-text/link-markdown-constants.js +458 -0
- package/dist/lib/rich-text/link-markdown-types.d.ts +53 -0
- package/dist/lib/rich-text/link-markdown-types.js +1 -0
- package/dist/lib/rich-text/link-markdown.d.ts +193 -0
- package/dist/lib/rich-text/link-markdown.js +592 -0
- package/dist/lib/rich-text/rich-markdown.d.ts +41 -0
- package/dist/lib/rich-text/rich-markdown.js +105 -0
- package/dist/lib/rich-text/rich-text-editor-dom.d.ts +26 -0
- package/dist/lib/rich-text/rich-text-editor-dom.js +79 -0
- package/dist/motion/glide-indicator.d.ts +37 -3
- package/dist/motion/glide-indicator.js +37 -3
- package/dist/motion/motion-slot.js +47 -18
- package/dist/motion/surface-keyframes.js +18 -6
- package/dist/motion/tokens.d.ts +41 -2
- package/dist/motion/tokens.js +40 -1
- package/dist/providers/beez-ui-provider.js +49 -17
- package/dist/styles.css +1 -1
- package/package.json +212 -2
|
@@ -3,6 +3,7 @@ import { c as _c } from "react/compiler-runtime";
|
|
|
3
3
|
import { useEffect, useRef, useState } from "react";
|
|
4
4
|
import { motion } from "motion/react";
|
|
5
5
|
import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
|
|
6
|
+
import { MOTION_TIMING } from "../motion/tokens.js";
|
|
6
7
|
import { cn } from "../lib/utils.js";
|
|
7
8
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
9
|
const motionElements = {
|
|
@@ -19,8 +20,23 @@ const motionElements = {
|
|
|
19
20
|
section: motion.section,
|
|
20
21
|
span: motion.span
|
|
21
22
|
};
|
|
23
|
+
/** Idle cursors fade out and back in, like a text editor's caret. */
|
|
24
|
+
const CURSOR_BLINK_OPACITY = [
|
|
25
|
+
1,
|
|
26
|
+
1,
|
|
27
|
+
0,
|
|
28
|
+
0,
|
|
29
|
+
1
|
|
30
|
+
];
|
|
31
|
+
const CURSOR_BLINK_TIMES = [
|
|
32
|
+
0,
|
|
33
|
+
.4,
|
|
34
|
+
.5,
|
|
35
|
+
.9,
|
|
36
|
+
1
|
|
37
|
+
];
|
|
22
38
|
export function TypingAnimation(t0) {
|
|
23
|
-
const $ = _c(
|
|
39
|
+
const $ = _c(68);
|
|
24
40
|
let children;
|
|
25
41
|
let className;
|
|
26
42
|
let deleteSpeed;
|
|
@@ -293,6 +309,7 @@ export function TypingAnimation(t0) {
|
|
|
293
309
|
const currentWordGraphemes = t19;
|
|
294
310
|
const isComplete = !loop && currentWordIndex === wordsToAnimate.length - 1 && currentCharIndex >= currentWordGraphemes.length && phase !== "deleting";
|
|
295
311
|
const shouldShowCursor = showCursor && !shouldReduceMotion && !isComplete && (hasMultipleWords || loop || currentCharIndex < currentWordGraphemes.length);
|
|
312
|
+
const isCursorIdle = !shouldStart || phase === "pause" || displayedText === "";
|
|
296
313
|
let t20;
|
|
297
314
|
if ($[51] !== cursorStyle) {
|
|
298
315
|
t20 = () => {
|
|
@@ -328,20 +345,30 @@ export function TypingAnimation(t0) {
|
|
|
328
345
|
t23 = $[56];
|
|
329
346
|
}
|
|
330
347
|
let t24;
|
|
331
|
-
if ($[57] !== blinkCursor || $[58] !== getCursorChar || $[59] !== shouldShowCursor) {
|
|
332
|
-
t24 = shouldShowCursor && /* @__PURE__ */ _jsx(
|
|
333
|
-
|
|
348
|
+
if ($[57] !== blinkCursor || $[58] !== getCursorChar || $[59] !== isCursorIdle || $[60] !== shouldShowCursor) {
|
|
349
|
+
t24 = shouldShowCursor && /* @__PURE__ */ _jsx(motion.span, {
|
|
350
|
+
"aria-hidden": "true",
|
|
351
|
+
"data-slot": "typing-animation-cursor",
|
|
352
|
+
className: "inline-block",
|
|
353
|
+
animate: { opacity: blinkCursor && isCursorIdle ? CURSOR_BLINK_OPACITY : 1 },
|
|
354
|
+
transition: blinkCursor && isCursorIdle ? {
|
|
355
|
+
duration: MOTION_TIMING.cursorBlink,
|
|
356
|
+
times: CURSOR_BLINK_TIMES,
|
|
357
|
+
repeat: Infinity,
|
|
358
|
+
ease: "easeInOut"
|
|
359
|
+
} : { duration: MOTION_TIMING.fast },
|
|
334
360
|
children: getCursorChar()
|
|
335
361
|
});
|
|
336
362
|
$[57] = blinkCursor;
|
|
337
363
|
$[58] = getCursorChar;
|
|
338
|
-
$[59] =
|
|
339
|
-
$[60] =
|
|
364
|
+
$[59] = isCursorIdle;
|
|
365
|
+
$[60] = shouldShowCursor;
|
|
366
|
+
$[61] = t24;
|
|
340
367
|
} else {
|
|
341
|
-
t24 = $[
|
|
368
|
+
t24 = $[61];
|
|
342
369
|
}
|
|
343
370
|
let t25;
|
|
344
|
-
if ($[
|
|
371
|
+
if ($[62] !== MotionComponent || $[63] !== displayedText || $[64] !== props || $[65] !== t23 || $[66] !== t24) {
|
|
345
372
|
t25 = /* @__PURE__ */ _jsxs(MotionComponent, {
|
|
346
373
|
ref: elementRef,
|
|
347
374
|
"data-slot": "typing-animation",
|
|
@@ -349,14 +376,14 @@ export function TypingAnimation(t0) {
|
|
|
349
376
|
...props,
|
|
350
377
|
children: [displayedText, t24]
|
|
351
378
|
});
|
|
352
|
-
$[
|
|
353
|
-
$[
|
|
354
|
-
$[
|
|
355
|
-
$[
|
|
356
|
-
$[
|
|
357
|
-
$[
|
|
379
|
+
$[62] = MotionComponent;
|
|
380
|
+
$[63] = displayedText;
|
|
381
|
+
$[64] = props;
|
|
382
|
+
$[65] = t23;
|
|
383
|
+
$[66] = t24;
|
|
384
|
+
$[67] = t25;
|
|
358
385
|
} else {
|
|
359
|
-
t25 = $[
|
|
386
|
+
t25 = $[67];
|
|
360
387
|
}
|
|
361
388
|
return t25;
|
|
362
389
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface EmojiPickerLabels {
|
|
2
|
+
/** Accessible name of the trigger. */
|
|
3
|
+
chooseEmoji: string;
|
|
4
|
+
/** Accessible name of the popover. */
|
|
5
|
+
picker: string;
|
|
6
|
+
searchPlaceholder: string;
|
|
7
|
+
loading: string;
|
|
8
|
+
}
|
|
9
|
+
export interface EmojiPickerProps {
|
|
10
|
+
/** Currently selected emoji; empty shows a placeholder icon. */
|
|
11
|
+
value: string;
|
|
12
|
+
onChange: (emoji: string) => void;
|
|
13
|
+
/** Visible label of the field. */
|
|
14
|
+
label: string;
|
|
15
|
+
/** Keeps the label for assistive technology but hides it visually. */
|
|
16
|
+
isLabelVisuallyHidden?: boolean;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
labels?: Partial<EmojiPickerLabels>;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Renders an outline trigger showing the current emoji that opens a searchable emoji popover. The
|
|
23
|
+
* chosen emoji swaps in with a short cross-fade; the picker follows the resolved color theme.
|
|
24
|
+
* @param props - Current value, change handler, label and optional copy.
|
|
25
|
+
* @returns The labelled emoji picker.
|
|
26
|
+
*/
|
|
27
|
+
export declare function EmojiPicker({ value, onChange, label, isLabelVisuallyHidden, disabled, labels, className, }: EmojiPickerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { c as _c } from "react/compiler-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Isolates the optional `emoji-picker-react` peer from the package root: only apps importing
|
|
5
|
+
* `beez-ui/emoji-picker` need it installed.
|
|
6
|
+
*/
|
|
7
|
+
import { lazy, Suspense, useState } from "react";
|
|
8
|
+
import { SmilePlusIcon } from "lucide-react";
|
|
9
|
+
import { useTheme } from "next-themes";
|
|
10
|
+
import { cn } from "./lib/utils.js";
|
|
11
|
+
import { Button } from "./components/button.js";
|
|
12
|
+
import { Popover, PopoverContent, PopoverTrigger } from "./components/popover.js";
|
|
13
|
+
import { PresenceSwap } from "./components/presence-swap.js";
|
|
14
|
+
import { BouncingDotsLoader } from "./components/bouncing-dots-loader.js";
|
|
15
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
16
|
+
/** Loads the picker bundle (and its emoji data) only when the popover opens for the first time. */
|
|
17
|
+
const LazyEmojiPickerReact = lazy(async () => {
|
|
18
|
+
const emojiPickerModule = await import("emoji-picker-react");
|
|
19
|
+
const moduleDefault = emojiPickerModule.default;
|
|
20
|
+
return { default: "default" in moduleDefault ? moduleDefault.default : moduleDefault };
|
|
21
|
+
});
|
|
22
|
+
const EMOJI_PICKER_HEIGHT_PX = 360;
|
|
23
|
+
/** Fills the popover, which already caps its width to the viewport on phones. */
|
|
24
|
+
const EMOJI_PICKER_WIDTH = "100%";
|
|
25
|
+
/** Presence key of the placeholder icon shown before an emoji is chosen. */
|
|
26
|
+
const EMPTY_SELECTION_KEY = "empty";
|
|
27
|
+
const DARK_THEME = "dark";
|
|
28
|
+
/**
|
|
29
|
+
* Picker options as the string values of the library enums. Only types are imported, so the
|
|
30
|
+
* library is not evaluated until the lazy import runs (never during server rendering).
|
|
31
|
+
*/
|
|
32
|
+
const EMOJI_PICKER_OPTIONS = {
|
|
33
|
+
emojiStyle: "apple",
|
|
34
|
+
defaultSkinTone: "neutral",
|
|
35
|
+
skinTonePickerLocation: "SEARCH",
|
|
36
|
+
suggestedEmojisMode: "recent",
|
|
37
|
+
darkTheme: "dark",
|
|
38
|
+
lightTheme: "light"
|
|
39
|
+
};
|
|
40
|
+
const EMOJI_PICKER_DEFAULT_LABELS = {
|
|
41
|
+
chooseEmoji: "Elegir emoji",
|
|
42
|
+
picker: "Selector de emojis",
|
|
43
|
+
searchPlaceholder: "Buscar emoji",
|
|
44
|
+
loading: "Cargando emojis..."
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Renders an outline trigger showing the current emoji that opens a searchable emoji popover. The
|
|
48
|
+
* chosen emoji swaps in with a short cross-fade; the picker follows the resolved color theme.
|
|
49
|
+
* @param props - Current value, change handler, label and optional copy.
|
|
50
|
+
* @returns The labelled emoji picker.
|
|
51
|
+
*/
|
|
52
|
+
export function EmojiPicker(t0) {
|
|
53
|
+
const $ = _c(46);
|
|
54
|
+
const { value, onChange, label, isLabelVisuallyHidden: t1, disabled: t2, labels, className } = t0;
|
|
55
|
+
const isLabelVisuallyHidden = t1 === undefined ? false : t1;
|
|
56
|
+
const disabled = t2 === undefined ? false : t2;
|
|
57
|
+
let t3;
|
|
58
|
+
if ($[0] !== labels) {
|
|
59
|
+
t3 = {
|
|
60
|
+
...EMOJI_PICKER_DEFAULT_LABELS,
|
|
61
|
+
...labels
|
|
62
|
+
};
|
|
63
|
+
$[0] = labels;
|
|
64
|
+
$[1] = t3;
|
|
65
|
+
} else {
|
|
66
|
+
t3 = $[1];
|
|
67
|
+
}
|
|
68
|
+
const resolvedLabels = t3;
|
|
69
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
70
|
+
const { resolvedTheme } = useTheme();
|
|
71
|
+
let t4;
|
|
72
|
+
if ($[2] !== value) {
|
|
73
|
+
t4 = value.trim();
|
|
74
|
+
$[2] = value;
|
|
75
|
+
$[3] = t4;
|
|
76
|
+
} else {
|
|
77
|
+
t4 = $[3];
|
|
78
|
+
}
|
|
79
|
+
const selectedEmoji = t4;
|
|
80
|
+
let t5;
|
|
81
|
+
if ($[4] !== onChange) {
|
|
82
|
+
t5 = (emojiData) => {
|
|
83
|
+
onChange(emojiData.emoji);
|
|
84
|
+
setIsOpen(false);
|
|
85
|
+
};
|
|
86
|
+
$[4] = onChange;
|
|
87
|
+
$[5] = t5;
|
|
88
|
+
} else {
|
|
89
|
+
t5 = $[5];
|
|
90
|
+
}
|
|
91
|
+
const handleEmojiClick = t5;
|
|
92
|
+
let t6;
|
|
93
|
+
if ($[6] !== className) {
|
|
94
|
+
t6 = cn("grid w-fit min-w-0 gap-[0.4rem]", className);
|
|
95
|
+
$[6] = className;
|
|
96
|
+
$[7] = t6;
|
|
97
|
+
} else {
|
|
98
|
+
t6 = $[7];
|
|
99
|
+
}
|
|
100
|
+
const t7 = isLabelVisuallyHidden && "sr-only";
|
|
101
|
+
let t8;
|
|
102
|
+
if ($[8] !== t7) {
|
|
103
|
+
t8 = cn("text-[0.82rem] leading-tight font-semibold text-muted-foreground", t7);
|
|
104
|
+
$[8] = t7;
|
|
105
|
+
$[9] = t8;
|
|
106
|
+
} else {
|
|
107
|
+
t8 = $[9];
|
|
108
|
+
}
|
|
109
|
+
let t9;
|
|
110
|
+
if ($[10] !== label || $[11] !== t8) {
|
|
111
|
+
t9 = /* @__PURE__ */ _jsx("span", {
|
|
112
|
+
className: t8,
|
|
113
|
+
children: label
|
|
114
|
+
});
|
|
115
|
+
$[10] = label;
|
|
116
|
+
$[11] = t8;
|
|
117
|
+
$[12] = t9;
|
|
118
|
+
} else {
|
|
119
|
+
t9 = $[12];
|
|
120
|
+
}
|
|
121
|
+
const t10 = selectedEmoji || EMPTY_SELECTION_KEY;
|
|
122
|
+
let t11;
|
|
123
|
+
if ($[13] !== selectedEmoji) {
|
|
124
|
+
t11 = selectedEmoji || /* @__PURE__ */ _jsx(SmilePlusIcon, {});
|
|
125
|
+
$[13] = selectedEmoji;
|
|
126
|
+
$[14] = t11;
|
|
127
|
+
} else {
|
|
128
|
+
t11 = $[14];
|
|
129
|
+
}
|
|
130
|
+
let t12;
|
|
131
|
+
if ($[15] !== t11) {
|
|
132
|
+
t12 = /* @__PURE__ */ _jsx("span", {
|
|
133
|
+
"aria-hidden": true,
|
|
134
|
+
children: t11
|
|
135
|
+
});
|
|
136
|
+
$[15] = t11;
|
|
137
|
+
$[16] = t12;
|
|
138
|
+
} else {
|
|
139
|
+
t12 = $[16];
|
|
140
|
+
}
|
|
141
|
+
let t13;
|
|
142
|
+
if ($[17] !== t10 || $[18] !== t12) {
|
|
143
|
+
t13 = /* @__PURE__ */ _jsx(PresenceSwap, {
|
|
144
|
+
as: "span",
|
|
145
|
+
className: "inline-grid min-h-5 min-w-5 place-items-center text-[1.15rem] leading-none",
|
|
146
|
+
mode: "popLayout",
|
|
147
|
+
presenceKey: t10,
|
|
148
|
+
children: t12
|
|
149
|
+
});
|
|
150
|
+
$[17] = t10;
|
|
151
|
+
$[18] = t12;
|
|
152
|
+
$[19] = t13;
|
|
153
|
+
} else {
|
|
154
|
+
t13 = $[19];
|
|
155
|
+
}
|
|
156
|
+
let t14;
|
|
157
|
+
if ($[20] !== disabled || $[21] !== resolvedLabels.chooseEmoji || $[22] !== t13) {
|
|
158
|
+
t14 = /* @__PURE__ */ _jsx(PopoverTrigger, {
|
|
159
|
+
asChild: true,
|
|
160
|
+
children: /* @__PURE__ */ _jsx(Button, {
|
|
161
|
+
"aria-label": resolvedLabels.chooseEmoji,
|
|
162
|
+
className: "min-h-[2.7rem] w-fit min-w-[3.25rem] justify-center gap-[0.55rem] border-border bg-background text-[0.95rem] text-foreground data-[state=open]:border-ring data-[state=open]:shadow-[0_0_0_2px_color-mix(in_srgb,var(--ring)_18%,transparent)]",
|
|
163
|
+
disabled,
|
|
164
|
+
type: "button",
|
|
165
|
+
variant: "outline",
|
|
166
|
+
children: t13
|
|
167
|
+
})
|
|
168
|
+
});
|
|
169
|
+
$[20] = disabled;
|
|
170
|
+
$[21] = resolvedLabels.chooseEmoji;
|
|
171
|
+
$[22] = t13;
|
|
172
|
+
$[23] = t14;
|
|
173
|
+
} else {
|
|
174
|
+
t14 = $[23];
|
|
175
|
+
}
|
|
176
|
+
let t15;
|
|
177
|
+
if ($[24] !== resolvedLabels.loading) {
|
|
178
|
+
t15 = /* @__PURE__ */ _jsx(BouncingDotsLoader, {
|
|
179
|
+
className: "py-10",
|
|
180
|
+
label: resolvedLabels.loading,
|
|
181
|
+
size: "sm"
|
|
182
|
+
});
|
|
183
|
+
$[24] = resolvedLabels.loading;
|
|
184
|
+
$[25] = t15;
|
|
185
|
+
} else {
|
|
186
|
+
t15 = $[25];
|
|
187
|
+
}
|
|
188
|
+
let t16;
|
|
189
|
+
if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
|
|
190
|
+
t16 = [];
|
|
191
|
+
$[26] = t16;
|
|
192
|
+
} else {
|
|
193
|
+
t16 = $[26];
|
|
194
|
+
}
|
|
195
|
+
let t17;
|
|
196
|
+
if ($[27] === Symbol.for("react.memo_cache_sentinel")) {
|
|
197
|
+
t17 = { showPreview: false };
|
|
198
|
+
$[27] = t17;
|
|
199
|
+
} else {
|
|
200
|
+
t17 = $[27];
|
|
201
|
+
}
|
|
202
|
+
const t18 = resolvedTheme === DARK_THEME ? EMOJI_PICKER_OPTIONS.darkTheme : EMOJI_PICKER_OPTIONS.lightTheme;
|
|
203
|
+
let t19;
|
|
204
|
+
if ($[28] !== handleEmojiClick || $[29] !== resolvedLabels.searchPlaceholder || $[30] !== t18) {
|
|
205
|
+
t19 = /* @__PURE__ */ _jsx(LazyEmojiPickerReact, {
|
|
206
|
+
autoFocusSearch: true,
|
|
207
|
+
customEmojis: t16,
|
|
208
|
+
defaultSkinTone: EMOJI_PICKER_OPTIONS.defaultSkinTone,
|
|
209
|
+
emojiStyle: EMOJI_PICKER_OPTIONS.emojiStyle,
|
|
210
|
+
height: EMOJI_PICKER_HEIGHT_PX,
|
|
211
|
+
lazyLoadEmojis: true,
|
|
212
|
+
onEmojiClick: handleEmojiClick,
|
|
213
|
+
previewConfig: t17,
|
|
214
|
+
searchPlaceholder: resolvedLabels.searchPlaceholder,
|
|
215
|
+
skinTonePickerLocation: EMOJI_PICKER_OPTIONS.skinTonePickerLocation,
|
|
216
|
+
suggestedEmojisMode: EMOJI_PICKER_OPTIONS.suggestedEmojisMode,
|
|
217
|
+
theme: t18,
|
|
218
|
+
width: EMOJI_PICKER_WIDTH
|
|
219
|
+
});
|
|
220
|
+
$[28] = handleEmojiClick;
|
|
221
|
+
$[29] = resolvedLabels.searchPlaceholder;
|
|
222
|
+
$[30] = t18;
|
|
223
|
+
$[31] = t19;
|
|
224
|
+
} else {
|
|
225
|
+
t19 = $[31];
|
|
226
|
+
}
|
|
227
|
+
let t20;
|
|
228
|
+
if ($[32] !== t15 || $[33] !== t19) {
|
|
229
|
+
t20 = /* @__PURE__ */ _jsx(Suspense, {
|
|
230
|
+
fallback: t15,
|
|
231
|
+
children: t19
|
|
232
|
+
});
|
|
233
|
+
$[32] = t15;
|
|
234
|
+
$[33] = t19;
|
|
235
|
+
$[34] = t20;
|
|
236
|
+
} else {
|
|
237
|
+
t20 = $[34];
|
|
238
|
+
}
|
|
239
|
+
let t21;
|
|
240
|
+
if ($[35] !== resolvedLabels.picker || $[36] !== t20) {
|
|
241
|
+
t21 = /* @__PURE__ */ _jsx(PopoverContent, {
|
|
242
|
+
"data-slot": "emoji-picker-content",
|
|
243
|
+
align: "start",
|
|
244
|
+
"aria-label": resolvedLabels.picker,
|
|
245
|
+
className: "w-[min(20rem,calc(100vw-2rem))] overflow-hidden p-0",
|
|
246
|
+
children: t20
|
|
247
|
+
});
|
|
248
|
+
$[35] = resolvedLabels.picker;
|
|
249
|
+
$[36] = t20;
|
|
250
|
+
$[37] = t21;
|
|
251
|
+
} else {
|
|
252
|
+
t21 = $[37];
|
|
253
|
+
}
|
|
254
|
+
let t22;
|
|
255
|
+
if ($[38] !== isOpen || $[39] !== t14 || $[40] !== t21) {
|
|
256
|
+
t22 = /* @__PURE__ */ _jsxs(Popover, {
|
|
257
|
+
open: isOpen,
|
|
258
|
+
onOpenChange: setIsOpen,
|
|
259
|
+
children: [t14, t21]
|
|
260
|
+
});
|
|
261
|
+
$[38] = isOpen;
|
|
262
|
+
$[39] = t14;
|
|
263
|
+
$[40] = t21;
|
|
264
|
+
$[41] = t22;
|
|
265
|
+
} else {
|
|
266
|
+
t22 = $[41];
|
|
267
|
+
}
|
|
268
|
+
let t23;
|
|
269
|
+
if ($[42] !== t22 || $[43] !== t6 || $[44] !== t9) {
|
|
270
|
+
t23 = /* @__PURE__ */ _jsxs("div", {
|
|
271
|
+
"data-slot": "emoji-picker",
|
|
272
|
+
className: t6,
|
|
273
|
+
children: [t9, t22]
|
|
274
|
+
});
|
|
275
|
+
$[42] = t22;
|
|
276
|
+
$[43] = t6;
|
|
277
|
+
$[44] = t9;
|
|
278
|
+
$[45] = t23;
|
|
279
|
+
} else {
|
|
280
|
+
t23 = $[45];
|
|
281
|
+
}
|
|
282
|
+
return t23;
|
|
283
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Recognizes one-finger horizontal swipes on touch surfaces such as pagers and calendars. */
|
|
2
|
+
import { type TouchEvent } from "react";
|
|
3
|
+
import { type HorizontalSwipeDirection } from "../lib/horizontal-swipe.js";
|
|
4
|
+
/**
|
|
5
|
+
* Touch handlers to spread on the swipe surface.
|
|
6
|
+
*/
|
|
7
|
+
export type HorizontalSwipeHandlers = {
|
|
8
|
+
onTouchCancel: () => void;
|
|
9
|
+
onTouchEnd: (event: TouchEvent<HTMLElement>) => void;
|
|
10
|
+
onTouchStart: (event: TouchEvent<HTMLElement>) => void;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Detects horizontal one-finger swipes. Touch events are used instead of
|
|
14
|
+
* Pointer Events because browsers fire `pointercancel` as soon as they start
|
|
15
|
+
* scrolling, and WebKit (iOS Safari and every iOS browser) has only partial
|
|
16
|
+
* `touch-action` support to prevent it, while `touchend` is delivered on
|
|
17
|
+
* both engines. The handlers never call `preventDefault`, so native vertical
|
|
18
|
+
* scrolling and pinch-zoom keep working; mouse drags never trigger a swipe.
|
|
19
|
+
*
|
|
20
|
+
* @param onSwipe - Called once per recognised swipe.
|
|
21
|
+
* @returns Handlers for the swipe surface.
|
|
22
|
+
*/
|
|
23
|
+
export declare function useHorizontalSwipe(onSwipe: (direction: HorizontalSwipeDirection) => void): HorizontalSwipeHandlers;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { c as _c } from "react/compiler-runtime";
|
|
3
|
+
/** Recognizes one-finger horizontal swipes on touch surfaces such as pagers and calendars. */
|
|
4
|
+
import { useRef } from "react";
|
|
5
|
+
import { resolveHorizontalSwipe } from "../lib/horizontal-swipe.js";
|
|
6
|
+
/**
|
|
7
|
+
* Detects horizontal one-finger swipes. Touch events are used instead of
|
|
8
|
+
* Pointer Events because browsers fire `pointercancel` as soon as they start
|
|
9
|
+
* scrolling, and WebKit (iOS Safari and every iOS browser) has only partial
|
|
10
|
+
* `touch-action` support to prevent it, while `touchend` is delivered on
|
|
11
|
+
* both engines. The handlers never call `preventDefault`, so native vertical
|
|
12
|
+
* scrolling and pinch-zoom keep working; mouse drags never trigger a swipe.
|
|
13
|
+
*
|
|
14
|
+
* @param onSwipe - Called once per recognised swipe.
|
|
15
|
+
* @returns Handlers for the swipe surface.
|
|
16
|
+
*/
|
|
17
|
+
export function useHorizontalSwipe(onSwipe) {
|
|
18
|
+
const $ = _c(6);
|
|
19
|
+
const swipeStartRef = useRef(null);
|
|
20
|
+
let t0;
|
|
21
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
22
|
+
t0 = () => {
|
|
23
|
+
swipeStartRef.current = null;
|
|
24
|
+
};
|
|
25
|
+
$[0] = t0;
|
|
26
|
+
} else {
|
|
27
|
+
t0 = $[0];
|
|
28
|
+
}
|
|
29
|
+
let t1;
|
|
30
|
+
if ($[1] !== onSwipe) {
|
|
31
|
+
t1 = (event) => {
|
|
32
|
+
const swipeStart = swipeStartRef.current;
|
|
33
|
+
const endTouch = swipeStart ? Array.from(event.changedTouches).find((touch) => touch.identifier === swipeStart.identifier) : undefined;
|
|
34
|
+
swipeStartRef.current = null;
|
|
35
|
+
if (!swipeStart || !endTouch) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const direction = resolveHorizontalSwipe({
|
|
39
|
+
deltaX: endTouch.clientX - swipeStart.x,
|
|
40
|
+
deltaY: endTouch.clientY - swipeStart.y,
|
|
41
|
+
durationMs: event.timeStamp - swipeStart.startTime
|
|
42
|
+
});
|
|
43
|
+
if (direction) {
|
|
44
|
+
onSwipe(direction);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
$[1] = onSwipe;
|
|
48
|
+
$[2] = t1;
|
|
49
|
+
} else {
|
|
50
|
+
t1 = $[2];
|
|
51
|
+
}
|
|
52
|
+
let t2;
|
|
53
|
+
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
|
54
|
+
t2 = (event_0) => {
|
|
55
|
+
const [firstTouch] = Array.from(event_0.touches);
|
|
56
|
+
swipeStartRef.current = event_0.touches.length === 1 && firstTouch ? {
|
|
57
|
+
identifier: firstTouch.identifier,
|
|
58
|
+
startTime: event_0.timeStamp,
|
|
59
|
+
x: firstTouch.clientX,
|
|
60
|
+
y: firstTouch.clientY
|
|
61
|
+
} : null;
|
|
62
|
+
};
|
|
63
|
+
$[3] = t2;
|
|
64
|
+
} else {
|
|
65
|
+
t2 = $[3];
|
|
66
|
+
}
|
|
67
|
+
let t3;
|
|
68
|
+
if ($[4] !== t1) {
|
|
69
|
+
t3 = {
|
|
70
|
+
onTouchCancel: t0,
|
|
71
|
+
onTouchEnd: t1,
|
|
72
|
+
onTouchStart: t2
|
|
73
|
+
};
|
|
74
|
+
$[4] = t1;
|
|
75
|
+
$[5] = t3;
|
|
76
|
+
} else {
|
|
77
|
+
t3 = $[5];
|
|
78
|
+
}
|
|
79
|
+
return t3;
|
|
80
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hydration store: the server snapshot is `false` and the client snapshot is
|
|
3
|
+
* `true`, so the first client render still matches the server markup and the
|
|
4
|
+
* component learns it is hydrated on the very next render without an effect.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useIsHydrated(): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/** Tells hydrated client renders apart from server and hydration renders without an effect. */
|
|
3
|
+
import { useSyncExternalStore } from "react";
|
|
4
|
+
function subscribeToNothing() {
|
|
5
|
+
return () => undefined;
|
|
6
|
+
}
|
|
7
|
+
function getHydratedSnapshot() {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
function getServerHydratedSnapshot() {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Hydration store: the server snapshot is `false` and the client snapshot is
|
|
15
|
+
* `true`, so the first client render still matches the server markup and the
|
|
16
|
+
* component learns it is hydrated on the very next render without an effect.
|
|
17
|
+
*/
|
|
18
|
+
export function useIsHydrated() {
|
|
19
|
+
return useSyncExternalStore(subscribeToNothing, getHydratedSnapshot, getServerHydratedSnapshot);
|
|
20
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Moves the clock forward to `instantTime` (epoch ms) and re-renders every
|
|
3
|
+
* consumer. Earlier instants are ignored, so the clock never goes back. Use
|
|
4
|
+
* it when a scheduled boundary is reached or the server proved that an
|
|
5
|
+
* instant already passed (for example an occurrence it reported as ended
|
|
6
|
+
* while the local clock still lagged behind).
|
|
7
|
+
*
|
|
8
|
+
* @param instantTime - Instant the clock must reach, in epoch milliseconds.
|
|
9
|
+
*/
|
|
10
|
+
export declare function advanceMinuteClockTo(instantTime: number): void;
|
|
11
|
+
/**
|
|
12
|
+
* Current time, refreshed on every minute boundary and at the exact instant of
|
|
13
|
+
* each wake-up time that falls before the next boundary. Between boundaries it
|
|
14
|
+
* holds the minute (or the last wake-up instant) it settled on. Returns null
|
|
15
|
+
* during server rendering and hydration so time-dependent UI never produces a
|
|
16
|
+
* server/client markup mismatch; it settles to a number right after mount.
|
|
17
|
+
*
|
|
18
|
+
* @param wakeUpTimes - Instants (epoch ms) where time-dependent UI changes,
|
|
19
|
+
* such as the end of an occurrence on screen; the clock re-renders exactly
|
|
20
|
+
* then instead of waiting for the next minute.
|
|
21
|
+
* @returns The clock value in epoch milliseconds, or null before hydration.
|
|
22
|
+
*/
|
|
23
|
+
export declare function useMinuteClock(wakeUpTimes?: readonly number[]): number | null;
|