@liveblocks/react-ui 3.15.0 → 3.15.1-rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/_private/index.cjs +2 -0
  2. package/dist/_private/index.cjs.map +1 -1
  3. package/dist/_private/index.d.cts +3 -1
  4. package/dist/_private/index.d.ts +3 -1
  5. package/dist/_private/index.js +1 -0
  6. package/dist/_private/index.js.map +1 -1
  7. package/dist/components/AvatarStack.cjs +15 -10
  8. package/dist/components/AvatarStack.cjs.map +1 -1
  9. package/dist/components/AvatarStack.js +15 -10
  10. package/dist/components/AvatarStack.js.map +1 -1
  11. package/dist/components/CommentPin.cjs +4 -2
  12. package/dist/components/CommentPin.cjs.map +1 -1
  13. package/dist/components/CommentPin.js +4 -2
  14. package/dist/components/CommentPin.js.map +1 -1
  15. package/dist/components/Cursors.cjs +13 -16
  16. package/dist/components/Cursors.cjs.map +1 -1
  17. package/dist/components/Cursors.js +14 -17
  18. package/dist/components/Cursors.js.map +1 -1
  19. package/dist/components/FloatingComposer.cjs +14 -2
  20. package/dist/components/FloatingComposer.cjs.map +1 -1
  21. package/dist/components/FloatingComposer.js +15 -3
  22. package/dist/components/FloatingComposer.js.map +1 -1
  23. package/dist/components/FloatingThread.cjs +1 -0
  24. package/dist/components/FloatingThread.cjs.map +1 -1
  25. package/dist/components/FloatingThread.js +1 -0
  26. package/dist/components/FloatingThread.js.map +1 -1
  27. package/dist/components/internal/Dropdown.cjs +1 -0
  28. package/dist/components/internal/Dropdown.cjs.map +1 -1
  29. package/dist/components/internal/Dropdown.js +1 -0
  30. package/dist/components/internal/Dropdown.js.map +1 -1
  31. package/dist/components/internal/EmojiPicker.cjs +1 -0
  32. package/dist/components/internal/EmojiPicker.cjs.map +1 -1
  33. package/dist/components/internal/EmojiPicker.js +1 -0
  34. package/dist/components/internal/EmojiPicker.js.map +1 -1
  35. package/dist/components/internal/Tooltip.cjs +1 -0
  36. package/dist/components/internal/Tooltip.cjs.map +1 -1
  37. package/dist/components/internal/Tooltip.js +1 -0
  38. package/dist/components/internal/Tooltip.js.map +1 -1
  39. package/dist/icon.cjs +2 -0
  40. package/dist/icon.cjs.map +1 -1
  41. package/dist/icon.js +1 -0
  42. package/dist/icon.js.map +1 -1
  43. package/dist/icons/Plus.cjs +11 -0
  44. package/dist/icons/Plus.cjs.map +1 -0
  45. package/dist/icons/Plus.js +9 -0
  46. package/dist/icons/Plus.js.map +1 -0
  47. package/dist/icons/index.cjs +2 -0
  48. package/dist/icons/index.cjs.map +1 -1
  49. package/dist/icons/index.js +1 -0
  50. package/dist/icons/index.js.map +1 -1
  51. package/dist/index.d.cts +11 -3
  52. package/dist/index.d.ts +11 -3
  53. package/dist/utils/px.cjs +14 -0
  54. package/dist/utils/px.cjs.map +1 -0
  55. package/dist/utils/px.js +12 -0
  56. package/dist/utils/px.js.map +1 -0
  57. package/dist/version.cjs +1 -1
  58. package/dist/version.cjs.map +1 -1
  59. package/dist/version.js +1 -1
  60. package/dist/version.js.map +1 -1
  61. package/package.json +4 -4
  62. package/src/styles/index.css +8 -1
  63. package/styles.css +1 -1
  64. package/styles.css.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Cursors.js","sources":["../../src/components/Cursors.tsx"],"sourcesContent":["import type { EventSource } from \"@liveblocks/core\";\nimport { isPlainObject, makeEventSource } from \"@liveblocks/core\";\nimport {\n useOther,\n useOthersConnectionIds,\n useRoom,\n useUpdateMyPresence,\n useUser,\n} from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComponentPropsWithoutRef,\n MutableRefObject,\n PointerEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nimport { type Animatable, makeAnimationLoop } from \"../utils/animation-loop\";\nimport { cn } from \"../utils/cn\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport { Cursor } from \"./Cursor\";\n\nconst STIFFNESS = 320;\nconst DAMPING = 32;\nconst EPSILON = 0.01;\n\nconst DEFAULT_PRESENCE_KEY = \"cursor\";\n\nexport interface CursorsProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The key used to store the cursors in users' Presence.\n * This can be used to have multiple `Cursors` in a single room.\n */\n presenceKey?: string;\n}\n\ntype Coordinates = {\n x: number;\n y: number;\n};\n\ntype Size = {\n width: number;\n height: number;\n};\n\nfunction $string(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction $coordinates(value: unknown): Coordinates | undefined {\n if (\n isPlainObject(value) &&\n typeof value.x === \"number\" &&\n typeof value.y === \"number\"\n ) {\n return value as Coordinates;\n }\n\n return undefined;\n}\n\n// Use a shared animation loop for all (active) springs.\nconst loop = makeAnimationLoop();\n\nfunction makeCoordinatesSpring() {\n const updates = makeEventSource<Coordinates | null>();\n let value: Coordinates | null = null;\n let target: Coordinates | null = null;\n const velocity = { x: 0, y: 0 };\n\n const spring: Animatable = {\n active: false,\n step(dt: number) {\n if (value === null || target === null) {\n spring.active = false;\n return;\n }\n\n const k = STIFFNESS;\n const d = DAMPING;\n const dx = value.x - target.x;\n const dy = value.y - target.y;\n\n velocity.x += (-k * dx - d * velocity.x) * dt;\n velocity.y += (-k * dy - d * velocity.y) * dt;\n\n const nx = value.x + velocity.x * dt;\n const ny = value.y + velocity.y * dt;\n\n if (nx !== value.x || ny !== value.y) {\n value.x = nx;\n value.y = ny;\n updates.notify(value);\n }\n\n if (\n Math.abs(velocity.x) < EPSILON &&\n Math.abs(velocity.y) < EPSILON &&\n Math.abs(target.x - value.x) < EPSILON &&\n Math.abs(target.y - value.y) < EPSILON\n ) {\n if (value.x !== target.x || value.y !== target.y) {\n value.x = target.x;\n value.y = target.y;\n updates.notify(value);\n }\n\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n }\n },\n };\n\n return {\n get() {\n return value;\n },\n set(point: Coordinates | null) {\n if (point === null) {\n value = null;\n target = null;\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n loop.remove(spring);\n updates.notify(null);\n return;\n }\n\n if (value === null) {\n value = { x: point.x, y: point.y };\n target = point;\n velocity.x = 0;\n velocity.y = 0;\n updates.notify(value);\n return;\n }\n\n target = point;\n\n if (!spring.active && (value.x !== target.x || value.y !== target.y)) {\n spring.active = true;\n loop.add(spring);\n }\n },\n subscribe: updates.subscribe,\n dispose() {\n spring.active = false;\n loop.remove(spring);\n updates.dispose();\n },\n };\n}\n\nfunction PresenceCursor({\n connectionId,\n presenceKey,\n sizeRef,\n sizeEvents,\n}: {\n connectionId: number;\n presenceKey: string;\n sizeRef: MutableRefObject<Size | null>;\n sizeEvents: EventSource<void>;\n}) {\n const room = useRoom();\n const cursorRef = useRef<HTMLDivElement>(null);\n const userId = useOther(connectionId, (other) => $string(other.id));\n const { user, isLoading } = useUser(userId ?? \"\");\n const hasUserInfo = userId !== undefined && !isLoading;\n const color = $string(user?.color);\n const name = $string(user?.name);\n\n useLayoutEffect(() => {\n const spring = makeCoordinatesSpring();\n\n function update() {\n const element = cursorRef.current;\n const coordinates = spring.get();\n\n if (!element) {\n return;\n }\n\n if (!hasUserInfo || coordinates === null) {\n element.style.transform = \"translate3d(0, 0, 0)\";\n element.style.display = \"none\";\n return;\n }\n\n if (sizeRef.current) {\n element.style.transform = `translate3d(${coordinates.x * sizeRef.current.width}px, ${coordinates.y * sizeRef.current.height}px, 0)`;\n }\n\n element.style.display = \"\";\n }\n\n const unsubscribeSpring = spring.subscribe(update);\n const unsubscribeSize = sizeEvents.subscribe(update);\n update();\n\n const unsubscribeOther = room.events.others.subscribe(({ others }) => {\n const other = others.find((other) => other.connectionId === connectionId);\n const cursor = $coordinates(other?.presence[presenceKey]);\n\n spring.set(cursor ?? null);\n });\n\n return () => {\n spring.dispose();\n unsubscribeSpring();\n unsubscribeSize();\n unsubscribeOther();\n };\n }, [room, connectionId, presenceKey, sizeRef, sizeEvents, hasUserInfo]);\n\n return (\n <Cursor\n color={color}\n label={name}\n ref={cursorRef}\n style={{ display: \"none\" }}\n />\n );\n}\n\n/**\n * Displays multiplayer cursors.\n */\nexport const Cursors = forwardRef<HTMLDivElement, CursorsProps>(\n (\n { className, children, presenceKey = DEFAULT_PRESENCE_KEY, ...props },\n forwardedRef\n ) => {\n const ref = useRef<HTMLDivElement>(null);\n const updateMyPresence = useUpdateMyPresence();\n const othersConnectionIds = useOthersConnectionIds();\n const sizeRef = useRef<Size | null>(null);\n const [sizeEvents] = useState(() => makeEventSource<void>());\n const isWindowFocused = useWindowFocus();\n\n useEffect(() => {\n const element = ref.current;\n\n if (!element) {\n return;\n }\n\n function setSize(size: Size) {\n sizeRef.current = size;\n sizeEvents.notify();\n }\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target === element) {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n });\n }\n }\n });\n\n setSize({\n width: element.clientWidth,\n height: element.clientHeight,\n });\n\n observer.observe(element);\n\n return () => {\n observer.disconnect();\n };\n }, [sizeEvents]);\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n const element = ref.current;\n\n if (!element) {\n return;\n }\n\n const bounds = element.getBoundingClientRect();\n\n if (bounds.width === 0 || bounds.height === 0) {\n return;\n }\n\n updateMyPresence({\n [presenceKey]: {\n x: (event.clientX - bounds.left) / bounds.width,\n y: (event.clientY - bounds.top) / bounds.height,\n },\n });\n },\n [updateMyPresence, presenceKey]\n );\n\n const handlePointerLeave = useCallback(() => {\n updateMyPresence({\n [presenceKey]: null,\n });\n }, [updateMyPresence, presenceKey]);\n\n useEffect(() => {\n if (!isWindowFocused) {\n updateMyPresence({\n [presenceKey]: null,\n });\n }\n }, [isWindowFocused, updateMyPresence, presenceKey]);\n\n useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(\n forwardedRef,\n () => ref.current,\n []\n );\n\n return (\n <div\n className={cn(\"lb-root lb-cursors\", className)}\n {...props}\n onPointerMove={handlePointerMove}\n onPointerLeave={handlePointerLeave}\n ref={ref}\n >\n <div className=\"lb-cursors-container\">\n {othersConnectionIds.map((connectionId) => (\n <PresenceCursor\n key={connectionId}\n connectionId={connectionId}\n presenceKey={presenceKey}\n sizeRef={sizeRef}\n sizeEvents={sizeEvents}\n />\n ))}\n </div>\n\n {children}\n </div>\n );\n }\n);\n"],"names":["other"],"mappings":"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"}
