@underverse-ui/underverse 2.0.16 → 2.0.18

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 (29) hide show
  1. package/README.md +18 -0
  2. package/api-reference.json +16 -2
  3. package/dist/{EmojiPicker-3X2S7XPP.js → EmojiPicker-SFPFCRI4.js} +4 -4
  4. package/dist/{chunk-HTGAV4IG.js → chunk-LQCKCWVZ.js} +3 -3
  5. package/dist/{chunk-YM56RXIZ.js → chunk-MSTO23JM.js} +6 -6
  6. package/dist/{chunk-HEXF4EOB.js → chunk-NJ53GV74.js} +3 -3
  7. package/dist/{chunk-EPBYGZHZ.js → chunk-PZCD342B.js} +6 -4
  8. package/dist/{chunk-EPBYGZHZ.js.map → chunk-PZCD342B.js.map} +1 -1
  9. package/dist/{chunk-23VKHYEB.js → chunk-RSLY7UU2.js} +70 -50
  10. package/dist/chunk-RSLY7UU2.js.map +1 -0
  11. package/dist/{chunk-SKCO2GFM.js → chunk-SBDZKVUJ.js} +2 -2
  12. package/dist/index.cjs +111 -75
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +12 -4
  15. package/dist/index.d.ts +12 -4
  16. package/dist/index.js +46 -32
  17. package/dist/index.js.map +1 -1
  18. package/dist/{menu-bar-7MPCNTHR.js → menu-bar-JXYQ5CH5.js} +4 -4
  19. package/dist/ueditor.cjs +69 -47
  20. package/dist/ueditor.cjs.map +1 -1
  21. package/dist/ueditor.js +4 -4
  22. package/package.json +2 -1
  23. package/dist/chunk-23VKHYEB.js.map +0 -1
  24. /package/dist/{EmojiPicker-3X2S7XPP.js.map → EmojiPicker-SFPFCRI4.js.map} +0 -0
  25. /package/dist/{chunk-HTGAV4IG.js.map → chunk-LQCKCWVZ.js.map} +0 -0
  26. /package/dist/{chunk-YM56RXIZ.js.map → chunk-MSTO23JM.js.map} +0 -0
  27. /package/dist/{chunk-HEXF4EOB.js.map → chunk-NJ53GV74.js.map} +0 -0
  28. /package/dist/{chunk-SKCO2GFM.js.map → chunk-SBDZKVUJ.js.map} +0 -0
  29. /package/dist/{menu-bar-7MPCNTHR.js.map → menu-bar-JXYQ5CH5.js.map} +0 -0
@@ -11,7 +11,7 @@ import {
11
11
  setRefValue,
12
12
  useSmartTranslations,
13
13
  useUEditorPortalContainerGetter
14
- } from "./chunk-EPBYGZHZ.js";
14
+ } from "./chunk-PZCD342B.js";
15
15
 
16
16
  // src/contexts/UnderverseConfigContext.tsx
17
17
  import * as React from "react";
@@ -192,24 +192,26 @@ var shadcnAnimationStyles = `
192
192
  transition: backdrop-filter 200ms ease, background-color 200ms ease;
193
193
  }
194
194
  `;
