@botiverse/raft-ui 0.35.0 → 0.36.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 +39 -0
- package/dist/foundation.css +4 -1
- package/dist/{inbox-item-CQJIhaym.d.mts → inbox-item-B8eXIikq.d.mts} +73 -1
- package/dist/{inbox-item-Cgu0ERol.mjs → inbox-item-DIUkRiT4.mjs} +630 -2
- package/dist/index.d.mts +50 -8
- package/dist/index.mjs +287 -81
- package/dist/styles.css +32 -0
- package/dist/tokens.json +14 -0
- package/dist/wip.d.mts +334 -3
- package/dist/wip.mjs +253 -2
- package/package.json +1 -1
|
@@ -14,13 +14,14 @@ import { ScrollArea } from "@base-ui/react/scroll-area";
|
|
|
14
14
|
import { Avatar } from "@base-ui/react";
|
|
15
15
|
import { Menu } from "@base-ui/react/menu";
|
|
16
16
|
import { Popover } from "@base-ui/react/popover";
|
|
17
|
-
import { PointerSensor, TouchSensor, useSensor } from "@dnd-kit/core";
|
|
17
|
+
import { DragOverlay, KeyboardSensor, PointerSensor, TouchSensor, defaultDropAnimationSideEffects, useDndContext, useSensor, useSensors } from "@dnd-kit/core";
|
|
18
18
|
import { PreviewCard } from "@base-ui/react/preview-card";
|
|
19
19
|
import { Input } from "@base-ui/react/input";
|
|
20
20
|
import { Radio } from "@base-ui/react/radio";
|
|
21
21
|
import { RadioGroup } from "@base-ui/react/radio-group";
|
|
22
22
|
import { Toggle } from "@base-ui/react/toggle";
|
|
23
23
|
import { Toolbar } from "@base-ui/react/toolbar";
|
|
24
|
+
import { sortableKeyboardCoordinates } from "@dnd-kit/sortable";
|
|
24
25
|
//#region src/lib/decision-width.ts
|
|
25
26
|
/**
|
|
26
27
|
* The width of every decision dialog (dialog.md#variants): AlertDialog and a
|
|
@@ -2563,6 +2564,8 @@ function MobileNavLabel({ className, render, ...props }) {
|
|
|
2563
2564
|
* touch on its distance and this sensor would never run.
|
|
2564
2565
|
*/
|
|
2565
2566
|
const TOUCH_DRAG_HOLD_MS = 500;
|
|
2567
|
+
const TOUCH_DRAG_DISTANCE_PX = 10;
|
|
2568
|
+
const TOUCH_DRAG_TOLERANCE_PX = 10;
|
|
2566
2569
|
const holds = /* @__PURE__ */ new WeakMap();
|
|
2567
2570
|
function touchPoint(event) {
|
|
2568
2571
|
const touch = event.touches?.[0] ?? event.changedTouches?.[0];
|
|
@@ -5753,6 +5756,631 @@ function MessageListJumpPillDismiss({ className, children, render, nativeButton,
|
|
|
5753
5756
|
});
|
|
5754
5757
|
}
|
|
5755
5758
|
//#endregion
|
|
5759
|
+
//#region src/components/drag/drag-announcements.ts
|
|
5760
|
+
function at({ place, position, count }) {
|
|
5761
|
+
const where = position == null ? "" : count == null ? `position ${position}` : `position ${position} of ${count}`;
|
|
5762
|
+
if (!place) return where;
|
|
5763
|
+
return where ? `${place}, ${where}` : place;
|
|
5764
|
+
}
|
|
5765
|
+
function sentence(text) {
|
|
5766
|
+
return /[.!?]$/.test(text) ? text : `${text}.`;
|
|
5767
|
+
}
|
|
5768
|
+
const DEFAULT_DRAG_MESSAGES = {
|
|
5769
|
+
instructions: "To pick up an item, press Space. Use the arrow keys to move it, Space to drop it, Escape to cancel.",
|
|
5770
|
+
pickedUp: ({ name, ...place }) => at(place) ? `Picked up ${name}. Over ${at(place)}.` : `Picked up ${name}.`,
|
|
5771
|
+
over: ({ name: _name, ...place }) => `Over ${at(place)}.`,
|
|
5772
|
+
notOver: () => "Not over a place. Dropping now cancels.",
|
|
5773
|
+
refused: ({ name, place, reason }) => `${name} can't go to ${place}. ${reason}`,
|
|
5774
|
+
dropped: ({ name, ...place }) => `Dropped ${name} in ${at(place)}.`,
|
|
5775
|
+
cancelled: ({ name, ...place }) => at(place) ? `Cancelled. ${name} is back in ${at(place)}.` : `Cancelled. ${name} is back.`,
|
|
5776
|
+
refusedDrop: ({ reason, ...rest }) => `${sentence(reason)} ${DEFAULT_DRAG_MESSAGES.cancelled(rest)}`
|
|
5777
|
+
};
|
|
5778
|
+
/** Merges your messages over the English defaults. */
|
|
5779
|
+
function dragMessages(messages) {
|
|
5780
|
+
return messages ? {
|
|
5781
|
+
...DEFAULT_DRAG_MESSAGES,
|
|
5782
|
+
...messages
|
|
5783
|
+
} : DEFAULT_DRAG_MESSAGES;
|
|
5784
|
+
}
|
|
5785
|
+
/**
|
|
5786
|
+
* dnd-kit `announcements` that speak by name, from your names and places,
|
|
5787
|
+
* in your language. Pass them with `dragInstructions` as a `DndContext`'s
|
|
5788
|
+
* `accessibility`, or to `TaskDndProvider`'s.
|
|
5789
|
+
*/
|
|
5790
|
+
function createDragAnnouncements(source, messages) {
|
|
5791
|
+
const say = dragMessages(messages);
|
|
5792
|
+
let lastPlace = null;
|
|
5793
|
+
const placeKey = (place) => place ? JSON.stringify(place) : null;
|
|
5794
|
+
const describeOver = (name, activeId, overId) => {
|
|
5795
|
+
if (overId == null) {
|
|
5796
|
+
lastPlace = null;
|
|
5797
|
+
return say.notOver({ name });
|
|
5798
|
+
}
|
|
5799
|
+
const refused = source.refusal?.(activeId, overId);
|
|
5800
|
+
if (refused) {
|
|
5801
|
+
lastPlace = null;
|
|
5802
|
+
return say.refused({
|
|
5803
|
+
name,
|
|
5804
|
+
...refused
|
|
5805
|
+
});
|
|
5806
|
+
}
|
|
5807
|
+
if (!source.place) return void 0;
|
|
5808
|
+
const place = source.place(activeId, overId);
|
|
5809
|
+
if (!place) {
|
|
5810
|
+
lastPlace = null;
|
|
5811
|
+
return say.notOver({ name });
|
|
5812
|
+
}
|
|
5813
|
+
const key = placeKey(place);
|
|
5814
|
+
if (key === lastPlace) return void 0;
|
|
5815
|
+
lastPlace = key;
|
|
5816
|
+
return say.over({
|
|
5817
|
+
name,
|
|
5818
|
+
...place
|
|
5819
|
+
});
|
|
5820
|
+
};
|
|
5821
|
+
const named = (speak) => (event) => {
|
|
5822
|
+
const name = source.name(event.active.id);
|
|
5823
|
+
return name ? speak(name, event) : void 0;
|
|
5824
|
+
};
|
|
5825
|
+
return {
|
|
5826
|
+
onDragStart: named((name, { active }) => {
|
|
5827
|
+
const home = source.place?.(active.id, null);
|
|
5828
|
+
lastPlace = placeKey(home);
|
|
5829
|
+
return say.pickedUp({
|
|
5830
|
+
name,
|
|
5831
|
+
...home
|
|
5832
|
+
});
|
|
5833
|
+
}),
|
|
5834
|
+
onDragOver: named((name, { active, over }) => describeOver(name, active.id, over?.id ?? null)),
|
|
5835
|
+
onDragMove: () => void 0,
|
|
5836
|
+
onDragEnd: named((name, { active, over }) => {
|
|
5837
|
+
const refused = over == null ? null : source.refusal?.(active.id, over.id);
|
|
5838
|
+
if (over != null && !refused && !source.place) return void 0;
|
|
5839
|
+
const place = over == null || refused ? null : source.place?.(active.id, over.id);
|
|
5840
|
+
if (place) return say.dropped({
|
|
5841
|
+
name,
|
|
5842
|
+
...place
|
|
5843
|
+
});
|
|
5844
|
+
const home = source.place?.(active.id, null);
|
|
5845
|
+
return refused ? say.refusedDrop({
|
|
5846
|
+
name,
|
|
5847
|
+
reason: refused.reason,
|
|
5848
|
+
...home
|
|
5849
|
+
}) : say.cancelled({
|
|
5850
|
+
name,
|
|
5851
|
+
...home
|
|
5852
|
+
});
|
|
5853
|
+
}),
|
|
5854
|
+
onDragCancel: named((name, { active }) => say.cancelled({
|
|
5855
|
+
name,
|
|
5856
|
+
...source.place?.(active.id, null)
|
|
5857
|
+
}))
|
|
5858
|
+
};
|
|
5859
|
+
}
|
|
5860
|
+
/** Announcements that say nothing, for a surface that announces on its own or has no names. */
|
|
5861
|
+
const SILENT_DRAG_ANNOUNCEMENTS = {
|
|
5862
|
+
onDragStart: () => void 0,
|
|
5863
|
+
onDragMove: () => void 0,
|
|
5864
|
+
onDragOver: () => void 0,
|
|
5865
|
+
onDragEnd: () => void 0,
|
|
5866
|
+
onDragCancel: () => void 0
|
|
5867
|
+
};
|
|
5868
|
+
/** dnd-kit `screenReaderInstructions`: Space, not Enter, in your language. */
|
|
5869
|
+
function dragInstructions(messages) {
|
|
5870
|
+
return { draggable: dragMessages(messages).instructions };
|
|
5871
|
+
}
|
|
5872
|
+
//#endregion
|
|
5873
|
+
//#region src/components/drag/drag.recipe.ts
|
|
5874
|
+
/**
|
|
5875
|
+
* The lift look, for a copy drawn outside `DragLift`: an opaque popover
|
|
5876
|
+
* surface, `shadow-float` and the `line-seam` ring. No scale, no tilt.
|
|
5877
|
+
*/
|
|
5878
|
+
const LIFT_CLASS = "bg-layer-popover shadow-float ring-1 ring-line-seam";
|
|
5879
|
+
const drag = tv$1({
|
|
5880
|
+
slots: {
|
|
5881
|
+
lift: [
|
|
5882
|
+
"pointer-events-none size-full",
|
|
5883
|
+
"rounded-control",
|
|
5884
|
+
LIFT_CLASS
|
|
5885
|
+
],
|
|
5886
|
+
placeholder: [
|
|
5887
|
+
"pointer-events-none box-border",
|
|
5888
|
+
"rounded-control",
|
|
5889
|
+
"border-[1.5px] border-dashed border-line-strong bg-fill-subtle"
|
|
5890
|
+
],
|
|
5891
|
+
hint: [
|
|
5892
|
+
"pointer-events-none fixed top-0 left-0 z-70 max-w-80",
|
|
5893
|
+
"rounded-chip px-2 py-1",
|
|
5894
|
+
"font-sans text-caption",
|
|
5895
|
+
"bg-layer-hud text-foreground-on-hud shadow-float ring-1 ring-line-seam"
|
|
5896
|
+
]
|
|
5897
|
+
},
|
|
5898
|
+
variants: { opaque: { true: { placeholder: ["bg-layer-canvas", "bg-[linear-gradient(var(--fill-subtle),var(--fill-subtle))]"] } } }
|
|
5899
|
+
});
|
|
5900
|
+
//#endregion
|
|
5901
|
+
//#region src/components/drag/drag-lift.tsx
|
|
5902
|
+
/**
|
|
5903
|
+
* A drag settling (motion.md, `motion-drag-settle-*`): the lifted copy
|
|
5904
|
+
* gliding into its place on a drop or back home on a cancel, siblings sliding
|
|
5905
|
+
* apart to open the place, and a layout reflowing on a drop.
|
|
5906
|
+
*/
|
|
5907
|
+
const DRAG_SETTLE = {
|
|
5908
|
+
duration: 160,
|
|
5909
|
+
easing: "cubic-bezier(0.25, 1, 0.5, 1)"
|
|
5910
|
+
};
|
|
5911
|
+
/** For `useSortable({ transition })`: siblings slide with the same token. */
|
|
5912
|
+
const DRAG_SIBLING_TRANSITION = {
|
|
5913
|
+
duration: DRAG_SETTLE.duration,
|
|
5914
|
+
easing: DRAG_SETTLE.easing
|
|
5915
|
+
};
|
|
5916
|
+
/** The item a drag came from, while nothing else has taken its place (`data-drag-origin`). */
|
|
5917
|
+
const ORIGIN_OPACITY = .4;
|
|
5918
|
+
/** Auto-scroll starts this close to the edge of anything that scrolls. */
|
|
5919
|
+
const DRAG_AUTO_SCROLL_ZONE_PX = 48;
|
|
5920
|
+
/** How far a keyboard drag sets the copy off its place, so the place's dashed outline shows. */
|
|
5921
|
+
const DRAG_KEYBOARD_OFFSET_PX = 6;
|
|
5922
|
+
const hideActiveWhileGliding = defaultDropAnimationSideEffects({ styles: { active: { opacity: "0" } } });
|
|
5923
|
+
/**
|
|
5924
|
+
* Drop: the copy glides into its place. Cancel: it glides back home. While
|
|
5925
|
+
* it glides, the item it will become stays hidden, then appears there.
|
|
5926
|
+
*/
|
|
5927
|
+
const DROP_GLIDE = {
|
|
5928
|
+
duration: DRAG_SETTLE.duration,
|
|
5929
|
+
easing: DRAG_SETTLE.easing,
|
|
5930
|
+
sideEffects: (parameters) => {
|
|
5931
|
+
const restore = hideActiveWhileGliding(parameters);
|
|
5932
|
+
const copy = parameters.dragOverlay.node.querySelector("[data-slot=drag-lift]");
|
|
5933
|
+
if (copy?.style.translate) {
|
|
5934
|
+
copy.style.transition = `translate ${DRAG_SETTLE.duration}ms ${DRAG_SETTLE.easing}`;
|
|
5935
|
+
copy.style.translate = "0px 0px";
|
|
5936
|
+
}
|
|
5937
|
+
return restore;
|
|
5938
|
+
}
|
|
5939
|
+
};
|
|
5940
|
+
const OVERLAY_STYLE = { pointerEvents: "none" };
|
|
5941
|
+
const REDUCED_MOTION = "(prefers-reduced-motion: reduce)";
|
|
5942
|
+
function subscribeReducedMotion(listener) {
|
|
5943
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return () => {};
|
|
5944
|
+
const query = window.matchMedia(REDUCED_MOTION);
|
|
5945
|
+
query.addEventListener("change", listener);
|
|
5946
|
+
return () => query.removeEventListener("change", listener);
|
|
5947
|
+
}
|
|
5948
|
+
function reducedMotion() {
|
|
5949
|
+
return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(REDUCED_MOTION).matches;
|
|
5950
|
+
}
|
|
5951
|
+
/**
|
|
5952
|
+
* The sibling transition for `useSortable({ transition })`: the drag-settle
|
|
5953
|
+
* slide, or none with `prefers-reduced-motion`.
|
|
5954
|
+
*/
|
|
5955
|
+
function useDragSiblingTransition() {
|
|
5956
|
+
return useSyncExternalStore(subscribeReducedMotion, reducedMotion, () => false) ? null : DRAG_SIBLING_TRANSITION;
|
|
5957
|
+
}
|
|
5958
|
+
const KEYBOARD_OFFSET = `6px 6px`;
|
|
5959
|
+
function isKeyboardEvent(event) {
|
|
5960
|
+
return typeof KeyboardEvent !== "undefined" && event instanceof KeyboardEvent;
|
|
5961
|
+
}
|
|
5962
|
+
/**
|
|
5963
|
+
* For a compact proxy (a section's head, at most 240px wide): the grab point
|
|
5964
|
+
* is kept, but pulled to within `inset` of the proxy's end, so the hand never
|
|
5965
|
+
* holds empty air beside it. A constant shift: the copy still tracks 1:1.
|
|
5966
|
+
*/
|
|
5967
|
+
function keepGrabInside(proxyWidth, inset = 20) {
|
|
5968
|
+
return ({ transform, activatorEvent, activeNodeRect }) => {
|
|
5969
|
+
if (!activeNodeRect || !activatorEvent) return transform;
|
|
5970
|
+
const point = eventPoint(activatorEvent);
|
|
5971
|
+
if (!point) return transform;
|
|
5972
|
+
const grabX = point.x - activeNodeRect.left;
|
|
5973
|
+
const max = proxyWidth - inset;
|
|
5974
|
+
return grabX > max ? {
|
|
5975
|
+
...transform,
|
|
5976
|
+
x: transform.x + (grabX - max)
|
|
5977
|
+
} : transform;
|
|
5978
|
+
};
|
|
5979
|
+
}
|
|
5980
|
+
function eventPoint(event) {
|
|
5981
|
+
if ("clientX" in event && typeof event.clientX === "number") {
|
|
5982
|
+
const pointerEvent = event;
|
|
5983
|
+
return {
|
|
5984
|
+
x: pointerEvent.clientX,
|
|
5985
|
+
y: pointerEvent.clientY
|
|
5986
|
+
};
|
|
5987
|
+
}
|
|
5988
|
+
const touch = event.touches?.[0] ?? event.changedTouches?.[0];
|
|
5989
|
+
return touch ? {
|
|
5990
|
+
x: touch.clientX,
|
|
5991
|
+
y: touch.clientY
|
|
5992
|
+
} : null;
|
|
5993
|
+
}
|
|
5994
|
+
/**
|
|
5995
|
+
* Cancels the drag in progress, whichever sensor holds it. Every dnd-kit
|
|
5996
|
+
* sensor (and so every sensor of `useDragSensors`) puts the item back when the
|
|
5997
|
+
* window is resized, so this sends the window a `resize`: unlike a synthetic
|
|
5998
|
+
* Escape, no app's own Escape handler (a dialog, a panel, a popover) hears it.
|
|
5999
|
+
*/
|
|
6000
|
+
function cancelDrag(win = window) {
|
|
6001
|
+
win.dispatchEvent(new Event("resize"));
|
|
6002
|
+
}
|
|
6003
|
+
/**
|
|
6004
|
+
* Above every raft-ui layer (popovers 50, a stacked dialog 60, toasts and the
|
|
6005
|
+
* lightbox 70) and an app's own top layers: the copy in the hand is always on
|
|
6006
|
+
* top. dnd-kit's own default.
|
|
6007
|
+
*/
|
|
6008
|
+
const DRAG_LIFT_Z_INDEX = 999;
|
|
6009
|
+
const noSubscribe = () => () => {};
|
|
6010
|
+
const clientBody = () => document.body;
|
|
6011
|
+
const serverBody = () => null;
|
|
6012
|
+
/**
|
|
6013
|
+
* For a component whose copy goes to `document.body` unless it is told
|
|
6014
|
+
* otherwise: `undefined` is the body (once on the client, so hydration
|
|
6015
|
+
* matches), `null` is in place, and an element is that element.
|
|
6016
|
+
*/
|
|
6017
|
+
function useLiftContainer(container) {
|
|
6018
|
+
const body = useSyncExternalStore(noSubscribe, clientBody, serverBody);
|
|
6019
|
+
return container === void 0 ? body : container;
|
|
6020
|
+
}
|
|
6021
|
+
/**
|
|
6022
|
+
* The copy of a dragged item that follows the hand
|
|
6023
|
+
* (design/patterns/drag-and-drop.md#what-follows-the-hand): an opaque popover
|
|
6024
|
+
* surface with `shadow-float` and a `line-seam` ring, no scale and no tilt,
|
|
6025
|
+
* 1:1 with the pointer from the grab point, never clamped to its container and
|
|
6026
|
+
* never held to one axis. On a drop it glides into its place, and on a cancel
|
|
6027
|
+
* back home (160ms, `motion-drag-settle-*`; none with reduced motion).
|
|
6028
|
+
*
|
|
6029
|
+
* While something is lifted it also sets the grabbing cursor, cancels the
|
|
6030
|
+
* drag when the window loses focus or the tab is hidden, and scrolls an area
|
|
6031
|
+
* the pointer is near the edge of. Render it inside the `DndContext`.
|
|
6032
|
+
*/
|
|
6033
|
+
function DragLift({ children, className, style, modifiers, autoScroll = true, container, zIndex = 999 }) {
|
|
6034
|
+
const { lift } = drag();
|
|
6035
|
+
const { resolvedMode } = useTheme();
|
|
6036
|
+
const reduced = useSyncExternalStore(subscribeReducedMotion, reducedMotion, () => false);
|
|
6037
|
+
const { activatorEvent } = useDndContext();
|
|
6038
|
+
const liftStyle = useMemo(() => isKeyboardEvent(activatorEvent) ? {
|
|
6039
|
+
translate: KEYBOARD_OFFSET,
|
|
6040
|
+
...style
|
|
6041
|
+
} : style, [activatorEvent, style]);
|
|
6042
|
+
const overlay = /* @__PURE__ */ jsx(DragOverlay, {
|
|
6043
|
+
dropAnimation: reduced ? null : DROP_GLIDE,
|
|
6044
|
+
modifiers,
|
|
6045
|
+
zIndex,
|
|
6046
|
+
style: OVERLAY_STYLE,
|
|
6047
|
+
children: children == null || children === false ? null : /* @__PURE__ */ jsx("div", {
|
|
6048
|
+
className: "size-full",
|
|
6049
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
6050
|
+
"data-slot": "drag-lift",
|
|
6051
|
+
className: lift({ className }),
|
|
6052
|
+
style: liftStyle,
|
|
6053
|
+
children
|
|
6054
|
+
})
|
|
6055
|
+
})
|
|
6056
|
+
});
|
|
6057
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DragSession, { autoScroll }), container ? createPortal(/* @__PURE__ */ jsx("div", {
|
|
6058
|
+
"data-slot": "drag-lift-portal",
|
|
6059
|
+
className: cn("contents", resolvedMode),
|
|
6060
|
+
children: overlay
|
|
6061
|
+
}), container) : overlay] });
|
|
6062
|
+
}
|
|
6063
|
+
/** Where the pointer is during a drag: auto-scroll and the refusal hint read it. */
|
|
6064
|
+
const pointer = {
|
|
6065
|
+
x: 0,
|
|
6066
|
+
y: 0,
|
|
6067
|
+
known: false
|
|
6068
|
+
};
|
|
6069
|
+
function trackPointer(event) {
|
|
6070
|
+
const point = "touches" in event ? event.touches[0] : event;
|
|
6071
|
+
if (!point) return;
|
|
6072
|
+
pointer.x = point.clientX;
|
|
6073
|
+
pointer.y = point.clientY;
|
|
6074
|
+
pointer.known = true;
|
|
6075
|
+
}
|
|
6076
|
+
/** The pointer's last place, for a hint that follows it. */
|
|
6077
|
+
function dragPointer() {
|
|
6078
|
+
return pointer.known ? {
|
|
6079
|
+
x: pointer.x,
|
|
6080
|
+
y: pointer.y
|
|
6081
|
+
} : null;
|
|
6082
|
+
}
|
|
6083
|
+
function DragSession({ autoScroll }) {
|
|
6084
|
+
const { active, activatorEvent } = useDndContext();
|
|
6085
|
+
const dragging = active != null;
|
|
6086
|
+
const viaKeyboard = isKeyboardEvent(activatorEvent);
|
|
6087
|
+
useEffect(() => {
|
|
6088
|
+
if (!dragging) return;
|
|
6089
|
+
const root = document.documentElement;
|
|
6090
|
+
root.setAttribute("data-dragging", "");
|
|
6091
|
+
if (activatorEvent && !viaKeyboard) trackPointer(activatorEvent);
|
|
6092
|
+
const onMove = (event) => trackPointer(event);
|
|
6093
|
+
const onBlur = () => cancelDrag();
|
|
6094
|
+
const onVisibility = () => {
|
|
6095
|
+
if (document.visibilityState === "hidden") cancelDrag();
|
|
6096
|
+
};
|
|
6097
|
+
window.addEventListener("pointermove", onMove, {
|
|
6098
|
+
capture: true,
|
|
6099
|
+
passive: true
|
|
6100
|
+
});
|
|
6101
|
+
window.addEventListener("touchmove", onMove, {
|
|
6102
|
+
capture: true,
|
|
6103
|
+
passive: true
|
|
6104
|
+
});
|
|
6105
|
+
window.addEventListener("blur", onBlur);
|
|
6106
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
6107
|
+
let frame = 0;
|
|
6108
|
+
const tick = () => {
|
|
6109
|
+
if (pointer.known) autoScrollAt(pointer.x, pointer.y);
|
|
6110
|
+
frame = requestAnimationFrame(tick);
|
|
6111
|
+
};
|
|
6112
|
+
if (autoScroll && !viaKeyboard) frame = requestAnimationFrame(tick);
|
|
6113
|
+
return () => {
|
|
6114
|
+
root.removeAttribute("data-dragging");
|
|
6115
|
+
pointer.known = false;
|
|
6116
|
+
window.removeEventListener("pointermove", onMove, { capture: true });
|
|
6117
|
+
window.removeEventListener("touchmove", onMove, { capture: true });
|
|
6118
|
+
window.removeEventListener("blur", onBlur);
|
|
6119
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
6120
|
+
cancelAnimationFrame(frame);
|
|
6121
|
+
};
|
|
6122
|
+
}, [
|
|
6123
|
+
dragging,
|
|
6124
|
+
viaKeyboard,
|
|
6125
|
+
autoScroll,
|
|
6126
|
+
activatorEvent
|
|
6127
|
+
]);
|
|
6128
|
+
return null;
|
|
6129
|
+
}
|
|
6130
|
+
function scrollable(element) {
|
|
6131
|
+
const style = getComputedStyle(element);
|
|
6132
|
+
return {
|
|
6133
|
+
x: /(auto|scroll)/.test(style.overflowX) && element.scrollWidth > element.clientWidth,
|
|
6134
|
+
y: /(auto|scroll)/.test(style.overflowY) && element.scrollHeight > element.clientHeight
|
|
6135
|
+
};
|
|
6136
|
+
}
|
|
6137
|
+
/** Faster the nearer the edge: up to 16px a frame at the edge itself. */
|
|
6138
|
+
function speed(depth) {
|
|
6139
|
+
return Math.ceil(16 * Math.min(1, depth / 48) ** 2);
|
|
6140
|
+
}
|
|
6141
|
+
function scrollDelta(start, end, at, position, max) {
|
|
6142
|
+
const zone = 48;
|
|
6143
|
+
if (at < start + zone && position > 0) return -speed(start + zone - at);
|
|
6144
|
+
if (at > end - zone && position < max) return speed(at - (end - zone));
|
|
6145
|
+
return 0;
|
|
6146
|
+
}
|
|
6147
|
+
/** Scrolls the nearest area under the point that can still scroll toward the edge it is near. */
|
|
6148
|
+
function autoScrollAt(x, y) {
|
|
6149
|
+
let element = document.elementFromPoint(x, y);
|
|
6150
|
+
while (element && element !== document.documentElement && element !== document.body) {
|
|
6151
|
+
const can = scrollable(element);
|
|
6152
|
+
if (can.x || can.y) {
|
|
6153
|
+
const rect = element.getBoundingClientRect();
|
|
6154
|
+
const dy = can.y ? scrollDelta(rect.top, rect.bottom, y, element.scrollTop, element.scrollHeight - element.clientHeight - 1) : 0;
|
|
6155
|
+
const dx = can.x ? scrollDelta(rect.left, rect.right, x, element.scrollLeft, element.scrollWidth - element.clientWidth - 1) : 0;
|
|
6156
|
+
if (dx || dy) {
|
|
6157
|
+
element.scrollBy(dx, dy);
|
|
6158
|
+
return;
|
|
6159
|
+
}
|
|
6160
|
+
}
|
|
6161
|
+
element = element.parentElement;
|
|
6162
|
+
}
|
|
6163
|
+
const page = document.scrollingElement ?? document.documentElement;
|
|
6164
|
+
const dy = scrollDelta(0, window.innerHeight, y, page.scrollTop, page.scrollHeight - window.innerHeight - 1);
|
|
6165
|
+
if (dy) window.scrollBy(0, dy);
|
|
6166
|
+
}
|
|
6167
|
+
//#endregion
|
|
6168
|
+
//#region src/components/drag/drag-sensors.ts
|
|
6169
|
+
/**
|
|
6170
|
+
* A mouse or a pen picks an item up once it has moved this far, so a click
|
|
6171
|
+
* never moves anything (design/patterns/drag-and-drop.md#starting-a-drag).
|
|
6172
|
+
*/
|
|
6173
|
+
const MOUSE_DRAG_DISTANCE_PX = 6;
|
|
6174
|
+
/**
|
|
6175
|
+
* Space picks up and drops, Escape puts back, the arrow keys move. Enter
|
|
6176
|
+
* never starts a drag: on an item that can also be opened or activated, Enter
|
|
6177
|
+
* does that.
|
|
6178
|
+
*/
|
|
6179
|
+
const DRAG_KEYBOARD_CODES = {
|
|
6180
|
+
start: ["Space"],
|
|
6181
|
+
cancel: ["Escape"],
|
|
6182
|
+
end: ["Space"]
|
|
6183
|
+
};
|
|
6184
|
+
const NO_TOUCH = {};
|
|
6185
|
+
/**
|
|
6186
|
+
* The one sensor set for everything that can be dragged
|
|
6187
|
+
* (design/patterns/drag-and-drop.md#starting-a-drag):
|
|
6188
|
+
*
|
|
6189
|
+
* - a mouse or a pen: after 6px of movement;
|
|
6190
|
+
* - a finger: hold still 500ms, then move 10px (`useHoldThenMoveTouchSensor`);
|
|
6191
|
+
* - the keyboard: Space picks up, the arrows move, Space drops, Escape puts
|
|
6192
|
+
* back. Enter never starts a drag.
|
|
6193
|
+
*
|
|
6194
|
+
* Pass the options, or only the keyboard's `coordinateGetter`.
|
|
6195
|
+
*/
|
|
6196
|
+
function useDragSensors(options = {}) {
|
|
6197
|
+
const { coordinateGetter = listKeyboardCoordinates, keyboard = true, touch = NO_TOUCH } = typeof options === "function" ? { coordinateGetter: options } : options;
|
|
6198
|
+
const keyboardOptions = useMemo(() => ({
|
|
6199
|
+
keyboardCodes: DRAG_KEYBOARD_CODES,
|
|
6200
|
+
coordinateGetter
|
|
6201
|
+
}), [coordinateGetter]);
|
|
6202
|
+
const mouse = useMouseOnlyPointerSensor(6);
|
|
6203
|
+
const finger = useHoldThenMoveTouchSensor(touch);
|
|
6204
|
+
const keys = useSensor(KeyboardSensor, keyboardOptions);
|
|
6205
|
+
return useSensors(mouse, finger, keyboard ? keys : null);
|
|
6206
|
+
}
|
|
6207
|
+
/**
|
|
6208
|
+
* dnd-kit's sortable keyboard steps, measured from where the item's place
|
|
6209
|
+
* actually is (its own node, slid into the landing spot) rather than from the
|
|
6210
|
+
* lifted copy. After an item moves into another list the two differ, and the
|
|
6211
|
+
* arrows would skip a place. Use it for lists inside one `DndContext`.
|
|
6212
|
+
*/
|
|
6213
|
+
const listKeyboardCoordinates = (event, args) => {
|
|
6214
|
+
const { context } = args;
|
|
6215
|
+
const node = context.active == null ? null : context.draggableNodes.get(context.active.id)?.node.current;
|
|
6216
|
+
if (!node) return sortableKeyboardCoordinates(event, args);
|
|
6217
|
+
const rect = node.getBoundingClientRect();
|
|
6218
|
+
const collisionRect = {
|
|
6219
|
+
top: rect.top,
|
|
6220
|
+
left: rect.left,
|
|
6221
|
+
width: rect.width,
|
|
6222
|
+
height: rect.height,
|
|
6223
|
+
bottom: rect.bottom,
|
|
6224
|
+
right: rect.right
|
|
6225
|
+
};
|
|
6226
|
+
return sortableKeyboardCoordinates(event, {
|
|
6227
|
+
...args,
|
|
6228
|
+
context: {
|
|
6229
|
+
...context,
|
|
6230
|
+
collisionRect
|
|
6231
|
+
}
|
|
6232
|
+
});
|
|
6233
|
+
};
|
|
6234
|
+
/**
|
|
6235
|
+
* The keyboard fix for an item that moves between lists while it is dragged
|
|
6236
|
+
* (a sidebar's sections, a board's columns). Without it, dnd-kit still counts
|
|
6237
|
+
* the row the item was put next to as the place under it, projects one more
|
|
6238
|
+
* move, and the next arrow skips a place: what is announced and where the item
|
|
6239
|
+
* drops disagree. With it:
|
|
6240
|
+
*
|
|
6241
|
+
* - right after it moves list, the item is over itself (by keyboard until the
|
|
6242
|
+
* next arrow, by pointer for one frame);
|
|
6243
|
+
* - the arrows are measured from the item's real place (`listKeyboardCoordinates`).
|
|
6244
|
+
*
|
|
6245
|
+
* Render `DragRemeasure` too, so the lists are measured again after the move.
|
|
6246
|
+
*/
|
|
6247
|
+
function useDragAcrossLists(collisionDetection) {
|
|
6248
|
+
const box = useRef({
|
|
6249
|
+
overSelf: false,
|
|
6250
|
+
justMoved: false,
|
|
6251
|
+
frame: 0
|
|
6252
|
+
});
|
|
6253
|
+
return useMemo(() => {
|
|
6254
|
+
const clearFrame = () => {
|
|
6255
|
+
const state = box.current;
|
|
6256
|
+
if (state.frame && typeof cancelAnimationFrame !== "undefined") cancelAnimationFrame(state.frame);
|
|
6257
|
+
state.frame = 0;
|
|
6258
|
+
};
|
|
6259
|
+
return {
|
|
6260
|
+
collisionDetection: (args) => (box.current.justMoved || box.current.overSelf) && args.active ? [{ id: args.active.id }] : collisionDetection(args),
|
|
6261
|
+
coordinateGetter: (event, args) => {
|
|
6262
|
+
box.current.overSelf = false;
|
|
6263
|
+
return listKeyboardCoordinates(event, args);
|
|
6264
|
+
},
|
|
6265
|
+
moved: (viaKeyboard) => {
|
|
6266
|
+
const state = box.current;
|
|
6267
|
+
state.justMoved = true;
|
|
6268
|
+
if (viaKeyboard) state.overSelf = true;
|
|
6269
|
+
clearFrame();
|
|
6270
|
+
if (typeof requestAnimationFrame === "undefined") {
|
|
6271
|
+
state.justMoved = false;
|
|
6272
|
+
return;
|
|
6273
|
+
}
|
|
6274
|
+
state.frame = requestAnimationFrame(() => {
|
|
6275
|
+
state.frame = requestAnimationFrame(() => {
|
|
6276
|
+
state.justMoved = false;
|
|
6277
|
+
state.frame = 0;
|
|
6278
|
+
});
|
|
6279
|
+
});
|
|
6280
|
+
},
|
|
6281
|
+
reset: () => {
|
|
6282
|
+
clearFrame();
|
|
6283
|
+
box.current.overSelf = false;
|
|
6284
|
+
box.current.justMoved = false;
|
|
6285
|
+
}
|
|
6286
|
+
};
|
|
6287
|
+
}, [collisionDetection]);
|
|
6288
|
+
}
|
|
6289
|
+
/**
|
|
6290
|
+
* Measures every drop target again once an item's move into another list has
|
|
6291
|
+
* rendered. dnd-kit's own observers skip targets whose size didn't change,
|
|
6292
|
+
* even when they moved. Render it inside the `DndContext`.
|
|
6293
|
+
*/
|
|
6294
|
+
function DragRemeasure({ version }) {
|
|
6295
|
+
const context = useDndContext();
|
|
6296
|
+
const latest = useRef(context);
|
|
6297
|
+
useLayoutEffect(() => {
|
|
6298
|
+
latest.current = context;
|
|
6299
|
+
});
|
|
6300
|
+
useLayoutEffect(() => {
|
|
6301
|
+
const { active, droppableContainers } = latest.current;
|
|
6302
|
+
if (active) latest.current.measureDroppableContainers([...droppableContainers.keys()]);
|
|
6303
|
+
}, [version]);
|
|
6304
|
+
return null;
|
|
6305
|
+
}
|
|
6306
|
+
//#endregion
|
|
6307
|
+
//#region src/components/drag/drop-placeholder.tsx
|
|
6308
|
+
/**
|
|
6309
|
+
* Where a dragged item will land (design/patterns/drag-and-drop.md#where-it-will-land):
|
|
6310
|
+
* a 1.5px dashed `line-strong` outline on `fill-subtle`, with the item's
|
|
6311
|
+
* radius and size. One look for every place. The control radius is the
|
|
6312
|
+
* default; pass the item's own (`rounded-container` for a card). Hidden from
|
|
6313
|
+
* assistive technology: the announcements say where the item is.
|
|
6314
|
+
*/
|
|
6315
|
+
function DropPlaceholder({ opaque = false, className, render, ...props }) {
|
|
6316
|
+
const { placeholder } = drag({ opaque });
|
|
6317
|
+
return useRender({
|
|
6318
|
+
defaultTagName: "div",
|
|
6319
|
+
render,
|
|
6320
|
+
props: mergeProps({
|
|
6321
|
+
"aria-hidden": true,
|
|
6322
|
+
className: placeholder({ className })
|
|
6323
|
+
}, props, { "data-slot": "drop-placeholder" })
|
|
6324
|
+
});
|
|
6325
|
+
}
|
|
6326
|
+
/**
|
|
6327
|
+
* Shown while the hand is over a place that refuses the item
|
|
6328
|
+
* (design/patterns/drag-and-drop.md#refused-places): the reason, in a HUD
|
|
6329
|
+
* chip by the pointer (by the lifted copy in a keyboard drag), and the
|
|
6330
|
+
* not-allowed cursor. Render it only while the place is refused, inside the
|
|
6331
|
+
* `DndContext`, with no placeholder anywhere. Announce the reason as well:
|
|
6332
|
+
* the chip is not read out.
|
|
6333
|
+
*/
|
|
6334
|
+
function DragRefusalHint({ children, container, className, style, ...props }) {
|
|
6335
|
+
const { hint } = drag();
|
|
6336
|
+
const ref = useRef(null);
|
|
6337
|
+
const { active, activatorEvent } = useDndContext();
|
|
6338
|
+
const dragging = active != null;
|
|
6339
|
+
const viaKeyboard = typeof KeyboardEvent !== "undefined" && activatorEvent instanceof KeyboardEvent;
|
|
6340
|
+
useEffect(() => {
|
|
6341
|
+
if (!dragging) return;
|
|
6342
|
+
const root = document.documentElement;
|
|
6343
|
+
root.setAttribute("data-drag-refused", "");
|
|
6344
|
+
let frame = 0;
|
|
6345
|
+
const tick = () => {
|
|
6346
|
+
const node = ref.current;
|
|
6347
|
+
if (node) {
|
|
6348
|
+
let point = dragPointer();
|
|
6349
|
+
if (viaKeyboard || !point) {
|
|
6350
|
+
const lift = document.querySelector("[data-slot=drag-lift]")?.getBoundingClientRect();
|
|
6351
|
+
if (lift) point = {
|
|
6352
|
+
x: lift.right,
|
|
6353
|
+
y: lift.top + lift.height / 2
|
|
6354
|
+
};
|
|
6355
|
+
}
|
|
6356
|
+
if (point) {
|
|
6357
|
+
node.style.transform = `translate(${Math.round(point.x + 14)}px, ${Math.round(point.y + 16)}px)`;
|
|
6358
|
+
node.style.visibility = "visible";
|
|
6359
|
+
}
|
|
6360
|
+
}
|
|
6361
|
+
frame = requestAnimationFrame(tick);
|
|
6362
|
+
};
|
|
6363
|
+
tick();
|
|
6364
|
+
return () => {
|
|
6365
|
+
root.removeAttribute("data-drag-refused");
|
|
6366
|
+
cancelAnimationFrame(frame);
|
|
6367
|
+
};
|
|
6368
|
+
}, [dragging, viaKeyboard]);
|
|
6369
|
+
if (!dragging || typeof document === "undefined") return null;
|
|
6370
|
+
return createPortal(/* @__PURE__ */ jsx("div", {
|
|
6371
|
+
...props,
|
|
6372
|
+
ref,
|
|
6373
|
+
"data-slot": "drag-refusal-hint",
|
|
6374
|
+
"aria-hidden": true,
|
|
6375
|
+
className: hint({ className }),
|
|
6376
|
+
style: {
|
|
6377
|
+
visibility: "hidden",
|
|
6378
|
+
...style
|
|
6379
|
+
},
|
|
6380
|
+
children
|
|
6381
|
+
}), container ?? document.body);
|
|
6382
|
+
}
|
|
6383
|
+
//#endregion
|
|
5756
6384
|
//#region src/components/skeleton/skeleton.tsx
|
|
5757
6385
|
const skeleton = tv$1({
|
|
5758
6386
|
slots: { root: [
|
|
@@ -6196,4 +6824,4 @@ function InboxItemActions({ className, render, reveal, ...props }) {
|
|
|
6196
6824
|
});
|
|
6197
6825
|
}
|
|
6198
6826
|
//#endregion
|
|
6199
|
-
export {
|
|
6827
|
+
export { MessageListDateDivider as $, DialogContent as $i, PreviewCardContent as $n, DropdownMenuItemLabel as $r, MessageReactionTooltipNameText as $t, DRAG_AUTO_SCROLL_ZONE_PX as A, controlIconInset as Aa, ListRow as Ai, MessageItem as An, PopoverPopup as Ar, MessageMultiSelectToolbarActions as At, useDragSiblingTransition as B, ListRowValue as Bi, RadioGroupItem as Bn, TOUCH_DRAG_TOLERANCE_PX as Br, inlineChip as Bt, DropPlaceholder as C, withOverlayLayer as Ca, ScrollAreaCorner as Ci, MessageItemEdited as Cn, PopoverArrow as Cr, messageEmbed as Ct, listKeyboardCoordinates as D, tv$1 as Da, Checkbox$1 as Di, MessageItemAvatarSlot as Dn, PopoverContent as Dr, MessageMultiSelect as Dt, MOUSE_DRAG_DISTANCE_PX as E, ThemeStateContext as Ea, ScrollAreaViewport as Ei, MessageItemSearchMatch as En, PopoverClose as Er, MessageTextSelectionToolbarSeparator as Et, DROP_GLIDE as F, ListRowGroup as Fi, AvatarGroup as Fn, PopoverViewport as Fr, MessageReferencePending as Ft, SILENT_DRAG_ANNOUNCEMENTS as G, TooltipTrigger as Gi, measureContent as Gn, MobileNavRoot as Gr, MessageReactionGlyph as Gt, LIFT_CLASS as H, TooltipContent as Hi, InputGroupAddon as Hn, useMouseOnlyPointerSensor as Hr, MessageReactionChip as Ht, DragLift as I, ListRowIcon as Ii, AvatarGroupCount as In, HoldThenMoveTouchSensor as Ir, MessageReferenceReadMark as It, dragMessages as J, DialogSheetContent as Ji, readNow as Jn, DropdownMenuCheckboxItemIndicator as Jr, MessageReactionQuickButton as Jt, createDragAnnouncements as K, Badge as Ki, measureElement as Kn, DropdownMenu as Kr, MessageReactionPickerContent as Kt, ORIGIN_OPACITY as L, ListRowMeta as Li, AvatarImage as Ln, MouseOnlyPointerSensor as Lr, MessageReferenceSuffix as Lt, DRAG_LIFT_Z_INDEX as M, headEdges as Ma, ListRowBottom as Mi, Avatar$1 as Mn, PopoverSeparator as Mr, MessageReferenceIcon as Mt, DRAG_SETTLE as N, decisionWidth as Na, ListRowChevron as Ni, AvatarBadge as Nn, PopoverTitle as Nr, MessageReferenceIndicator as Nt, useDragAcrossLists as O, stackedActions as Oa, CheckboxIndicator as Oi, MessageItemContinuationTime as On, PopoverDescription as Or, MessageMultiSelectCheckbox as Ot, DRAG_SIBLING_TRANSITION as P, ListRowDescription as Pi, AvatarFallback as Pn, PopoverTrigger as Pr, MessageReferenceLabel as Pt, MessageListJumpPillGroup as Q, DialogClose as Qi, PreviewCardBody as Qn, DropdownMenuItemCount as Qr, MessageReactionTooltipName as Qt, cancelDrag as R, ListRowTitle as Ri, RadioGroup$1 as Rn, TOUCH_DRAG_DISTANCE_PX as Rr, MessageReferenceText as Rt, DragRefusalHint as S, useParentOverlayKind as Sa, ScrollAreaContent as Si, MessageItemContent as Sn, PopoverActions as Sr, MessageEmbedHeader as St, DragRemeasure as T, useTheme as Ta, ScrollAreaThumb as Ti, MessageItemFooter as Tn, PopoverBody as Tr, MessageTextSelectionToolbarButton as Tt, drag as U, TooltipPortal as Ui, InputGroupInput as Un, MobileNavItem as Ur, MessageReactionCount as Ut, useLiftContainer as V, Tooltip$1 as Vi, InputGroup as Vn, useHoldThenMoveTouchSensor as Vr, MessageReactionAddButton as Vt, DEFAULT_DRAG_MESSAGES as W, TooltipProvider as Wi, useOverflowTitle as Wn, MobileNavLabel as Wr, MessageReactionErrorIndicator as Wt, MessageListJumpPill as X, Dialog$1 as Xi, PreviewCardActions as Xn, DropdownMenuFooter as Xr, MessageReactionTooltipContent as Xt, MessageListJumpControls as Y, useMobileViewport as Yi, PreviewCard$1 as Yn, DropdownMenuContent as Yr, MessageReactionQuickRow as Yt, MessageListJumpPillDismiss as Z, DialogBody as Zi, PreviewCardArrow as Zn, DropdownMenuItem as Zr, MessageReactionTooltipMeta as Zt, InboxItemTrailing as _, Button$1 as _a, PanelHeaderRoot as _i, MessageItemSenderButton as _n, MobileNavServerPopoverRow as _r, MessageQuotedPreviewTimestamp as _t, InboxItemContext as a, DialogOverlay as aa, DropdownMenuRadioItem as ai, MessageItemSavedIndicator as an, PreviewCardPopup as ar, MessageQuotedPreviewAttachment as at, useLatestRef as b, defaultNativeButton as ba, PanelSection as bi, MessageItemAttachments as bn, MobileNavServerPopoverRowLabel as br, MessageEmbedContent as bt, InboxItemLeading as c, DialogSurface as ca, DropdownMenuShortcut as ci, MessageItemDelegatedAvatar as cn, PreviewCardTitle as cr, MessageQuotedPreviewAuthorDelegatedBy as ct, InboxItemMetadata as d, PanelAction as da, DropdownMenuTrigger as di, MessageItemDelegatedByName as dn, MobileNavServerPopover as dr, MessageQuotedPreviewChannel as dt, DialogDescription as ea, DropdownMenuLabel as ei, MessageReactionTooltipNames as en, PreviewCardDescription as er, MessageListEndFade as et, InboxItemSelection as f, panelToggleAction as fa, Kbd as fi, MessageItemHeader as fn, MobileNavServerPopoverContent as fr, MessageQuotedPreviewContent as ft, InboxItemTitle as g, DialogSheetReset as ga, PanelFooter as gi, MessageItemSenderBadges as gn, MobileNavServerPopoverList as gr, MessageQuotedPreviewThread as gt, InboxItemTimestamp as h, textLinkVariants as ha, PanelBody as hi, MessageItemSender as hn, MobileNavServerPopoverGroup as hr, MessageQuotedPreviewText as ht, InboxItemContent as i, DialogNav as ia, DropdownMenuRadioGroup as ii, MessageItemReadReceipt as in, PreviewCardMeta as ir, MessageQuotedPreview as it, DRAG_KEYBOARD_OFFSET_PX as j, headEdgePull as ja, ListRowBody as ji, searchHit as jn, PopoverPortal as jr, MessageReferenceChip as jt, useDragSensors as k, useStackedActions as ka, PRESENCE_COLOR as ki, MessageItemGutter as kn, PopoverHeader as kr, MessageMultiSelectToolbar as kt, InboxItemMarks as l, DialogTitle as la, DropdownMenuSubmenu as li, MessageItemDelegatedBy as ln, PreviewCardTrigger as lr, MessageQuotedPreviewAuthorMeta as lt, InboxItemSubtitle as m, TextLinkExternalIcon as ma, Panel as mi, MessageItemMeta as mn, MobileNavServerPopoverDestinations as mr, MessageQuotedPreviewLoading as mt, InboxItemActions as n, DialogFooterNote as na, DropdownMenuPopup as ni, MessageItemBadge as nn, PreviewCardFooter as nr, MessageListNotice as nt, InboxItemHeading as o, DialogPortal as oa, DropdownMenuRadioItemIndicator as oi, MessageItemToolbar as on, PreviewCardPortal as or, MessageQuotedPreviewAttachments as ot, InboxItemSender as p, TextLink as pa, KbdGroup as pi, MessageItemInlineStatus as pn, MobileNavServerPopoverDestination as pr, MessageQuotedPreviewHeader as pt, dragInstructions as q, DialogCommit as qi, observeTruncation as qn, DropdownMenuCheckboxItem as qr, MessageReactionPickerStatic as qt, InboxItemBody as r, DialogHeader as ra, DropdownMenuPortal as ri, MessageItemBadgeSeparator as rn, PreviewCardHeader as rr, MessageList as rt, InboxItemHoverTarget as s, DialogSheetBack as sa, DropdownMenuSeparator as si, MessageItemToolbarButton as sn, PreviewCardSeparator as sr, MessageQuotedPreviewAuthor as st, InboxItem as t, DialogFooter as ta, DropdownMenuLinkItem as ti, MessageReactionTooltipSeparator as tn, PreviewCardEyebrow as tr, MessageListHistoryLimited as tt, InboxItemMessage as u, DialogTrigger as ua, DropdownMenuSubmenuTrigger as ui, MessageItemDelegatedByButton as un, MobileNavServerItem as ur, MessageQuotedPreviewAuthorName as ut, InboxItemTrigger as v, buttonVariants as va, PanelScrollContent as vi, MessageItemSenderGroup as vn, MobileNavServerPopoverRowBody as vr, MessageQuotedPreviewUnavailable as vt, DRAG_KEYBOARD_CODES as w, useThemeScopeProps as wa, ScrollAreaScrollbar as wi, MessageItemEmbedded as wn, PopoverBackdrop as wr, MessageTextSelectionToolbar as wt, Skeleton as x, OverlayLayerProvider as xa, ScrollArea$1 as xi, MessageItemBody as xn, Popover$1 as xr, MessageEmbedFooter as xt, inboxItem as y, Spinner as ya, PanelScrollViewport as yi, MessageItemTime as yn, MobileNavServerPopoverRowDescription as yr, MessageEmbed as yt, keepGrabInside as z, ListRowTop as zi, RadioGroupIndicator as zn, TOUCH_DRAG_HOLD_MS as zr, MessageReferenceUnavailable as zt };
|