1
+ {"version":3,"file":"Cursors.js","sources":["../../src/components/Cursors.tsx"],"sourcesContent":["import type { EventSource } from \"@liveblocks/core\";\nimport { isPlainObject, makeEventSource } from \"@liveblocks/core\";\nimport {\n useOther,\n useOthersConnectionIds,\n useRoom,\n useUpdateMyPresence,\n useUser,\n} from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComponentPropsWithoutRef,\n MutableRefObject,\n PointerEvent,\n} from \"react\";\nimport { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { type Animatable, makeAnimationLoop } from \"../utils/animation-loop\";\nimport { cn } from \"../utils/cn\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport { Cursor } from \"./Cursor\";\n\nconst STIFFNESS = 320;\nconst DAMPING = 32;\nconst EPSILON = 0.01;\n\nconst DEFAULT_PRESENCE_KEY = \"cursor\";\n\nexport interface CursorsProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The key used to store the cursors in users' Presence.\n * This can be used to have multiple `Cursors` in a single room.\n */\n presenceKey?: string;\n}\n\ntype Coordinates = {\n x: number;\n y: number;\n};\n\ntype Size = {\n width: number;\n height: number;\n};\n\nfunction $string(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction $coordinates(value: unknown): Coordinates | undefined {\n if (\n isPlainObject(value) &&\n typeof value.x === \"number\" &&\n typeof value.y === \"number\"\n ) {\n return value as Coordinates;\n }\n\n return undefined;\n}\n\n// Use a shared animation loop for all (active) springs.\nconst loop = makeAnimationLoop();\n\nfunction makeCoordinatesSpring() {\n const updates = makeEventSource<Coordinates | null>();\n let value: Coordinates | null = null;\n let target: Coordinates | null = null;\n const velocity = { x: 0, y: 0 };\n\n const spring: Animatable = {\n active: false,\n step(dt: number) {\n if (value === null || target === null) {\n spring.active = false;\n return;\n }\n\n const k = STIFFNESS;\n const d = DAMPING;\n const dx = value.x - target.x;\n const dy = value.y - target.y;\n\n velocity.x += (-k * dx - d * velocity.x) * dt;\n velocity.y += (-k * dy - d * velocity.y) * dt;\n\n const nx = value.x + velocity.x * dt;\n const ny = value.y + velocity.y * dt;\n\n if (nx !== value.x || ny !== value.y) {\n value.x = nx;\n value.y = ny;\n updates.notify(value);\n }\n\n if (\n Math.abs(velocity.x) < EPSILON &&\n Math.abs(velocity.y) < EPSILON &&\n Math.abs(target.x - value.x) < EPSILON &&\n Math.abs(target.y - value.y) < EPSILON\n ) {\n if (value.x !== target.x || value.y !== target.y) {\n value.x = target.x;\n value.y = target.y;\n updates.notify(value);\n }\n\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n }\n },\n };\n\n return {\n get() {\n return value;\n },\n set(point: Coordinates | null) {\n if (point === null) {\n value = null;\n target = null;\n velocity.x = 0;\n velocity.y = 0;\n spring.active = false;\n loop.remove(spring);\n updates.notify(null);\n return;\n }\n\n if (value === null) {\n value = { x: point.x, y: point.y };\n target = point;\n velocity.x = 0;\n velocity.y = 0;\n updates.notify(value);\n return;\n }\n\n target = point;\n\n if (!spring.active && (value.x !== target.x || value.y !== target.y)) {\n spring.active = true;\n loop.add(spring);\n }\n },\n subscribe: updates.subscribe,\n dispose() {\n spring.active = false;\n loop.remove(spring);\n updates.dispose();\n },\n };\n}\n\nfunction PresenceCursor({\n connectionId,\n presenceKey,\n sizeRef,\n sizeEvents,\n}: {\n connectionId: number;\n presenceKey: string;\n sizeRef: MutableRefObject<Size | null>;\n sizeEvents: EventSource<void>;\n}) {\n const room = useRoom();\n const cursorRef = useRef<HTMLDivElement>(null);\n const userId = useOther(connectionId, (other) => $string(other.id));\n const { user, isLoading } = useUser(userId ?? \"\");\n const hasUserInfo = userId !== undefined && !isLoading;\n const color = $string(user?.color);\n const name = $string(user?.name);\n\n useLayoutEffect(() => {\n const spring = makeCoordinatesSpring();\n\n function update() {\n const element = cursorRef.current;\n const coordinates = spring.get();\n\n if (!element) {\n return;\n }\n\n if (!hasUserInfo || coordinates === null) {\n element.style.transform = \"translate3d(0, 0, 0)\";\n element.style.display = \"none\";\n return;\n }\n\n if (sizeRef.current) {\n element.style.transform = `translate3d(${coordinates.x * sizeRef.current.width}px, ${coordinates.y * sizeRef.current.height}px, 0)`;\n }\n\n element.style.display = \"\";\n }\n\n const unsubscribeSpring = spring.subscribe(update);\n const unsubscribeSize = sizeEvents.subscribe(update);\n update();\n\n const unsubscribeOther = room.events.others.subscribe(({ others }) => {\n const other = others.find((other) => other.connectionId === connectionId);\n const cursor = $coordinates(other?.presence[presenceKey]);\n\n spring.set(cursor ?? null);\n });\n\n return () => {\n spring.dispose();\n unsubscribeSpring();\n unsubscribeSize();\n unsubscribeOther();\n };\n }, [room, connectionId, presenceKey, sizeRef, sizeEvents, hasUserInfo]);\n\n return (\n <Cursor\n color={color}\n label={name}\n ref={cursorRef}\n style={{ display: \"none\" }}\n />\n );\n}\n\n/**\n * Displays multiplayer cursors.\n */\nexport const Cursors = forwardRef<HTMLDivElement, CursorsProps>(\n (\n { className, children, presenceKey = DEFAULT_PRESENCE_KEY, ...props },\n forwardedRef\n ) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, containerRef);\n const updateMyPresence = useUpdateMyPresence();\n const othersConnectionIds = useOthersConnectionIds();\n const sizeRef = useRef<Size | null>(null);\n const [sizeEvents] = useState(() => makeEventSource<void>());\n const isWindowFocused = useWindowFocus();\n\n useEffect(() => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n function setSize(size: Size) {\n sizeRef.current = size;\n sizeEvents.notify();\n }\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n if (entry.target === container) {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n });\n }\n }\n });\n\n setSize({\n width: container.clientWidth,\n height: container.clientHeight,\n });\n\n observer.observe(container);\n\n return () => {\n observer.disconnect();\n };\n }, [sizeEvents]);\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n const bounds = container.getBoundingClientRect();\n\n if (bounds.width === 0 || bounds.height === 0) {\n return;\n }\n\n updateMyPresence({\n [presenceKey]: {\n x: (event.clientX - bounds.left) / bounds.width,\n y: (event.clientY - bounds.top) / bounds.height,\n },\n });\n },\n [updateMyPresence, presenceKey]\n );\n\n const handlePointerLeave = useCallback(() => {\n updateMyPresence({\n [presenceKey]: null,\n });\n }, [updateMyPresence, presenceKey]);\n\n useEffect(() => {\n if (!isWindowFocused) {\n updateMyPresence({\n [presenceKey]: null,\n });\n }\n }, [isWindowFocused, updateMyPresence, presenceKey]);\n\n return (\n <div\n className={cn(\"lb-root lb-cursors\", className)}\n {...props}\n onPointerMove={handlePointerMove}\n onPointerLeave={handlePointerLeave}\n ref={mergedRefs}\n >\n <div className=\"lb-cursors-container\">\n {othersConnectionIds.map((connectionId) => (\n <PresenceCursor\n key={connectionId}\n connectionId={connectionId}\n presenceKey={presenceKey}\n sizeRef={sizeRef}\n sizeEvents={sizeEvents}\n />\n ))}\n </div>\n\n {children}\n </div>\n );\n }\n);\n"],"names":["other"],"mappings":"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"}
@@ -9,6 +9,7 @@ var constants = require('../constants.cjs');
9
9
  var overrides = require('../overrides.cjs');
10
10
  var cn = require('../utils/cn.cjs');
11
11
  var useControllableState = require('../utils/use-controllable-state.cjs');
12
+ var useRefs = require('../utils/use-refs.cjs');
12
13
  var Composer = require('./Composer.cjs');
13
14
 
14
15
 