195
- function ensureAnimationStylesInjected() {
196
- if (typeof document !== "undefined") {
195
+ function ensureAnimationStylesInjected(targetDocument) {
196
+ const resolvedDocument = targetDocument ?? (typeof document !== "undefined" ? document : void 0);
197
+ if (resolvedDocument) {
197
198
  const styleId = "shadcn-animations";
198
- if (!document.getElementById(styleId)) {
199
- const styleElement = document.createElement("style");
199
+ if (!resolvedDocument.getElementById(styleId)) {
200
+ const styleElement = resolvedDocument.createElement("style");
200
201
  styleElement.id = styleId;
201
202
  styleElement.textContent = shadcnAnimationStyles;
202
- document.head.appendChild(styleElement);
203
+ resolvedDocument.head.appendChild(styleElement);
203
204
  }
204
205
  }
205
206
  }
206
- function useShadCNAnimations() {
207
+ function useShadCNAnimations(targetDocument) {
207
208
  useEffect(() => {
208
- ensureAnimationStylesInjected();
209
- }, []);
209
+ if (targetDocument === null) return;
210
+ ensureAnimationStylesInjected(targetDocument);
211
+ }, [targetDocument]);
210
212
  }
211
- function injectAnimationStyles() {
212
- ensureAnimationStylesInjected();
213
+ function injectAnimationStyles(targetDocument) {
214
+ ensureAnimationStylesInjected(targetDocument);
213
215
  }
214
216
  function getAnimationStyles() {
215
217
  return shadcnAnimationStyles;
@@ -277,20 +279,30 @@ function overflowAmount(left, width, viewportWidth, padding) {
277
279
  return overflowLeft + overflowRight;
278
280
  }
279
281
  function computePopoverPosition(args) {
280
- const { triggerRect, contentSize, placement, offset, padding, viewport } = args;
282
+ const { triggerRect, contentSize, placement, offset, padding, viewport, constrainToAvailableHeight } = args;
281
283
  let { side, align } = normalizePlacement(placement);
284
+ const availableBelow = Math.max(0, viewport.height - padding - triggerRect.bottom - offset);
285
+ const availableAbove = Math.max(0, triggerRect.top - padding - offset);
282
286
  if (side === "bottom") {
283
- const bottomTop = triggerRect.bottom + offset;
284
- const overflowsBottom = bottomTop + contentSize.height > viewport.height - padding;
285
- const topTop = triggerRect.top - offset - contentSize.height;
286
- const fitsTop = topTop >= padding;
287
- if (overflowsBottom && fitsTop) side = "top";
287
+ if (constrainToAvailableHeight) {
288
+ if (contentSize.height > availableBelow && availableAbove > availableBelow) side = "top";
289
+ } else {
290
+ const bottomTop = triggerRect.bottom + offset;
291
+ const overflowsBottom = bottomTop + contentSize.height > viewport.height - padding;
292
+ const topTop = triggerRect.top - offset - contentSize.height;
293
+ const fitsTop = topTop >= padding;
294
+ if (overflowsBottom && fitsTop) side = "top";
295
+ }
288
296
  } else if (side === "top") {
289
- const topTop = triggerRect.top - offset - contentSize.height;
290
- const overflowsTop = topTop < padding;
291
- const bottomTop = triggerRect.bottom + offset;
292
- const fitsBottom = bottomTop + contentSize.height <= viewport.height - padding;
293
- if (overflowsTop && fitsBottom) side = "bottom";
297
+ if (constrainToAvailableHeight) {
298
+ if (contentSize.height > availableAbove && availableBelow > availableAbove) side = "bottom";
299
+ } else {
300
+ const topTop = triggerRect.top - offset - contentSize.height;
301
+ const overflowsTop = topTop < padding;
302
+ const bottomTop = triggerRect.bottom + offset;
303
+ const fitsBottom = bottomTop + contentSize.height <= viewport.height - padding;
304
+ if (overflowsTop && fitsBottom) side = "bottom";
305
+ }
294
306
  } else if (side === "right") {
295
307
  const rightLeft = triggerRect.right + offset;
296
308
  const overflowsRight = rightLeft + contentSize.width > viewport.width - padding;
@@ -314,16 +326,18 @@ function computePopoverPosition(args) {
314
326
  if (align === "start" && startOverflow > 0 && endOverflow < startOverflow) align = "end";
315
327
  if (align === "end" && endOverflow > 0 && startOverflow < endOverflow) align = "start";
316
328
  left = align === "end" ? leftEnd : leftStart;
317
- top = side === "top" ? triggerRect.top - offset - contentSize.height : triggerRect.bottom + offset;
329
+ const availableHeight = side === "top" ? availableAbove : availableBelow;
330
+ const renderedHeight = constrainToAvailableHeight ? Math.min(contentSize.height, availableHeight) : contentSize.height;
331
+ top = side === "top" ? triggerRect.top - offset - renderedHeight : triggerRect.bottom + offset;
318
332
  left = clamp(left, padding, viewport.width - contentSize.width - padding);
319
- top = clamp(top, padding, viewport.height - contentSize.height - padding);
320
- return { top, left, side, align };
333
+ top = clamp(top, padding, viewport.height - renderedHeight - padding);
334
+ return { top, left, side, align, availableHeight };
321
335
  }
322
336
  top = triggerRect.top;
323
337
  left = side === "left" ? triggerRect.left - offset - contentSize.width : triggerRect.right + offset;
324
338
  left = clamp(left, padding, viewport.width - contentSize.width - padding);
325
339
  top = clamp(top, padding, viewport.height - contentSize.height - padding);
326
- return { top, left, side, align };
340
+ return { top, left, side, align, availableHeight: Math.max(0, viewport.height - padding * 2) };
327
341
  }
328
342
  var Popover = ({
329
343
  trigger,
@@ -339,7 +353,9 @@ var Popover = ({
339
353
  onOpenChange,
340
354
  matchTriggerWidth = false,
341
355
  contentWidth,
342
- borderMode
356
+ borderMode,
357
+ getPortalContainer,
358
+ constrainToAvailableHeight = false
343
359
  }) => {
344
360
  const isControlled = open !== void 0;
345
361
  const [internalOpen, setInternalOpen] = React2.useState(false);
@@ -347,14 +363,14 @@ var Popover = ({
347
363
  const positionerRef = React2.useRef(null);
348
364
  const panelRef = React2.useRef(null);
349
365
  const lastAppliedRef = React2.useRef(null);
350
- useShadCNAnimations();
351
366
  const globalConfig = useUnderverseUIConfig();
352
367
  const resolvedBorderMode = borderMode ?? globalConfig.popover?.borderMode ?? globalConfig.borderMode;
353
368
  const isOpen = isControlled ? open : internalOpen;
354
- const getPortalContainer = useUEditorPortalContainerGetter();
355
- const portalContainer = isOpen ? resolveUEditorPortalContainer(getPortalContainer) : null;
369
+ const contextGetPortalContainer = useUEditorPortalContainerGetter();
370
+ const portalContainer = isOpen ? resolveUEditorPortalContainer(getPortalContainer, contextGetPortalContainer) : null;
356
371
  const portalDocument = portalContainer?.ownerDocument ?? null;
357
372
  const portalWindow = portalDocument?.defaultView ?? null;
373
+ useShadCNAnimations(portalDocument);
358
374
  const setIsOpen = React2.useCallback(
359
375
  (next) => {
360
376
  if (!isControlled) setInternalOpen(next);
@@ -364,20 +380,14 @@ var Popover = ({
364
380
  );
365
381
  const offset = 4;
366
382
  const padding = 8;
367
- const triggerSelector = React2.useId();
368
383
  const initialPlacement = React2.useMemo(() => normalizePlacement(placement), [placement]);
369
- React2.useLayoutEffect(() => {
370
- if (typeof document === "undefined") return;
371
- const triggerEl = document.querySelector(`[data-underverse-popover-trigger="${triggerSelector}"]`);
372
- if (triggerEl) {
373
- triggerRef.current = triggerEl;
374
- }
375
- }, [triggerSelector, trigger]);
376
384
  const updatePosition = React2.useCallback(() => {
377
385
  const triggerEl = triggerRef.current;
378
386
  const positionerEl = positionerRef.current;
379
387
  const panelEl = panelRef.current;
380
- if (!triggerEl || !positionerEl || !panelEl) return;
388
+ if (!triggerEl || !positionerEl || !panelEl || !portalWindow) return;
389
+ const contentEl = panelEl.firstElementChild;
390
+ if (!contentEl) return;
381
391
  const triggerRect = triggerEl.getBoundingClientRect();
382
392
  const widthWanted = matchTriggerWidth ? triggerRect.width : contentWidth;
383
393
  const widthPx = widthWanted == null ? void 0 : Math.max(0, Math.round(widthWanted));
@@ -391,7 +401,7 @@ var Popover = ({
391
401
  const measuredHeight = positionerEl.offsetHeight;
392
402
  const contentRect = positionerEl.getBoundingClientRect();
393
403
  const contentBoxWidth = measuredWidth || contentRect.width;
394
- const contentBoxHeight = measuredHeight || contentRect.height;
404
+ const contentBoxHeight = Math.max(measuredHeight, contentRect.height, contentEl.scrollHeight);
395
405
  const next = computePopoverPosition({
396
406
  triggerRect,
397
407
  contentSize: { width: contentBoxWidth, height: contentBoxHeight },
@@ -399,20 +409,31 @@ var Popover = ({
399
409
  offset,
400
410
  padding,
401
411
  viewport: {
402
- width: portalWindow?.innerWidth ?? window.innerWidth,
403
- height: portalWindow?.innerHeight ?? window.innerHeight
404
- }
412
+ width: portalWindow.innerWidth,
413
+ height: portalWindow.innerHeight
414
+ },
415
+ constrainToAvailableHeight
405
416
  });
406
417
  const top = Math.round(next.top);
407
418
  const left = Math.round(next.left);
408
- const applied = prevApplied && Math.abs(prevApplied.top - top) < 0.5 && Math.abs(prevApplied.left - left) < 0.5 && prevApplied.side === next.side && prevApplied.align === next.align && prevApplied.width === widthPx;
419
+ const applied = prevApplied && Math.abs(prevApplied.top - top) < 0.5 && Math.abs(prevApplied.left - left) < 0.5 && prevApplied.side === next.side && prevApplied.align === next.align && prevApplied.width === widthPx && prevApplied.availableHeight === next.availableHeight;
409
420
  if (applied) return;
410
- lastAppliedRef.current = { top, left, side: next.side, align: next.align, width: widthPx };
421
+ lastAppliedRef.current = {
422
+ top,
423
+ left,
424
+ side: next.side,
425
+ align: next.align,
426
+ width: widthPx,
427
+ availableHeight: next.availableHeight
428
+ };
411
429
  positionerEl.style.transform = `translate3d(${left}px, ${top}px, 0)`;
430
+ positionerEl.style.setProperty("--underverse-popover-available-height", `${next.availableHeight}px`);
431
+ positionerEl.dataset.side = next.side;
432
+ positionerEl.dataset.align = next.align;
412
433
  panelEl.style.transformOrigin = getTransformOrigin(next.side, next.align);
413
434
  if (positionerEl.style.visibility !== "visible") positionerEl.style.visibility = "visible";
414
435
  if (positionerEl.style.pointerEvents !== "auto") positionerEl.style.pointerEvents = "auto";
415
- }, [placement, matchTriggerWidth, contentWidth, portalWindow]);
436
+ }, [placement, matchTriggerWidth, contentWidth, portalWindow, constrainToAvailableHeight]);
416
437
  React2.useLayoutEffect(() => {
417
438
  if (!isOpen || !portalWindow) return;
418
439
  updatePosition();
@@ -561,7 +582,6 @@ var Popover = ({
561
582
  ref: mergeRefs(childRef, (node) => {
562
583
  triggerRef.current = node;
563
584
  }),
564
- "data-underverse-popover-trigger": triggerSelector,
565
585
  onClick: chainEventHandlers(
566
586
  (e) => {
567
587
  triggerRef.current = e.currentTarget;
@@ -1891,7 +1911,7 @@ var ClipboardImages = Extension.create({
1891
1911
  });
1892
1912
 
1893
1913
  // src/components/UEditor/inputs.tsx
1894
- import { useEffect as useEffect3, useId as useId2, useRef as useRef2, useState as useState3 } from "react";
1914
+ import { useEffect as useEffect3, useId, useRef as useRef2, useState as useState3 } from "react";
1895
1915
  import { Check, X } from "lucide-react";
1896
1916
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1897
1917
  function normalizeUrl(raw) {
@@ -1906,7 +1926,7 @@ var LinkInput = ({
1906
1926
  const [url, setUrl] = useState3(initialUrl);
1907
1927
  const [error, setError] = useState3("");
1908
1928
  const inputRef = useRef2(null);
1909
- const errorId = useId2();
1929
+ const errorId = useId();
1910
1930
  useEffect3(() => {
1911
1931
  inputRef.current?.focus();
1912
1932
  inputRef.current?.select();
@@ -4658,4 +4678,4 @@ export {
4658
4678
  EditorToolbar,
4659
4679
  UEDITOR_PROSEMIRROR_CLASS_NAME
4660
4680
  };
4661
- //# sourceMappingURL=chunk-23VKHYEB.js.map
4681
+ //# sourceMappingURL=chunk-RSLY7UU2.js.map