@@ -22,10 +23,13 @@ const FloatingComposer = react.forwardRef(
22
23
  sideOffset = constants.FLOATING_ELEMENT_SIDE_OFFSET,
23
24
  align = "start",
24
25
  alignOffset,
26
+ autoFocus = true,
25
27
  overrides: overrides$1,
26
28
  className,
27
29
  ...props
28
30
  }, forwardedRef) => {
31
+ const composerRef = react.useRef(null);
32
+ const mergedRefs = useRefs.useRefs(forwardedRef, composerRef);
29
33
  const $ = overrides.useOverrides(overrides$1);
30
34
  const { portalContainer } = config.useLiveblocksUiConfig();
31
35
  const [isOpen, setIsOpen] = useControllableState.useControllableState(
@@ -45,6 +49,7 @@ const FloatingComposer = react.forwardRef(
45
49
  dir: $.dir,
46
50
  side,
47
51
  sideOffset,
52
+ updatePositionStrategy: "always",
48
53
  align,
49
54
  alignOffset,
50
55
  collisionPadding: constants.FLOATING_ELEMENT_COLLISION_PADDING,
@@ -61,14 +66,21 @@ const FloatingComposer = react.forwardRef(
61
66
  event.preventDefault();
62
67
  }
63
68
  },
69
+ onOpenAutoFocus: (event) => {
70
+ if (!autoFocus) {
71
+ event.preventDefault();
72
+ composerRef.current?.focus();
73
+ }
74
+ },
64
75
  asChild: true,
65
76
  children: /* @__PURE__ */ jsxRuntime.jsx(
66
77
  Composer.Composer,
67
78
  {
68
- ref: forwardedRef,
79
+ ref: mergedRefs,
69
80
  overrides: overrides$1,
70
- autoFocus: true,
81
+ autoFocus,
71
82
  collapsed: false,
83
+ tabIndex: -1,
72
84
  ...props
73
85
  }
74
86
  )
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingComposer.cjs","sources":["../../src/components/FloatingComposer.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\n\nexport interface FloatingComposerProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<\n ComposerProps<TM, CM>,\n \"collapsed\" | \"onCollapsedChange\" | \"defaultCollapsed\"\n >,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating composer.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating composer attached to a trigger element.\n */\nexport const FloatingComposer = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n overrides,\n className,\n ...props\n }: FloatingComposerProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLFormElement>\n ) => {\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-composer\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n asChild\n >\n <Composer\n ref={forwardedRef}\n overrides={overrides}\n autoFocus\n collapsed={false}\n {...(props as ComposerProps<TM, CM>)}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingComposerProps<TM, CM> & RefAttributes<HTMLFormElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAgDO;AAAyB;AAE5B;AACE;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACA;AACA;AACG;AAIL;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACA;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACS;AACE;AACN;AAAA;AACP;AAAA;AAEJ;AACF;AAGN;;"}
1
+ {"version":3,"file":"FloatingComposer.cjs","sources":["../../src/components/FloatingComposer.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n useRef,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport { useRefs } from \"../utils/use-refs\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\n\nexport interface FloatingComposerProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<\n ComposerProps<TM, CM>,\n \"collapsed\" | \"onCollapsedChange\" | \"defaultCollapsed\"\n >,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating composer.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating composer attached to a trigger element.\n */\nexport const FloatingComposer = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n autoFocus = true,\n overrides,\n className,\n ...props\n }: FloatingComposerProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLFormElement>\n ) => {\n const composerRef = useRef<HTMLFormElement>(null);\n const mergedRefs = useRefs(forwardedRef, composerRef);\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-composer\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n updatePositionStrategy=\"always\"\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n onOpenAutoFocus={(event) => {\n if (!autoFocus) {\n event.preventDefault();\n composerRef.current?.focus();\n }\n }}\n asChild\n >\n <Composer\n ref={mergedRefs}\n overrides={overrides}\n autoFocus={autoFocus}\n collapsed={false}\n tabIndex={-1}\n {...(props as ComposerProps<TM, CM>)}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingComposerProps<TM, CM> & RefAttributes<HTMLFormElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AAkDO;AAAyB;AAE5B;AACE;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACY;AACZ;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACuB;AACvB;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AAEE;AACE;AACA;AAA2B;AAC7B;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACA;AACW;AACD;AACL;AAAA;AACP;AAAA;AAEJ;AACF;AAGN;;"}
@@ -1,12 +1,13 @@
1
1
  "use client";
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { Popover } from 'radix-ui';
4
- import { forwardRef } from 'react';
4
+ import { forwardRef, useRef } from 'react';
5
5
  import { useLiveblocksUiConfig } from '../config.js';
6
6
  import { FLOATING_ELEMENT_COLLISION_PADDING, FLOATING_ELEMENT_SIDE_OFFSET } from '../constants.js';
7
7
  import { useOverrides } from '../overrides.js';
8
8
  import { cn } from '../utils/cn.js';
9
9
  import { useControllableState } from '../utils/use-controllable-state.js';
10
+ import { useRefs } from '../utils/use-refs.js';
10
11
  import { Composer } from './Composer.js';
11
12
 
12
13
 
@@ -20,10 +21,13 @@ const FloatingComposer = forwardRef(
20
21
  sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,
21
22
  align = "start",
22
23
  alignOffset,
24
+ autoFocus = true,
23
25
  overrides,
24
26
  className,
25
27
  ...props
26
28
  }, forwardedRef) => {
29
+ const composerRef = useRef(null);
30
+ const mergedRefs = useRefs(forwardedRef, composerRef);
27
31
  const $ = useOverrides(overrides);
28
32
  const { portalContainer } = useLiveblocksUiConfig();
29
33
  const [isOpen, setIsOpen] = useControllableState(
@@ -43,6 +47,7 @@ const FloatingComposer = forwardRef(
43
47
  dir: $.dir,
44
48
  side,
45
49
  sideOffset,
50
+ updatePositionStrategy: "always",
46
51
  align,
47
52
  alignOffset,
48
53
  collisionPadding: FLOATING_ELEMENT_COLLISION_PADDING,
@@ -59,14 +64,21 @@ const FloatingComposer = forwardRef(
59
64
  event.preventDefault();
60
65
  }
61
66
  },
67
+ onOpenAutoFocus: (event) => {
68
+ if (!autoFocus) {
69
+ event.preventDefault();
70
+ composerRef.current?.focus();
71
+ }
72
+ },
62
73
  asChild: true,
63
74
  children: /* @__PURE__ */ jsx(
64
75
  Composer,
65
76
  {
66
- ref: forwardedRef,
77
+ ref: mergedRefs,
67
78
  overrides,
68
- autoFocus: true,
79
+ autoFocus,
69
80
  collapsed: false,
81
+ tabIndex: -1,
70
82
  ...props
71
83
  }
72
84
  )
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingComposer.js","sources":["../../src/components/FloatingComposer.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\n\nexport interface FloatingComposerProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<\n ComposerProps<TM, CM>,\n \"collapsed\" | \"onCollapsedChange\" | \"defaultCollapsed\"\n >,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating composer.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating composer attached to a trigger element.\n */\nexport const FloatingComposer = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n overrides,\n className,\n ...props\n }: FloatingComposerProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLFormElement>\n ) => {\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-composer\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n asChild\n >\n <Composer\n ref={forwardedRef}\n overrides={overrides}\n autoFocus\n collapsed={false}\n {...(props as ComposerProps<TM, CM>)}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingComposerProps<TM, CM> & RefAttributes<HTMLFormElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;AAgDO;AAAyB;AAE5B;AACE;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACA;AACA;AACG;AAIL;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACA;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACS;AACE;AACN;AAAA;AACP;AAAA;AAEJ;AACF;AAGN;;"}
1
+ {"version":3,"file":"FloatingComposer.js","sources":["../../src/components/FloatingComposer.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n useRef,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport { useRefs } from \"../utils/use-refs\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\n\nexport interface FloatingComposerProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<\n ComposerProps<TM, CM>,\n \"collapsed\" | \"onCollapsedChange\" | \"defaultCollapsed\"\n >,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating composer.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating composer attached to a trigger element.\n */\nexport const FloatingComposer = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n autoFocus = true,\n overrides,\n className,\n ...props\n }: FloatingComposerProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLFormElement>\n ) => {\n const composerRef = useRef<HTMLFormElement>(null);\n const mergedRefs = useRefs(forwardedRef, composerRef);\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-composer\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n updatePositionStrategy=\"always\"\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n onOpenAutoFocus={(event) => {\n if (!autoFocus) {\n event.preventDefault();\n composerRef.current?.focus();\n }\n }}\n asChild\n >\n <Composer\n ref={mergedRefs}\n overrides={overrides}\n autoFocus={autoFocus}\n collapsed={false}\n tabIndex={-1}\n {...(props as ComposerProps<TM, CM>)}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingComposerProps<TM, CM> & RefAttributes<HTMLFormElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;AAkDO;AAAyB;AAE5B;AACE;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACY;AACZ;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACuB;AACvB;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AAEE;AACE;AACA;AAA2B;AAC7B;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACA;AACW;AACD;AACL;AAAA;AACP;AAAA;AAEJ;AACF;AAGN;;"}
@@ -46,6 +46,7 @@ const FloatingThread = react.forwardRef(
46
46
  dir: $.dir,
47
47
  side,
48
48
  sideOffset,
49
+ updatePositionStrategy: "always",
49
50
  align,
50
51
  alignOffset,
51
52
  collisionPadding: constants.FLOATING_ELEMENT_COLLISION_PADDING,
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingThread.cjs","sources":["../../src/components/FloatingThread.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport type { ThreadProps } from \"./Thread\";\nimport { Thread } from \"./Thread\";\n\nexport interface FloatingThreadProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends ThreadProps<TM, CM>,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating thread.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating thread attached to a trigger element.\n */\nexport const FloatingThread = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n thread,\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n overrides,\n className,\n ...props\n }: FloatingThreadProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLDivElement>\n ) => {\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-thread\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n asChild\n >\n <Thread\n ref={forwardedRef}\n thread={thread}\n overrides={overrides}\n {...props}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingThreadProps<TM, CM> & RefAttributes<HTMLDivElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;AA6CO;AAAuB;AAE1B;AACE;AACA;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACA;AACA;AACG;AAIL;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACA;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACA;AACI;AAAA;AACN;AAAA;AAEJ;AACF;AAGN;;"}
1
+ {"version":3,"file":"FloatingThread.cjs","sources":["../../src/components/FloatingThread.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport type { ThreadProps } from \"./Thread\";\nimport { Thread } from \"./Thread\";\n\nexport interface FloatingThreadProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends ThreadProps<TM, CM>,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating thread.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating thread attached to a trigger element.\n */\nexport const FloatingThread = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n thread,\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n overrides,\n className,\n ...props\n }: FloatingThreadProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLDivElement>\n ) => {\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-thread\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n updatePositionStrategy=\"always\"\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n asChild\n >\n <Thread\n ref={forwardedRef}\n thread={thread}\n overrides={overrides}\n {...props}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingThreadProps<TM, CM> & RefAttributes<HTMLDivElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;AA6CO;AAAuB;AAE1B;AACE;AACA;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACA;AACA;AACG;AAIL;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACuB;AACvB;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACA;AACI;AAAA;AACN;AAAA;AAEJ;AACF;AAGN;;"}
@@ -44,6 +44,7 @@ const FloatingThread = forwardRef(
44
44
  dir: $.dir,
45
45
  side,
46
46
  sideOffset,
47
+ updatePositionStrategy: "always",
47
48
  align,
48
49
  alignOffset,
49
50
  collisionPadding: FLOATING_ELEMENT_COLLISION_PADDING,
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingThread.js","sources":["../../src/components/FloatingThread.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport type { ThreadProps } from \"./Thread\";\nimport { Thread } from \"./Thread\";\n\nexport interface FloatingThreadProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends ThreadProps<TM, CM>,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating thread.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating thread attached to a trigger element.\n */\nexport const FloatingThread = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n thread,\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n overrides,\n className,\n ...props\n }: FloatingThreadProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLDivElement>\n ) => {\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-thread\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n asChild\n >\n <Thread\n ref={forwardedRef}\n thread={thread}\n overrides={overrides}\n {...props}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingThreadProps<TM, CM> & RefAttributes<HTMLDivElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;AA6CO;AAAuB;AAE1B;AACE;AACA;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACA;AACA;AACG;AAIL;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACA;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACA;AACI;AAAA;AACN;AAAA;AAEJ;AACF;AAGN;;"}
1
+ {"version":3,"file":"FloatingThread.js","sources":["../../src/components/FloatingThread.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BaseMetadata, DCM, DTM, Relax } from \"@liveblocks/core\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport {\n type ForwardedRef,\n forwardRef,\n type ReactNode,\n type RefAttributes,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../constants\";\nimport { useOverrides } from \"../overrides\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport type { ThreadProps } from \"./Thread\";\nimport { Thread } from \"./Thread\";\n\nexport interface FloatingThreadProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends ThreadProps<TM, CM>,\n Relax<\n Pick<\n PopoverPrimitive.PopoverProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n > &\n Pick<\n PopoverPrimitive.PopoverContentProps,\n \"side\" | \"sideOffset\" | \"align\" | \"alignOffset\"\n >\n > {\n /**\n * The element which opens the floating thread.\n */\n children: ReactNode;\n}\n\n/**\n * Displays a floating thread attached to a trigger element.\n */\nexport const FloatingThread = forwardRef(\n <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n {\n thread,\n children,\n defaultOpen,\n open,\n onOpenChange,\n side = \"right\",\n sideOffset = FLOATING_ELEMENT_SIDE_OFFSET,\n align = \"start\",\n alignOffset,\n overrides,\n className,\n ...props\n }: FloatingThreadProps<TM, CM>,\n forwardedRef: ForwardedRef<HTMLDivElement>\n ) => {\n const $ = useOverrides(overrides);\n const { portalContainer } = useLiveblocksUiConfig();\n const [isOpen, setIsOpen] = useControllableState(\n defaultOpen ?? false,\n open,\n onOpenChange\n );\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>\n <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-floating-thread\",\n className\n )}\n dir={$.dir}\n side={side}\n sideOffset={sideOffset}\n updatePositionStrategy=\"always\"\n align={align}\n alignOffset={alignOffset}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n onEscapeKeyDown={(event) => {\n if (event.defaultPrevented) {\n return;\n }\n\n setIsOpen(false);\n\n // Prevent further parent layers from closing\n event.preventDefault();\n }}\n onInteractOutside={(event) => {\n // Prevent closing when interacting with elements inside portals\n // (e.g., emoji picker, dropdowns)\n const target = event.target as HTMLElement;\n if (target.closest(\".lb-portal\")) {\n event.preventDefault();\n }\n }}\n asChild\n >\n <Thread\n ref={forwardedRef}\n thread={thread}\n overrides={overrides}\n {...props}\n />\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n) as <TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM>(\n props: FloatingThreadProps<TM, CM> & RefAttributes<HTMLDivElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;AA6CO;AAAuB;AAE1B;AACE;AACA;AACA;AACA;AACA;AACO;AACM;AACL;AACR;AACA;AACA;AACG;AAIL;AACA;AACA;AAA4B;AACX;AACf;AACA;AAGF;AAEI;AAA4C;AAE1C;AAAkB;AAAjB;AACY;AACT;AACA;AACF;AACO;AACP;AACA;AACuB;AACvB;AACA;AACkB;AAEhB;AACE;AAAA;AAGF;AAGA;AAAqB;AACvB;AAIE;AACA;AACE;AAAqB;AACvB;AACF;AACO;AAEP;AAAC;AAAA;AACM;AACL;AACA;AACI;AAAA;AACN;AAAA;AAEJ;AACF;AAGN;;"}
@@ -39,6 +39,7 @@ function Dropdown({
39
39
  ),
40
40
  sideOffset: constants.FLOATING_ELEMENT_SIDE_OFFSET,
41
41
  collisionPadding: constants.FLOATING_ELEMENT_COLLISION_PADDING,
42
+ updatePositionStrategy: "always",
42
43
  ...props,
43
44
  children: content
44
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.cjs","sources":["../../../src/components/internal/Dropdown.tsx"],"sourcesContent":["\"use client\";\n\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { ReactNode } from \"react\";\nimport { forwardRef } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { useOverrides } from \"../../overrides\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface DropdownProps\n extends Pick<\n DropdownMenuPrimitive.DropdownMenuProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n >,\n Pick<DropdownMenuPrimitive.DropdownMenuTriggerProps, \"children\">,\n Omit<DropdownMenuPrimitive.DropdownMenuContentProps, \"content\"> {\n content: ReactNode;\n}\n\ninterface DropdownItemProps\n extends DropdownMenuPrimitive.DropdownMenuItemProps {\n icon?: ReactNode;\n}\n\nexport function Dropdown({\n children,\n content,\n defaultOpen,\n open,\n onOpenChange,\n className,\n ...props\n}: DropdownProps) {\n const $ = useOverrides();\n const { portalContainer } = useLiveblocksUiConfig();\n\n return (\n <DropdownMenuPrimitive.Root\n defaultOpen={defaultOpen}\n open={open}\n onOpenChange={onOpenChange}\n dir={$.dir}\n >\n {children}\n <DropdownMenuPrimitive.Portal container={portalContainer}>\n <DropdownMenuPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-dropdown\",\n className\n )}\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n {...props}\n >\n {content}\n </DropdownMenuPrimitive.Content>\n </DropdownMenuPrimitive.Portal>\n </DropdownMenuPrimitive.Root>\n );\n}\n\nexport const DropdownItem = forwardRef<HTMLDivElement, DropdownItemProps>(\n ({ children, className, icon, ...props }, forwardedRef) => {\n return (\n <DropdownMenuPrimitive.DropdownMenuItem\n className={cn(\"lb-dropdown-item\", className)}\n {...props}\n ref={forwardedRef}\n >\n {icon ? (\n <span className=\"lb-dropdown-item-icon lb-icon-container\">\n {icon}\n </span>\n ) : null}\n {children ? (\n <span className=\"lb-dropdown-item-label\">{children}</span>\n ) : null}\n </DropdownMenuPrimitive.DropdownMenuItem>\n );\n }\n);\n\nexport const DropdownTrigger = DropdownMenuPrimitive.Trigger;\n"],"names":[],"mappings":";;;;;;;;;;;;AA6BO;AAAkB;AACvB;AACA;AACA;AACA;AACA;AACA;AAEF;AACE;AACA;AAEA;AACE;AAAuB;AAAtB;AACC;AACA;AACA;AACO;AAEN;AAAA;AAEC;AAAuB;AAAtB;AACY;AACT;AACA;AACF;AACY;AACM;AACd;AAEH;AAAA;AAEL;AAAA;AAAA;AAGN;AAEO;AAAqB;AAExB;AACE;AAAuB;AAAtB;AAC4C;AACvC;AACC;AAEJ;AAIG;AAGA;AAAA;AAAA;AACN;AAGN;AAEO;;;;"}
1
+ {"version":3,"file":"Dropdown.cjs","sources":["../../../src/components/internal/Dropdown.tsx"],"sourcesContent":["\"use client\";\n\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { ReactNode } from \"react\";\nimport { forwardRef } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { useOverrides } from \"../../overrides\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface DropdownProps\n extends Pick<\n DropdownMenuPrimitive.DropdownMenuProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n >,\n Pick<DropdownMenuPrimitive.DropdownMenuTriggerProps, \"children\">,\n Omit<DropdownMenuPrimitive.DropdownMenuContentProps, \"content\"> {\n content: ReactNode;\n}\n\ninterface DropdownItemProps\n extends DropdownMenuPrimitive.DropdownMenuItemProps {\n icon?: ReactNode;\n}\n\nexport function Dropdown({\n children,\n content,\n defaultOpen,\n open,\n onOpenChange,\n className,\n ...props\n}: DropdownProps) {\n const $ = useOverrides();\n const { portalContainer } = useLiveblocksUiConfig();\n\n return (\n <DropdownMenuPrimitive.Root\n defaultOpen={defaultOpen}\n open={open}\n onOpenChange={onOpenChange}\n dir={$.dir}\n >\n {children}\n <DropdownMenuPrimitive.Portal container={portalContainer}>\n <DropdownMenuPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-dropdown\",\n className\n )}\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n updatePositionStrategy=\"always\"\n {...props}\n >\n {content}\n </DropdownMenuPrimitive.Content>\n </DropdownMenuPrimitive.Portal>\n </DropdownMenuPrimitive.Root>\n );\n}\n\nexport const DropdownItem = forwardRef<HTMLDivElement, DropdownItemProps>(\n ({ children, className, icon, ...props }, forwardedRef) => {\n return (\n <DropdownMenuPrimitive.DropdownMenuItem\n className={cn(\"lb-dropdown-item\", className)}\n {...props}\n ref={forwardedRef}\n >\n {icon ? (\n <span className=\"lb-dropdown-item-icon lb-icon-container\">\n {icon}\n </span>\n ) : null}\n {children ? (\n <span className=\"lb-dropdown-item-label\">{children}</span>\n ) : null}\n </DropdownMenuPrimitive.DropdownMenuItem>\n );\n }\n);\n\nexport const DropdownTrigger = DropdownMenuPrimitive.Trigger;\n"],"names":[],"mappings":";;;;;;;;;;;;AA6BO;AAAkB;AACvB;AACA;AACA;AACA;AACA;AACA;AAEF;AACE;AACA;AAEA;AACE;AAAuB;AAAtB;AACC;AACA;AACA;AACO;AAEN;AAAA;AAEC;AAAuB;AAAtB;AACY;AACT;AACA;AACF;AACY;AACM;AACK;AACnB;AAEH;AAAA;AAEL;AAAA;AAAA;AAGN;AAEO;AAAqB;AAExB;AACE;AAAuB;AAAtB;AAC4C;AACvC;AACC;AAEJ;AAIG;AAGA;AAAA;AAAA;AACN;AAGN;AAEO;;;;"}
@@ -37,6 +37,7 @@ function Dropdown({
37
37
  ),
38
38
  sideOffset: FLOATING_ELEMENT_SIDE_OFFSET,
39
39
  collisionPadding: FLOATING_ELEMENT_COLLISION_PADDING,
40
+ updatePositionStrategy: "always",
40
41
  ...props,
41
42
  children: content
42
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.js","sources":["../../../src/components/internal/Dropdown.tsx"],"sourcesContent":["\"use client\";\n\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { ReactNode } from \"react\";\nimport { forwardRef } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { useOverrides } from \"../../overrides\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface DropdownProps\n extends Pick<\n DropdownMenuPrimitive.DropdownMenuProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n >,\n Pick<DropdownMenuPrimitive.DropdownMenuTriggerProps, \"children\">,\n Omit<DropdownMenuPrimitive.DropdownMenuContentProps, \"content\"> {\n content: ReactNode;\n}\n\ninterface DropdownItemProps\n extends DropdownMenuPrimitive.DropdownMenuItemProps {\n icon?: ReactNode;\n}\n\nexport function Dropdown({\n children,\n content,\n defaultOpen,\n open,\n onOpenChange,\n className,\n ...props\n}: DropdownProps) {\n const $ = useOverrides();\n const { portalContainer } = useLiveblocksUiConfig();\n\n return (\n <DropdownMenuPrimitive.Root\n defaultOpen={defaultOpen}\n open={open}\n onOpenChange={onOpenChange}\n dir={$.dir}\n >\n {children}\n <DropdownMenuPrimitive.Portal container={portalContainer}>\n <DropdownMenuPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-dropdown\",\n className\n )}\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n {...props}\n >\n {content}\n </DropdownMenuPrimitive.Content>\n </DropdownMenuPrimitive.Portal>\n </DropdownMenuPrimitive.Root>\n );\n}\n\nexport const DropdownItem = forwardRef<HTMLDivElement, DropdownItemProps>(\n ({ children, className, icon, ...props }, forwardedRef) => {\n return (\n <DropdownMenuPrimitive.DropdownMenuItem\n className={cn(\"lb-dropdown-item\", className)}\n {...props}\n ref={forwardedRef}\n >\n {icon ? (\n <span className=\"lb-dropdown-item-icon lb-icon-container\">\n {icon}\n </span>\n ) : null}\n {children ? (\n <span className=\"lb-dropdown-item-label\">{children}</span>\n ) : null}\n </DropdownMenuPrimitive.DropdownMenuItem>\n );\n }\n);\n\nexport const DropdownTrigger = DropdownMenuPrimitive.Trigger;\n"],"names":[],"mappings":";;;;;;;;;;AA6BO;AAAkB;AACvB;AACA;AACA;AACA;AACA;AACA;AAEF;AACE;AACA;AAEA;AACE;AAAuB;AAAtB;AACC;AACA;AACA;AACO;AAEN;AAAA;AAEC;AAAuB;AAAtB;AACY;AACT;AACA;AACF;AACY;AACM;AACd;AAEH;AAAA;AAEL;AAAA;AAAA;AAGN;AAEO;AAAqB;AAExB;AACE;AAAuB;AAAtB;AAC4C;AACvC;AACC;AAEJ;AAIG;AAGA;AAAA;AAAA;AACN;AAGN;AAEO;;"}
1
+ {"version":3,"file":"Dropdown.js","sources":["../../../src/components/internal/Dropdown.tsx"],"sourcesContent":["\"use client\";\n\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { ReactNode } from \"react\";\nimport { forwardRef } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { useOverrides } from \"../../overrides\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface DropdownProps\n extends Pick<\n DropdownMenuPrimitive.DropdownMenuProps,\n \"defaultOpen\" | \"open\" | \"onOpenChange\"\n >,\n Pick<DropdownMenuPrimitive.DropdownMenuTriggerProps, \"children\">,\n Omit<DropdownMenuPrimitive.DropdownMenuContentProps, \"content\"> {\n content: ReactNode;\n}\n\ninterface DropdownItemProps\n extends DropdownMenuPrimitive.DropdownMenuItemProps {\n icon?: ReactNode;\n}\n\nexport function Dropdown({\n children,\n content,\n defaultOpen,\n open,\n onOpenChange,\n className,\n ...props\n}: DropdownProps) {\n const $ = useOverrides();\n const { portalContainer } = useLiveblocksUiConfig();\n\n return (\n <DropdownMenuPrimitive.Root\n defaultOpen={defaultOpen}\n open={open}\n onOpenChange={onOpenChange}\n dir={$.dir}\n >\n {children}\n <DropdownMenuPrimitive.Portal container={portalContainer}>\n <DropdownMenuPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-elevation lb-dropdown\",\n className\n )}\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n updatePositionStrategy=\"always\"\n {...props}\n >\n {content}\n </DropdownMenuPrimitive.Content>\n </DropdownMenuPrimitive.Portal>\n </DropdownMenuPrimitive.Root>\n );\n}\n\nexport const DropdownItem = forwardRef<HTMLDivElement, DropdownItemProps>(\n ({ children, className, icon, ...props }, forwardedRef) => {\n return (\n <DropdownMenuPrimitive.DropdownMenuItem\n className={cn(\"lb-dropdown-item\", className)}\n {...props}\n ref={forwardedRef}\n >\n {icon ? (\n <span className=\"lb-dropdown-item-icon lb-icon-container\">\n {icon}\n </span>\n ) : null}\n {children ? (\n <span className=\"lb-dropdown-item-label\">{children}</span>\n ) : null}\n </DropdownMenuPrimitive.DropdownMenuItem>\n );\n }\n);\n\nexport const DropdownTrigger = DropdownMenuPrimitive.Trigger;\n"],"names":[],"mappings":";;;;;;;;;;AA6BO;AAAkB;AACvB;AACA;AACA;AACA;AACA;AACA;AAEF;AACE;AACA;AAEA;AACE;AAAuB;AAAtB;AACC;AACA;AACA;AACO;AAEN;AAAA;AAEC;AAAuB;AAAtB;AACY;AACT;AACA;AACF;AACY;AACM;AACK;AACnB;AAEH;AAAA;AAEL;AAAA;AAAA;AAGN;AAEO;AAAqB;AAExB;AACE;AAAuB;AAAtB;AAC4C;AACvC;AACC;AAEJ;AAIG;AAGA;AAAA;AAAA;AACN;AAGN;AAEO;;"}
@@ -70,6 +70,7 @@ const EmojiPicker = react.forwardRef(
70
70
  {
71
71
  side: "top",
72
72
  align: "center",
73
+ updatePositionStrategy: "always",
73
74
  sideOffset: constants.FLOATING_ELEMENT_SIDE_OFFSET,
74
75
  collisionPadding: constants.FLOATING_ELEMENT_COLLISION_PADDING,
75
76
  className: cn.cn(
@@ -1 +1 @@
1
- {"version":3,"file":"EmojiPicker.cjs","sources":["../../../src/components/internal/EmojiPicker.tsx"],"sourcesContent":["import {\n type Emoji as FrimousseEmoji,\n EmojiPicker as EmojiPickerPrimitive,\n type EmojiPickerListCategoryHeaderProps,\n type EmojiPickerListEmojiProps,\n type EmojiPickerListRowProps,\n type Locale,\n} from \"frimousse\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport type { ComponentPropsWithoutRef, SyntheticEvent } from \"react\";\nimport { forwardRef, useCallback, useState } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { SearchIcon } from \"../../icons/Search\";\nimport { SpinnerIcon } from \"../../icons/Spinner\";\nimport { useOverrides } from \"../../overrides\";\nimport { cn } from \"../../utils/cn\";\nimport { Emoji } from \"./Emoji\";\nimport { Tooltip } from \"./Tooltip\";\n\nexport interface EmojiPickerProps extends ComponentPropsWithoutRef<\"div\"> {\n onOpenChange?: (open: boolean) => void;\n onEmojiSelect?: (emoji: string) => void;\n}\n\nfunction EmojiPickerListEmoji({\n emoji,\n className,\n ...props\n}: EmojiPickerListEmojiProps) {\n return (\n <button className={cn(\"lb-emoji-picker-emoji\", className)} {...props}>\n <Emoji emoji={emoji.emoji} />\n </button>\n );\n}\n\nfunction EmojiPickerListRow({\n children,\n className,\n ...props\n}: EmojiPickerListRowProps) {\n return (\n <div className={cn(\"lb-emoji-picker-row\", className)} {...props}>\n {children}\n </div>\n );\n}\n\nfunction EmojiPickerListCategoryHeader({\n category,\n className,\n ...props\n}: EmojiPickerListCategoryHeaderProps) {\n return (\n <div\n className={cn(\"lb-emoji-picker-category-header\", className)}\n {...props}\n >\n <span className=\"lb-emoji-picker-category-header-title\">\n {category.label}\n </span>\n </div>\n );\n}\n\nexport const EmojiPicker = forwardRef<HTMLDivElement, EmojiPickerProps>(\n (\n { onEmojiSelect, onOpenChange, children, className, ...props },\n forwardedRef\n ) => {\n const [isOpen, setOpen] = useState(false);\n const { portalContainer, emojibaseUrl } = useLiveblocksUiConfig();\n const $ = useOverrides();\n\n const handleOpenChange = useCallback(\n (isOpen: boolean) => {\n setOpen(isOpen);\n onOpenChange?.(isOpen);\n },\n [onOpenChange]\n );\n\n const handleEmojiSelect = useCallback(\n ({ emoji }: FrimousseEmoji) => {\n setOpen(false);\n onEmojiSelect?.(emoji);\n },\n [onEmojiSelect]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={handleOpenChange}>\n {children}\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n side=\"top\"\n align=\"center\"\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n className={cn(\n \"lb-root lb-portal lb-elevation lb-emoji-picker\",\n className\n )}\n {...props}\n ref={forwardedRef}\n asChild\n >\n <EmojiPickerPrimitive.Root\n onEmojiSelect={handleEmojiSelect}\n locale={$.locale as Locale}\n columns={10}\n emojiVersion={15.1}\n emojibaseUrl={emojibaseUrl}\n onClick={stopPropagation}\n >\n <div className=\"lb-emoji-picker-header\">\n <div className=\"lb-emoji-picker-search-container\">\n <EmojiPickerPrimitive.Search\n className=\"lb-emoji-picker-search\"\n placeholder={$.EMOJI_PICKER_SEARCH_PLACEHOLDER}\n autoFocus\n />\n <SearchIcon />\n </div>\n </div>\n <EmojiPickerPrimitive.Viewport className=\"lb-emoji-picker-content\">\n <EmojiPickerPrimitive.Loading className=\"lb-loading lb-emoji-picker-loading\">\n <SpinnerIcon />\n </EmojiPickerPrimitive.Loading>\n <EmojiPickerPrimitive.Empty className=\"lb-empty lb-emoji-picker-empty\">\n {$.EMOJI_PICKER_EMPTY}\n </EmojiPickerPrimitive.Empty>\n <EmojiPickerPrimitive.List\n className=\"lb-emoji-picker-list\"\n components={{\n CategoryHeader: EmojiPickerListCategoryHeader,\n Row: EmojiPickerListRow,\n Emoji: EmojiPickerListEmoji,\n }}\n />\n </EmojiPickerPrimitive.Viewport>\n <div className=\"lb-emoji-picker-footer\">\n <EmojiPickerPrimitive.ActiveEmoji>\n {({ emoji }) =>\n emoji ? (\n <>\n <div className=\"lb-emoji-picker-active-emoji\">\n {emoji.emoji}\n </div>\n <span className=\"lb-emoji-picker-active-emoji-label\">\n {emoji.label}\n </span>\n </>\n ) : (\n <span className=\"lb-emoji-picker-active-emoji-label lb-emoji-picker-active-emoji-label-placeholder\">\n Select an emoji…\n </span>\n )\n }\n </EmojiPickerPrimitive.ActiveEmoji>\n <Tooltip content={$.EMOJI_PICKER_CHANGE_SKIN_TONE}>\n <EmojiPickerPrimitive.SkinToneSelector className=\"lb-button lb-emoji-picker-skin-tone-selector\" />\n </Tooltip>\n </div>\n </EmojiPickerPrimitive.Root>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n);\n\nexport const EmojiPickerTrigger = PopoverPrimitive.Trigger;\n"],"names":["jsx","cn","Emoji","forwardRef","useState","useLiveblocksUiConfig","useOverrides","useCallback","isOpen","PopoverPrimitive","FLOATING_ELEMENT_SIDE_OFFSET","FLOATING_ELEMENT_COLLISION_PADDING","jsxs","EmojiPickerPrimitive","SearchIcon","SpinnerIcon","Fragment","Tooltip"],"mappings":"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"}
1
+ {"version":3,"file":"EmojiPicker.cjs","sources":["../../../src/components/internal/EmojiPicker.tsx"],"sourcesContent":["import {\n type Emoji as FrimousseEmoji,\n EmojiPicker as EmojiPickerPrimitive,\n type EmojiPickerListCategoryHeaderProps,\n type EmojiPickerListEmojiProps,\n type EmojiPickerListRowProps,\n type Locale,\n} from \"frimousse\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport type { ComponentPropsWithoutRef, SyntheticEvent } from \"react\";\nimport { forwardRef, useCallback, useState } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { SearchIcon } from \"../../icons/Search\";\nimport { SpinnerIcon } from \"../../icons/Spinner\";\nimport { useOverrides } from \"../../overrides\";\nimport { cn } from \"../../utils/cn\";\nimport { Emoji } from \"./Emoji\";\nimport { Tooltip } from \"./Tooltip\";\n\nexport interface EmojiPickerProps extends ComponentPropsWithoutRef<\"div\"> {\n onOpenChange?: (open: boolean) => void;\n onEmojiSelect?: (emoji: string) => void;\n}\n\nfunction EmojiPickerListEmoji({\n emoji,\n className,\n ...props\n}: EmojiPickerListEmojiProps) {\n return (\n <button className={cn(\"lb-emoji-picker-emoji\", className)} {...props}>\n <Emoji emoji={emoji.emoji} />\n </button>\n );\n}\n\nfunction EmojiPickerListRow({\n children,\n className,\n ...props\n}: EmojiPickerListRowProps) {\n return (\n <div className={cn(\"lb-emoji-picker-row\", className)} {...props}>\n {children}\n </div>\n );\n}\n\nfunction EmojiPickerListCategoryHeader({\n category,\n className,\n ...props\n}: EmojiPickerListCategoryHeaderProps) {\n return (\n <div\n className={cn(\"lb-emoji-picker-category-header\", className)}\n {...props}\n >\n <span className=\"lb-emoji-picker-category-header-title\">\n {category.label}\n </span>\n </div>\n );\n}\n\nexport const EmojiPicker = forwardRef<HTMLDivElement, EmojiPickerProps>(\n (\n { onEmojiSelect, onOpenChange, children, className, ...props },\n forwardedRef\n ) => {\n const [isOpen, setOpen] = useState(false);\n const { portalContainer, emojibaseUrl } = useLiveblocksUiConfig();\n const $ = useOverrides();\n\n const handleOpenChange = useCallback(\n (isOpen: boolean) => {\n setOpen(isOpen);\n onOpenChange?.(isOpen);\n },\n [onOpenChange]\n );\n\n const handleEmojiSelect = useCallback(\n ({ emoji }: FrimousseEmoji) => {\n setOpen(false);\n onEmojiSelect?.(emoji);\n },\n [onEmojiSelect]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={handleOpenChange}>\n {children}\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n side=\"top\"\n align=\"center\"\n updatePositionStrategy=\"always\"\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n className={cn(\n \"lb-root lb-portal lb-elevation lb-emoji-picker\",\n className\n )}\n {...props}\n ref={forwardedRef}\n asChild\n >\n <EmojiPickerPrimitive.Root\n onEmojiSelect={handleEmojiSelect}\n locale={$.locale as Locale}\n columns={10}\n emojiVersion={15.1}\n emojibaseUrl={emojibaseUrl}\n onClick={stopPropagation}\n >\n <div className=\"lb-emoji-picker-header\">\n <div className=\"lb-emoji-picker-search-container\">\n <EmojiPickerPrimitive.Search\n className=\"lb-emoji-picker-search\"\n placeholder={$.EMOJI_PICKER_SEARCH_PLACEHOLDER}\n autoFocus\n />\n <SearchIcon />\n </div>\n </div>\n <EmojiPickerPrimitive.Viewport className=\"lb-emoji-picker-content\">\n <EmojiPickerPrimitive.Loading className=\"lb-loading lb-emoji-picker-loading\">\n <SpinnerIcon />\n </EmojiPickerPrimitive.Loading>\n <EmojiPickerPrimitive.Empty className=\"lb-empty lb-emoji-picker-empty\">\n {$.EMOJI_PICKER_EMPTY}\n </EmojiPickerPrimitive.Empty>\n <EmojiPickerPrimitive.List\n className=\"lb-emoji-picker-list\"\n components={{\n CategoryHeader: EmojiPickerListCategoryHeader,\n Row: EmojiPickerListRow,\n Emoji: EmojiPickerListEmoji,\n }}\n />\n </EmojiPickerPrimitive.Viewport>\n <div className=\"lb-emoji-picker-footer\">\n <EmojiPickerPrimitive.ActiveEmoji>\n {({ emoji }) =>\n emoji ? (\n <>\n <div className=\"lb-emoji-picker-active-emoji\">\n {emoji.emoji}\n </div>\n <span className=\"lb-emoji-picker-active-emoji-label\">\n {emoji.label}\n </span>\n </>\n ) : (\n <span className=\"lb-emoji-picker-active-emoji-label lb-emoji-picker-active-emoji-label-placeholder\">\n Select an emoji…\n </span>\n )\n }\n </EmojiPickerPrimitive.ActiveEmoji>\n <Tooltip content={$.EMOJI_PICKER_CHANGE_SKIN_TONE}>\n <EmojiPickerPrimitive.SkinToneSelector className=\"lb-button lb-emoji-picker-skin-tone-selector\" />\n </Tooltip>\n </div>\n </EmojiPickerPrimitive.Root>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n);\n\nexport const EmojiPickerTrigger = PopoverPrimitive.Trigger;\n"],"names":["jsx","cn","Emoji","forwardRef","useState","useLiveblocksUiConfig","useOverrides","useCallback","isOpen","PopoverPrimitive","FLOATING_ELEMENT_SIDE_OFFSET","FLOATING_ELEMENT_COLLISION_PADDING","jsxs","EmojiPickerPrimitive","SearchIcon","SpinnerIcon","Fragment","Tooltip"],"mappings":"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"}
@@ -68,6 +68,7 @@ const EmojiPicker = forwardRef(
68
68
  {
69
69
  side: "top",
70
70
  align: "center",
71
+ updatePositionStrategy: "always",
71
72
  sideOffset: FLOATING_ELEMENT_SIDE_OFFSET,
72
73
  collisionPadding: FLOATING_ELEMENT_COLLISION_PADDING,
73
74
  className: cn(
@@ -1 +1 @@
1
- {"version":3,"file":"EmojiPicker.js","sources":["../../../src/components/internal/EmojiPicker.tsx"],"sourcesContent":["import {\n type Emoji as FrimousseEmoji,\n EmojiPicker as EmojiPickerPrimitive,\n type EmojiPickerListCategoryHeaderProps,\n type EmojiPickerListEmojiProps,\n type EmojiPickerListRowProps,\n type Locale,\n} from \"frimousse\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport type { ComponentPropsWithoutRef, SyntheticEvent } from \"react\";\nimport { forwardRef, useCallback, useState } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { SearchIcon } from \"../../icons/Search\";\nimport { SpinnerIcon } from \"../../icons/Spinner\";\nimport { useOverrides } from \"../../overrides\";\nimport { cn } from \"../../utils/cn\";\nimport { Emoji } from \"./Emoji\";\nimport { Tooltip } from \"./Tooltip\";\n\nexport interface EmojiPickerProps extends ComponentPropsWithoutRef<\"div\"> {\n onOpenChange?: (open: boolean) => void;\n onEmojiSelect?: (emoji: string) => void;\n}\n\nfunction EmojiPickerListEmoji({\n emoji,\n className,\n ...props\n}: EmojiPickerListEmojiProps) {\n return (\n <button className={cn(\"lb-emoji-picker-emoji\", className)} {...props}>\n <Emoji emoji={emoji.emoji} />\n </button>\n );\n}\n\nfunction EmojiPickerListRow({\n children,\n className,\n ...props\n}: EmojiPickerListRowProps) {\n return (\n <div className={cn(\"lb-emoji-picker-row\", className)} {...props}>\n {children}\n </div>\n );\n}\n\nfunction EmojiPickerListCategoryHeader({\n category,\n className,\n ...props\n}: EmojiPickerListCategoryHeaderProps) {\n return (\n <div\n className={cn(\"lb-emoji-picker-category-header\", className)}\n {...props}\n >\n <span className=\"lb-emoji-picker-category-header-title\">\n {category.label}\n </span>\n </div>\n );\n}\n\nexport const EmojiPicker = forwardRef<HTMLDivElement, EmojiPickerProps>(\n (\n { onEmojiSelect, onOpenChange, children, className, ...props },\n forwardedRef\n ) => {\n const [isOpen, setOpen] = useState(false);\n const { portalContainer, emojibaseUrl } = useLiveblocksUiConfig();\n const $ = useOverrides();\n\n const handleOpenChange = useCallback(\n (isOpen: boolean) => {\n setOpen(isOpen);\n onOpenChange?.(isOpen);\n },\n [onOpenChange]\n );\n\n const handleEmojiSelect = useCallback(\n ({ emoji }: FrimousseEmoji) => {\n setOpen(false);\n onEmojiSelect?.(emoji);\n },\n [onEmojiSelect]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={handleOpenChange}>\n {children}\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n side=\"top\"\n align=\"center\"\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n className={cn(\n \"lb-root lb-portal lb-elevation lb-emoji-picker\",\n className\n )}\n {...props}\n ref={forwardedRef}\n asChild\n >\n <EmojiPickerPrimitive.Root\n onEmojiSelect={handleEmojiSelect}\n locale={$.locale as Locale}\n columns={10}\n emojiVersion={15.1}\n emojibaseUrl={emojibaseUrl}\n onClick={stopPropagation}\n >\n <div className=\"lb-emoji-picker-header\">\n <div className=\"lb-emoji-picker-search-container\">\n <EmojiPickerPrimitive.Search\n className=\"lb-emoji-picker-search\"\n placeholder={$.EMOJI_PICKER_SEARCH_PLACEHOLDER}\n autoFocus\n />\n <SearchIcon />\n </div>\n </div>\n <EmojiPickerPrimitive.Viewport className=\"lb-emoji-picker-content\">\n <EmojiPickerPrimitive.Loading className=\"lb-loading lb-emoji-picker-loading\">\n <SpinnerIcon />\n </EmojiPickerPrimitive.Loading>\n <EmojiPickerPrimitive.Empty className=\"lb-empty lb-emoji-picker-empty\">\n {$.EMOJI_PICKER_EMPTY}\n </EmojiPickerPrimitive.Empty>\n <EmojiPickerPrimitive.List\n className=\"lb-emoji-picker-list\"\n components={{\n CategoryHeader: EmojiPickerListCategoryHeader,\n Row: EmojiPickerListRow,\n Emoji: EmojiPickerListEmoji,\n }}\n />\n </EmojiPickerPrimitive.Viewport>\n <div className=\"lb-emoji-picker-footer\">\n <EmojiPickerPrimitive.ActiveEmoji>\n {({ emoji }) =>\n emoji ? (\n <>\n <div className=\"lb-emoji-picker-active-emoji\">\n {emoji.emoji}\n </div>\n <span className=\"lb-emoji-picker-active-emoji-label\">\n {emoji.label}\n </span>\n </>\n ) : (\n <span className=\"lb-emoji-picker-active-emoji-label lb-emoji-picker-active-emoji-label-placeholder\">\n Select an emoji…\n </span>\n )\n }\n </EmojiPickerPrimitive.ActiveEmoji>\n <Tooltip content={$.EMOJI_PICKER_CHANGE_SKIN_TONE}>\n <EmojiPickerPrimitive.SkinToneSelector className=\"lb-button lb-emoji-picker-skin-tone-selector\" />\n </Tooltip>\n </div>\n </EmojiPickerPrimitive.Root>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n);\n\nexport const EmojiPickerTrigger = PopoverPrimitive.Trigger;\n"],"names":["isOpen","PopoverPrimitive","EmojiPickerPrimitive"],"mappings":"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"}
1
+ {"version":3,"file":"EmojiPicker.js","sources":["../../../src/components/internal/EmojiPicker.tsx"],"sourcesContent":["import {\n type Emoji as FrimousseEmoji,\n EmojiPicker as EmojiPickerPrimitive,\n type EmojiPickerListCategoryHeaderProps,\n type EmojiPickerListEmojiProps,\n type EmojiPickerListRowProps,\n type Locale,\n} from \"frimousse\";\nimport { Popover as PopoverPrimitive } from \"radix-ui\";\nimport type { ComponentPropsWithoutRef, SyntheticEvent } from \"react\";\nimport { forwardRef, useCallback, useState } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { SearchIcon } from \"../../icons/Search\";\nimport { SpinnerIcon } from \"../../icons/Spinner\";\nimport { useOverrides } from \"../../overrides\";\nimport { cn } from \"../../utils/cn\";\nimport { Emoji } from \"./Emoji\";\nimport { Tooltip } from \"./Tooltip\";\n\nexport interface EmojiPickerProps extends ComponentPropsWithoutRef<\"div\"> {\n onOpenChange?: (open: boolean) => void;\n onEmojiSelect?: (emoji: string) => void;\n}\n\nfunction EmojiPickerListEmoji({\n emoji,\n className,\n ...props\n}: EmojiPickerListEmojiProps) {\n return (\n <button className={cn(\"lb-emoji-picker-emoji\", className)} {...props}>\n <Emoji emoji={emoji.emoji} />\n </button>\n );\n}\n\nfunction EmojiPickerListRow({\n children,\n className,\n ...props\n}: EmojiPickerListRowProps) {\n return (\n <div className={cn(\"lb-emoji-picker-row\", className)} {...props}>\n {children}\n </div>\n );\n}\n\nfunction EmojiPickerListCategoryHeader({\n category,\n className,\n ...props\n}: EmojiPickerListCategoryHeaderProps) {\n return (\n <div\n className={cn(\"lb-emoji-picker-category-header\", className)}\n {...props}\n >\n <span className=\"lb-emoji-picker-category-header-title\">\n {category.label}\n </span>\n </div>\n );\n}\n\nexport const EmojiPicker = forwardRef<HTMLDivElement, EmojiPickerProps>(\n (\n { onEmojiSelect, onOpenChange, children, className, ...props },\n forwardedRef\n ) => {\n const [isOpen, setOpen] = useState(false);\n const { portalContainer, emojibaseUrl } = useLiveblocksUiConfig();\n const $ = useOverrides();\n\n const handleOpenChange = useCallback(\n (isOpen: boolean) => {\n setOpen(isOpen);\n onOpenChange?.(isOpen);\n },\n [onOpenChange]\n );\n\n const handleEmojiSelect = useCallback(\n ({ emoji }: FrimousseEmoji) => {\n setOpen(false);\n onEmojiSelect?.(emoji);\n },\n [onEmojiSelect]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n return (\n <PopoverPrimitive.Root open={isOpen} onOpenChange={handleOpenChange}>\n {children}\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n side=\"top\"\n align=\"center\"\n updatePositionStrategy=\"always\"\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n className={cn(\n \"lb-root lb-portal lb-elevation lb-emoji-picker\",\n className\n )}\n {...props}\n ref={forwardedRef}\n asChild\n >\n <EmojiPickerPrimitive.Root\n onEmojiSelect={handleEmojiSelect}\n locale={$.locale as Locale}\n columns={10}\n emojiVersion={15.1}\n emojibaseUrl={emojibaseUrl}\n onClick={stopPropagation}\n >\n <div className=\"lb-emoji-picker-header\">\n <div className=\"lb-emoji-picker-search-container\">\n <EmojiPickerPrimitive.Search\n className=\"lb-emoji-picker-search\"\n placeholder={$.EMOJI_PICKER_SEARCH_PLACEHOLDER}\n autoFocus\n />\n <SearchIcon />\n </div>\n </div>\n <EmojiPickerPrimitive.Viewport className=\"lb-emoji-picker-content\">\n <EmojiPickerPrimitive.Loading className=\"lb-loading lb-emoji-picker-loading\">\n <SpinnerIcon />\n </EmojiPickerPrimitive.Loading>\n <EmojiPickerPrimitive.Empty className=\"lb-empty lb-emoji-picker-empty\">\n {$.EMOJI_PICKER_EMPTY}\n </EmojiPickerPrimitive.Empty>\n <EmojiPickerPrimitive.List\n className=\"lb-emoji-picker-list\"\n components={{\n CategoryHeader: EmojiPickerListCategoryHeader,\n Row: EmojiPickerListRow,\n Emoji: EmojiPickerListEmoji,\n }}\n />\n </EmojiPickerPrimitive.Viewport>\n <div className=\"lb-emoji-picker-footer\">\n <EmojiPickerPrimitive.ActiveEmoji>\n {({ emoji }) =>\n emoji ? (\n <>\n <div className=\"lb-emoji-picker-active-emoji\">\n {emoji.emoji}\n </div>\n <span className=\"lb-emoji-picker-active-emoji-label\">\n {emoji.label}\n </span>\n </>\n ) : (\n <span className=\"lb-emoji-picker-active-emoji-label lb-emoji-picker-active-emoji-label-placeholder\">\n Select an emoji…\n </span>\n )\n }\n </EmojiPickerPrimitive.ActiveEmoji>\n <Tooltip content={$.EMOJI_PICKER_CHANGE_SKIN_TONE}>\n <EmojiPickerPrimitive.SkinToneSelector className=\"lb-button lb-emoji-picker-skin-tone-selector\" />\n </Tooltip>\n </div>\n </EmojiPickerPrimitive.Root>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n }\n);\n\nexport const EmojiPickerTrigger = PopoverPrimitive.Trigger;\n"],"names":["isOpen","PopoverPrimitive","EmojiPickerPrimitive"],"mappings":"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"}
@@ -62,6 +62,7 @@ const Tooltip = react.forwardRef(
62
62
  ),
63
63
  side: "top",
64
64
  align: "center",
65
+ updatePositionStrategy: "always",
65
66
  sideOffset: constants.FLOATING_ELEMENT_SIDE_OFFSET,
66
67
  collisionPadding: constants.FLOATING_ELEMENT_COLLISION_PADDING,
67
68
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.cjs","sources":["../../../src/components/internal/Tooltip.tsx"],"sourcesContent":["\"use client\";\n\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { cn } from \"../../utils/cn\";\nimport { isApple } from \"../../utils/is-apple\";\n\nconst ALT_KEY = { title: \"Alt\", key: \"⌥\" };\nconst COMMAND_KEY = { title: \"Command\", key: \"⌘\" };\nconst CONTROL_KEY = { title: \"Ctrl\", key: \"⌃\" };\nconst SHIFT_KEY = { title: \"Shift\", key: \"⇧\" };\nconst ENTER_KEY = { title: \"Enter\", key: \"⏎\" };\nconst SPACE_KEY = { title: \"Space\", key: \"␣\" };\nconst ESCAPE_KEY = { title: \"Escape\", key: \"⎋\" };\n\nconst KEYS = {\n alt: () => ALT_KEY,\n mod: () => (isApple() ? COMMAND_KEY : CONTROL_KEY),\n control: () => CONTROL_KEY,\n ctrl: () => CONTROL_KEY,\n command: () => COMMAND_KEY,\n cmd: () => COMMAND_KEY,\n shift: () => SHIFT_KEY,\n enter: () => ENTER_KEY,\n \" \": () => SPACE_KEY,\n space: () => SPACE_KEY,\n escape: () => ESCAPE_KEY,\n esc: () => ESCAPE_KEY,\n} as const;\n\nexport interface TooltipProps\n extends Pick<TooltipPrimitive.TooltipTriggerProps, \"children\">,\n Omit<TooltipPrimitive.TooltipContentProps, \"content\"> {\n content: ReactNode;\n multiline?: boolean;\n}\n\nexport interface ShortcutTooltipProps extends TooltipProps {\n shortcut?: string;\n}\n\nexport interface ShortcutTooltipKeyProps extends ComponentProps<\"abbr\"> {\n name: keyof typeof KEYS;\n}\n\nfunction getShortcutKbdFromKeymap(keymap: string) {\n const keys = keymap.split(\"-\");\n\n return (\n <>\n {keys.map((key, index) => {\n const lowerKey = key.toLowerCase();\n\n if (lowerKey in KEYS) {\n return (\n <ShortcutTooltipKey\n key={index}\n name={lowerKey as keyof typeof KEYS}\n />\n );\n }\n\n return <span key={index}>{key}</span>;\n })}\n </>\n );\n}\n\nexport const Tooltip = forwardRef<HTMLButtonElement, TooltipProps>(\n ({ children, content, multiline, className, ...props }, forwardedRef) => {\n const { portalContainer } = useLiveblocksUiConfig();\n\n return (\n <TooltipPrimitive.Root disableHoverableContent>\n <TooltipPrimitive.Trigger asChild ref={forwardedRef}>\n {children}\n </TooltipPrimitive.Trigger>\n <TooltipPrimitive.Portal container={portalContainer}>\n <TooltipPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-tooltip\",\n multiline && \"lb-tooltip:multiline\",\n className\n )}\n side=\"top\"\n align=\"center\"\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n {...props}\n >\n {content}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n </TooltipPrimitive.Root>\n );\n }\n);\n\nexport const ShortcutTooltip = forwardRef<\n HTMLButtonElement,\n ShortcutTooltipProps\n>(({ children, content, shortcut, ...props }, forwardedRef) => {\n const shortcutKbd = useMemo(() => {\n return shortcut ? getShortcutKbdFromKeymap(shortcut) : null;\n }, [shortcut]);\n\n return (\n <Tooltip\n content={\n <>\n {content}\n {shortcutKbd && (\n <kbd className=\"lb-tooltip-shortcut\">{shortcutKbd}</kbd>\n )}\n </>\n }\n {...props}\n ref={forwardedRef}\n >\n {children}\n </Tooltip>\n );\n});\n\nfunction ShortcutTooltipKey({ name, ...props }: ShortcutTooltipKeyProps) {\n const { title, key } = useMemo(() => KEYS[name]?.(), [name]);\n\n return (\n <abbr title={title} {...props}>\n {key}\n </abbr>\n );\n}\n\nexport const TooltipProvider = TooltipPrimitive.Provider;\n"],"names":[],"mappings":";;;;;;;;;;;;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAa;AACA;AAC2B;AACvB;AACH;AACG;AACJ;AACE;AACA;AACF;AACE;AACC;AAEhB;AAiBA;AACE;AAEA;AAGM;AAEA;AACE;AACE;AAAC;AAAA;AAEO;AAAA;AADD;AAEP;AAIJ;AAA8B;AAItC;AAEO;AAAgB;AAEnB;AAEA;AAEI;AAEA;AAEE;AAAkB;AAAjB;AACY;AACT;AACa;AACb;AACF;AACK;AACC;AACM;AACM;AACd;AAEH;AAAA;AAEL;AACF;AAGN;AAEa;AAIX;AACE;AAAuD;AAGzD;AACE;AAAC;AAAA;AAGM;AAAA;AAEmD;AAEtD;AAEE;AACC;AAEJ;AAAA;AAGP;AAEA;AACE;AAEA;AAKF;AAEO;;;;"}
1
+ {"version":3,"file":"Tooltip.cjs","sources":["../../../src/components/internal/Tooltip.tsx"],"sourcesContent":["\"use client\";\n\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { cn } from \"../../utils/cn\";\nimport { isApple } from \"../../utils/is-apple\";\n\nconst ALT_KEY = { title: \"Alt\", key: \"⌥\" };\nconst COMMAND_KEY = { title: \"Command\", key: \"⌘\" };\nconst CONTROL_KEY = { title: \"Ctrl\", key: \"⌃\" };\nconst SHIFT_KEY = { title: \"Shift\", key: \"⇧\" };\nconst ENTER_KEY = { title: \"Enter\", key: \"⏎\" };\nconst SPACE_KEY = { title: \"Space\", key: \"␣\" };\nconst ESCAPE_KEY = { title: \"Escape\", key: \"⎋\" };\n\nconst KEYS = {\n alt: () => ALT_KEY,\n mod: () => (isApple() ? COMMAND_KEY : CONTROL_KEY),\n control: () => CONTROL_KEY,\n ctrl: () => CONTROL_KEY,\n command: () => COMMAND_KEY,\n cmd: () => COMMAND_KEY,\n shift: () => SHIFT_KEY,\n enter: () => ENTER_KEY,\n \" \": () => SPACE_KEY,\n space: () => SPACE_KEY,\n escape: () => ESCAPE_KEY,\n esc: () => ESCAPE_KEY,\n} as const;\n\nexport interface TooltipProps\n extends Pick<TooltipPrimitive.TooltipTriggerProps, \"children\">,\n Omit<TooltipPrimitive.TooltipContentProps, \"content\"> {\n content: ReactNode;\n multiline?: boolean;\n}\n\nexport interface ShortcutTooltipProps extends TooltipProps {\n shortcut?: string;\n}\n\nexport interface ShortcutTooltipKeyProps extends ComponentProps<\"abbr\"> {\n name: keyof typeof KEYS;\n}\n\nfunction getShortcutKbdFromKeymap(keymap: string) {\n const keys = keymap.split(\"-\");\n\n return (\n <>\n {keys.map((key, index) => {\n const lowerKey = key.toLowerCase();\n\n if (lowerKey in KEYS) {\n return (\n <ShortcutTooltipKey\n key={index}\n name={lowerKey as keyof typeof KEYS}\n />\n );\n }\n\n return <span key={index}>{key}</span>;\n })}\n </>\n );\n}\n\nexport const Tooltip = forwardRef<HTMLButtonElement, TooltipProps>(\n ({ children, content, multiline, className, ...props }, forwardedRef) => {\n const { portalContainer } = useLiveblocksUiConfig();\n\n return (\n <TooltipPrimitive.Root disableHoverableContent>\n <TooltipPrimitive.Trigger asChild ref={forwardedRef}>\n {children}\n </TooltipPrimitive.Trigger>\n <TooltipPrimitive.Portal container={portalContainer}>\n <TooltipPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-tooltip\",\n multiline && \"lb-tooltip:multiline\",\n className\n )}\n side=\"top\"\n align=\"center\"\n updatePositionStrategy=\"always\"\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n {...props}\n >\n {content}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n </TooltipPrimitive.Root>\n );\n }\n);\n\nexport const ShortcutTooltip = forwardRef<\n HTMLButtonElement,\n ShortcutTooltipProps\n>(({ children, content, shortcut, ...props }, forwardedRef) => {\n const shortcutKbd = useMemo(() => {\n return shortcut ? getShortcutKbdFromKeymap(shortcut) : null;\n }, [shortcut]);\n\n return (\n <Tooltip\n content={\n <>\n {content}\n {shortcutKbd && (\n <kbd className=\"lb-tooltip-shortcut\">{shortcutKbd}</kbd>\n )}\n </>\n }\n {...props}\n ref={forwardedRef}\n >\n {children}\n </Tooltip>\n );\n});\n\nfunction ShortcutTooltipKey({ name, ...props }: ShortcutTooltipKeyProps) {\n const { title, key } = useMemo(() => KEYS[name]?.(), [name]);\n\n return (\n <abbr title={title} {...props}>\n {key}\n </abbr>\n );\n}\n\nexport const TooltipProvider = TooltipPrimitive.Provider;\n"],"names":[],"mappings":";;;;;;;;;;;;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAa;AACA;AAC2B;AACvB;AACH;AACG;AACJ;AACE;AACA;AACF;AACE;AACC;AAEhB;AAiBA;AACE;AAEA;AAGM;AAEA;AACE;AACE;AAAC;AAAA;AAEO;AAAA;AADD;AAEP;AAIJ;AAA8B;AAItC;AAEO;AAAgB;AAEnB;AAEA;AAEI;AAEA;AAEE;AAAkB;AAAjB;AACY;AACT;AACa;AACb;AACF;AACK;AACC;AACiB;AACX;AACM;AACd;AAEH;AAAA;AAEL;AACF;AAGN;AAEa;AAIX;AACE;AAAuD;AAGzD;AACE;AAAC;AAAA;AAGM;AAAA;AAEmD;AAEtD;AAEE;AACC;AAEJ;AAAA;AAGP;AAEA;AACE;AAEA;AAKF;AAEO;;;;"}
@@ -60,6 +60,7 @@ const Tooltip = forwardRef(
60
60
  ),
61
61
  side: "top",
62
62
  align: "center",
63
+ updatePositionStrategy: "always",
63
64
  sideOffset: FLOATING_ELEMENT_SIDE_OFFSET,
64
65
  collisionPadding: FLOATING_ELEMENT_COLLISION_PADDING,
65
66
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sources":["../../../src/components/internal/Tooltip.tsx"],"sourcesContent":["\"use client\";\n\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { cn } from \"../../utils/cn\";\nimport { isApple } from \"../../utils/is-apple\";\n\nconst ALT_KEY = { title: \"Alt\", key: \"⌥\" };\nconst COMMAND_KEY = { title: \"Command\", key: \"⌘\" };\nconst CONTROL_KEY = { title: \"Ctrl\", key: \"⌃\" };\nconst SHIFT_KEY = { title: \"Shift\", key: \"⇧\" };\nconst ENTER_KEY = { title: \"Enter\", key: \"⏎\" };\nconst SPACE_KEY = { title: \"Space\", key: \"␣\" };\nconst ESCAPE_KEY = { title: \"Escape\", key: \"⎋\" };\n\nconst KEYS = {\n alt: () => ALT_KEY,\n mod: () => (isApple() ? COMMAND_KEY : CONTROL_KEY),\n control: () => CONTROL_KEY,\n ctrl: () => CONTROL_KEY,\n command: () => COMMAND_KEY,\n cmd: () => COMMAND_KEY,\n shift: () => SHIFT_KEY,\n enter: () => ENTER_KEY,\n \" \": () => SPACE_KEY,\n space: () => SPACE_KEY,\n escape: () => ESCAPE_KEY,\n esc: () => ESCAPE_KEY,\n} as const;\n\nexport interface TooltipProps\n extends Pick<TooltipPrimitive.TooltipTriggerProps, \"children\">,\n Omit<TooltipPrimitive.TooltipContentProps, \"content\"> {\n content: ReactNode;\n multiline?: boolean;\n}\n\nexport interface ShortcutTooltipProps extends TooltipProps {\n shortcut?: string;\n}\n\nexport interface ShortcutTooltipKeyProps extends ComponentProps<\"abbr\"> {\n name: keyof typeof KEYS;\n}\n\nfunction getShortcutKbdFromKeymap(keymap: string) {\n const keys = keymap.split(\"-\");\n\n return (\n <>\n {keys.map((key, index) => {\n const lowerKey = key.toLowerCase();\n\n if (lowerKey in KEYS) {\n return (\n <ShortcutTooltipKey\n key={index}\n name={lowerKey as keyof typeof KEYS}\n />\n );\n }\n\n return <span key={index}>{key}</span>;\n })}\n </>\n );\n}\n\nexport const Tooltip = forwardRef<HTMLButtonElement, TooltipProps>(\n ({ children, content, multiline, className, ...props }, forwardedRef) => {\n const { portalContainer } = useLiveblocksUiConfig();\n\n return (\n <TooltipPrimitive.Root disableHoverableContent>\n <TooltipPrimitive.Trigger asChild ref={forwardedRef}>\n {children}\n </TooltipPrimitive.Trigger>\n <TooltipPrimitive.Portal container={portalContainer}>\n <TooltipPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-tooltip\",\n multiline && \"lb-tooltip:multiline\",\n className\n )}\n side=\"top\"\n align=\"center\"\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n {...props}\n >\n {content}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n </TooltipPrimitive.Root>\n );\n }\n);\n\nexport const ShortcutTooltip = forwardRef<\n HTMLButtonElement,\n ShortcutTooltipProps\n>(({ children, content, shortcut, ...props }, forwardedRef) => {\n const shortcutKbd = useMemo(() => {\n return shortcut ? getShortcutKbdFromKeymap(shortcut) : null;\n }, [shortcut]);\n\n return (\n <Tooltip\n content={\n <>\n {content}\n {shortcutKbd && (\n <kbd className=\"lb-tooltip-shortcut\">{shortcutKbd}</kbd>\n )}\n </>\n }\n {...props}\n ref={forwardedRef}\n >\n {children}\n </Tooltip>\n );\n});\n\nfunction ShortcutTooltipKey({ name, ...props }: ShortcutTooltipKeyProps) {\n const { title, key } = useMemo(() => KEYS[name]?.(), [name]);\n\n return (\n <abbr title={title} {...props}>\n {key}\n </abbr>\n );\n}\n\nexport const TooltipProvider = TooltipPrimitive.Provider;\n"],"names":[],"mappings":";;;;;;;;;;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAa;AACA;AAC2B;AACvB;AACH;AACG;AACJ;AACE;AACA;AACF;AACE;AACC;AAEhB;AAiBA;AACE;AAEA;AAGM;AAEA;AACE;AACE;AAAC;AAAA;AAEO;AAAA;AADD;AAEP;AAIJ;AAA8B;AAItC;AAEO;AAAgB;AAEnB;AAEA;AAEI;AAEA;AAEE;AAAkB;AAAjB;AACY;AACT;AACa;AACb;AACF;AACK;AACC;AACM;AACM;AACd;AAEH;AAAA;AAEL;AACF;AAGN;AAEa;AAIX;AACE;AAAuD;AAGzD;AACE;AAAC;AAAA;AAGM;AAAA;AAEmD;AAEtD;AAEE;AACC;AAEJ;AAAA;AAGP;AAEA;AACE;AAEA;AAKF;AAEO;;"}
1
+ {"version":3,"file":"Tooltip.js","sources":["../../../src/components/internal/Tooltip.tsx"],"sourcesContent":["\"use client\";\n\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../../config\";\nimport {\n FLOATING_ELEMENT_COLLISION_PADDING,\n FLOATING_ELEMENT_SIDE_OFFSET,\n} from \"../../constants\";\nimport { cn } from \"../../utils/cn\";\nimport { isApple } from \"../../utils/is-apple\";\n\nconst ALT_KEY = { title: \"Alt\", key: \"⌥\" };\nconst COMMAND_KEY = { title: \"Command\", key: \"⌘\" };\nconst CONTROL_KEY = { title: \"Ctrl\", key: \"⌃\" };\nconst SHIFT_KEY = { title: \"Shift\", key: \"⇧\" };\nconst ENTER_KEY = { title: \"Enter\", key: \"⏎\" };\nconst SPACE_KEY = { title: \"Space\", key: \"␣\" };\nconst ESCAPE_KEY = { title: \"Escape\", key: \"⎋\" };\n\nconst KEYS = {\n alt: () => ALT_KEY,\n mod: () => (isApple() ? COMMAND_KEY : CONTROL_KEY),\n control: () => CONTROL_KEY,\n ctrl: () => CONTROL_KEY,\n command: () => COMMAND_KEY,\n cmd: () => COMMAND_KEY,\n shift: () => SHIFT_KEY,\n enter: () => ENTER_KEY,\n \" \": () => SPACE_KEY,\n space: () => SPACE_KEY,\n escape: () => ESCAPE_KEY,\n esc: () => ESCAPE_KEY,\n} as const;\n\nexport interface TooltipProps\n extends Pick<TooltipPrimitive.TooltipTriggerProps, \"children\">,\n Omit<TooltipPrimitive.TooltipContentProps, \"content\"> {\n content: ReactNode;\n multiline?: boolean;\n}\n\nexport interface ShortcutTooltipProps extends TooltipProps {\n shortcut?: string;\n}\n\nexport interface ShortcutTooltipKeyProps extends ComponentProps<\"abbr\"> {\n name: keyof typeof KEYS;\n}\n\nfunction getShortcutKbdFromKeymap(keymap: string) {\n const keys = keymap.split(\"-\");\n\n return (\n <>\n {keys.map((key, index) => {\n const lowerKey = key.toLowerCase();\n\n if (lowerKey in KEYS) {\n return (\n <ShortcutTooltipKey\n key={index}\n name={lowerKey as keyof typeof KEYS}\n />\n );\n }\n\n return <span key={index}>{key}</span>;\n })}\n </>\n );\n}\n\nexport const Tooltip = forwardRef<HTMLButtonElement, TooltipProps>(\n ({ children, content, multiline, className, ...props }, forwardedRef) => {\n const { portalContainer } = useLiveblocksUiConfig();\n\n return (\n <TooltipPrimitive.Root disableHoverableContent>\n <TooltipPrimitive.Trigger asChild ref={forwardedRef}>\n {children}\n </TooltipPrimitive.Trigger>\n <TooltipPrimitive.Portal container={portalContainer}>\n <TooltipPrimitive.Content\n className={cn(\n \"lb-root lb-portal lb-tooltip\",\n multiline && \"lb-tooltip:multiline\",\n className\n )}\n side=\"top\"\n align=\"center\"\n updatePositionStrategy=\"always\"\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n {...props}\n >\n {content}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n </TooltipPrimitive.Root>\n );\n }\n);\n\nexport const ShortcutTooltip = forwardRef<\n HTMLButtonElement,\n ShortcutTooltipProps\n>(({ children, content, shortcut, ...props }, forwardedRef) => {\n const shortcutKbd = useMemo(() => {\n return shortcut ? getShortcutKbdFromKeymap(shortcut) : null;\n }, [shortcut]);\n\n return (\n <Tooltip\n content={\n <>\n {content}\n {shortcutKbd && (\n <kbd className=\"lb-tooltip-shortcut\">{shortcutKbd}</kbd>\n )}\n </>\n }\n {...props}\n ref={forwardedRef}\n >\n {children}\n </Tooltip>\n );\n});\n\nfunction ShortcutTooltipKey({ name, ...props }: ShortcutTooltipKeyProps) {\n const { title, key } = useMemo(() => KEYS[name]?.(), [name]);\n\n return (\n <abbr title={title} {...props}>\n {key}\n </abbr>\n );\n}\n\nexport const TooltipProvider = TooltipPrimitive.Provider;\n"],"names":[],"mappings":";;;;;;;;;;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAa;AACA;AAC2B;AACvB;AACH;AACG;AACJ;AACE;AACA;AACF;AACE;AACC;AAEhB;AAiBA;AACE;AAEA;AAGM;AAEA;AACE;AACE;AAAC;AAAA;AAEO;AAAA;AADD;AAEP;AAIJ;AAA8B;AAItC;AAEO;AAAgB;AAEnB;AAEA;AAEI;AAEA;AAEE;AAAkB;AAAjB;AACY;AACT;AACa;AACb;AACF;AACK;AACC;AACiB;AACX;AACM;AACd;AAEH;AAAA;AAEL;AACF;AAGN;AAEa;AAIX;AACE;AAAuD;AAGzD;AACE;AAAC;AAAA;AAGM;AAAA;AAEmD;AAEtD;AAEE;AACC;AAEJ;AAAA;AAGP;AAEA;AACE;AAEA;AAKF;AAEO;;"}
package/dist/icon.cjs CHANGED
@@ -32,6 +32,7 @@ var Lengthen = require('./icons/Lengthen.cjs');
32
32
  var ListOrdered = require('./icons/ListOrdered.cjs');
33
33
  var ListUnordered = require('./icons/ListUnordered.cjs');
34
34
  var Mention = require('./icons/Mention.cjs');
35
+ var Plus = require('./icons/Plus.cjs');
35
36
  var QuestionMark = require('./icons/QuestionMark.cjs');
36
37
  var Redo = require('./icons/Redo.cjs');
37
38
  var Retry = require('./icons/Retry.cjs');
@@ -83,6 +84,7 @@ exports.Lengthen = Lengthen.LengthenIcon;
83
84
  exports.ListOrdered = ListOrdered.ListOrderedIcon;
84
85
  exports.ListUnordered = ListUnordered.ListUnorderedIcon;
85
86
  exports.Mention = Mention.MentionIcon;
87
+ exports.Plus = Plus.PlusIcon;
86
88
  exports.QuestionMark = QuestionMark.QuestionMarkIcon;
87
89
  exports.Redo = Redo.RedoIcon;
88
90
  exports.Retry = Retry.RetryIcon;