@lobehub/ui 5.27.0 → 5.28.1

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 (65) hide show
  1. package/README.md +6 -6
  2. package/es/Image/Image.mjs +3 -2
  3. package/es/Image/Image.mjs.map +1 -1
  4. package/es/Image/style.mjs +19 -13
  5. package/es/Image/style.mjs.map +1 -1
  6. package/es/Image/type.d.mts +3 -0
  7. package/es/Image/viewer/ActualSizeIcon.mjs +44 -0
  8. package/es/Image/viewer/ActualSizeIcon.mjs.map +1 -0
  9. package/es/Image/viewer/ImageViewer.mjs +12 -3
  10. package/es/Image/viewer/ImageViewer.mjs.map +1 -1
  11. package/es/Image/viewer/Toolbar.mjs +17 -13
  12. package/es/Image/viewer/Toolbar.mjs.map +1 -1
  13. package/es/Image/viewer/ViewerChrome.mjs.map +1 -1
  14. package/es/Image/viewer/geometry.d.mts +5 -0
  15. package/es/Image/viewer/geometry.mjs +13 -1
  16. package/es/Image/viewer/geometry.mjs.map +1 -1
  17. package/es/Image/viewer/registry.mjs.map +1 -1
  18. package/es/Image/viewer/useFlipTransition.mjs +7 -4
  19. package/es/Image/viewer/useFlipTransition.mjs.map +1 -1
  20. package/es/Image/viewer/useGalleryNav.mjs +6 -5
  21. package/es/Image/viewer/useGalleryNav.mjs.map +1 -1
  22. package/es/Image/viewer/useViewerGestures.mjs +2 -6
  23. package/es/Image/viewer/useViewerGestures.mjs.map +1 -1
  24. package/es/Image/viewer/useZoomPan.mjs +80 -23
  25. package/es/Image/viewer/useZoomPan.mjs.map +1 -1
  26. package/es/Markdown/SyntaxMarkdown/CachedMarkdown.mjs +1 -1
  27. package/es/Markdown/plugins/rehypeCustomFootnotes.mjs +1 -1
  28. package/es/Markdown/plugins/rehypeKatexDir.d.mts +1 -1
  29. package/es/Markdown/plugins/rehypeKatexDir.mjs +1 -1
  30. package/es/Markdown/plugins/rehypeStreamAnimated.d.mts +1 -1
  31. package/es/Markdown/plugins/rehypeStreamAnimated.mjs +1 -1
  32. package/es/Markdown/plugins/remarkBr.mjs +1 -1
  33. package/es/Markdown/plugins/remarkColor.mjs +1 -1
  34. package/es/Markdown/plugins/remarkCustomFootnotes.mjs +2 -2
  35. package/es/Markdown/plugins/remarkGfmPlus.mjs +1 -1
  36. package/es/Markdown/plugins/remarkVideo.mjs +1 -1
  37. package/es/base-ui/Drawer/style.mjs +43 -21
  38. package/es/base-ui/Drawer/style.mjs.map +1 -1
  39. package/es/eslint/index.mjs +1 -0
  40. package/es/eslint/index.mjs.map +1 -1
  41. package/es/i18n/resources/en/image.d.mts +2 -1
  42. package/es/i18n/resources/en/image.mjs +3 -2
  43. package/es/i18n/resources/en/image.mjs.map +1 -1
  44. package/es/i18n/resources/zhCn/image.d.mts +2 -1
  45. package/es/i18n/resources/zhCn/image.mjs +3 -2
  46. package/es/i18n/resources/zhCn/image.mjs.map +1 -1
  47. package/es/index.d.mts +2 -2
  48. package/es/mdx/mdxComponents/index.d.mts +1 -1
  49. package/es/node_modules/{.bun → .pnpm}/@types_hast@3.0.5/node_modules/@types/hast/index.d.mts +1 -1
  50. package/es/node_modules/{.bun → .pnpm}/@types_mdx@2.0.14/node_modules/@types/mdx/types.d.mts +1 -1
  51. package/es/node_modules/{.bun → .pnpm}/@types_unist@3.0.3/node_modules/@types/unist/index.d.mts +1 -1
  52. package/es/node_modules/{.bun → .pnpm}/unist-util-is@6.0.1/node_modules/unist-util-is/lib/index.mjs +1 -1
  53. package/es/node_modules/.pnpm/unist-util-is@6.0.1/node_modules/unist-util-is/lib/index.mjs.map +1 -0
  54. package/es/node_modules/.pnpm/unist-util-visit-parents@6.0.2/node_modules/unist-util-visit-parents/lib/color.node.mjs +12 -0
  55. package/es/node_modules/.pnpm/unist-util-visit-parents@6.0.2/node_modules/unist-util-visit-parents/lib/color.node.mjs.map +1 -0
  56. package/es/node_modules/{.bun → .pnpm}/unist-util-visit-parents@6.0.2/node_modules/unist-util-visit-parents/lib/index.mjs +1 -1
  57. package/es/node_modules/.pnpm/unist-util-visit-parents@6.0.2/node_modules/unist-util-visit-parents/lib/index.mjs.map +1 -0
  58. package/es/node_modules/{.bun → .pnpm}/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs +1 -1
  59. package/es/node_modules/.pnpm/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs.map +1 -0
  60. package/package.json +4 -5
  61. package/es/node_modules/.bun/unist-util-is@6.0.1/node_modules/unist-util-is/lib/index.mjs.map +0 -1
  62. package/es/node_modules/.bun/unist-util-visit-parents@6.0.2/node_modules/unist-util-visit-parents/lib/color.node.mjs +0 -12
  63. package/es/node_modules/.bun/unist-util-visit-parents@6.0.2/node_modules/unist-util-visit-parents/lib/color.node.mjs.map +0 -1
  64. package/es/node_modules/.bun/unist-util-visit-parents@6.0.2/node_modules/unist-util-visit-parents/lib/index.mjs.map +0 -1
  65. package/es/node_modules/.bun/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useZoomPan.mjs","names":[],"sources":["../../../src/Image/viewer/useZoomPan.ts"],"sourcesContent":["import type { MotionValue } from 'motion/react';\nimport { animate, motionValue } from 'motion/react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport type { Point, Rect, Rotation, Size, TransformState } from './geometry';\nimport {\n anchoredZoom,\n clampPan,\n clampScale,\n computeFit,\n DEFAULT_MAX_SCALE,\n doubleClickTarget,\n normalizeRotation,\n panBounds,\n rubberBand,\n wheelZoomFactor,\n} from './geometry';\n\nconst WHEEL_CLOSE_THRESHOLD = 100;\nconst WHEEL_IDLE_MS = 300;\nconst ZOOM_STEP = 1.5;\nconst RESET_TRANSITION = { damping: 30, stiffness: 300, type: 'spring' as const };\nconst CLEAN_EPSILON = 0.01;\n\nexport interface WheelLikeEvent {\n clientX: number;\n clientY: number;\n ctrlKey?: boolean;\n deltaY: number;\n metaKey?: boolean;\n preventDefault?: () => void;\n}\n\nexport interface UseZoomPanOptions {\n fillViewport?: boolean;\n isClosing?: () => boolean;\n maxScale?: number;\n natural: Size;\n onCloseRequest?: () => void;\n viewport: Size;\n}\n\nexport interface UseZoomPanResult {\n canZoomIn: boolean;\n canZoomOut: boolean;\n dragBy: (delta: Point) => void;\n dragEnd: () => void;\n escIntent: () => 'reset' | 'close';\n flipHorizontal: () => void;\n flipVertical: () => void;\n flipX: MotionValue<boolean>;\n flipY: MotionValue<boolean>;\n handleDoubleClick: (point: Point) => void;\n handleWheel: (event: WheelLikeEvent) => void;\n isClean: boolean;\n isZoomed: boolean;\n reset: () => void;\n resetCloseTracking: () => void;\n rotate: MotionValue<number>;\n rotateLeft: () => void;\n rotateRight: () => void;\n rotation: Rotation;\n scale: MotionValue<number>;\n setNatural: (natural: Size) => void;\n setViewport: (viewport: Size) => void;\n x: MotionValue<number>;\n y: MotionValue<number>;\n zoomIn: () => void;\n zoomOut: () => void;\n}\n\ninterface DerivedState {\n canZoomIn: boolean;\n canZoomOut: boolean;\n isClean: boolean;\n isZoomed: boolean;\n rotation: Rotation;\n}\n\nexport const useZoomPan = ({\n natural,\n viewport,\n maxScale,\n onCloseRequest,\n isClosing,\n fillViewport,\n}: UseZoomPanOptions): UseZoomPanResult => {\n const [{ scale, x, y, rotate, flipX, flipY }] = useState(() => ({\n flipX: motionValue(false),\n flipY: motionValue(false),\n rotate: motionValue(0),\n scale: motionValue(1),\n x: motionValue(0),\n y: motionValue(0),\n }));\n\n const naturalRef = useRef(natural);\n const viewportRef = useRef(viewport);\n const maxScaleRef = useRef(maxScale ?? DEFAULT_MAX_SCALE);\n maxScaleRef.current = maxScale ?? DEFAULT_MAX_SCALE;\n const fillViewportRef = useRef(fillViewport ?? false);\n fillViewportRef.current = fillViewport ?? false;\n\n const onCloseRequestRef = useRef(onCloseRequest);\n onCloseRequestRef.current = onCloseRequest;\n\n const isClosingRef = useRef(isClosing);\n isClosingRef.current = isClosing;\n\n const closeAccumRef = useRef(0);\n const disarmedRef = useRef(false);\n const idleTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const resetCloseTracking = useCallback(() => {\n if (idleTimerRef.current !== null) {\n clearTimeout(idleTimerRef.current);\n idleTimerRef.current = null;\n }\n closeAccumRef.current = 0;\n disarmedRef.current = false;\n }, []);\n\n // The close FLIP spring animates these same scale/x/y values. Any of\n // these entry points still firing during the ~300ms close window would\n // either fight that spring visually or, for wheel/reset specifically,\n // race escIntent()/isCleanState() into cancelling the close outright.\n const closing = useCallback(() => isClosingRef.current?.() ?? false, []);\n\n const isCleanState = useCallback(\n () =>\n Math.abs(scale.get() - 1) < CLEAN_EPSILON &&\n Math.abs(rotate.get()) < CLEAN_EPSILON &&\n !flipX.get() &&\n !flipY.get(),\n [flipX, flipY, rotate, scale],\n );\n\n const computeDerived = useCallback((): DerivedState => {\n const currentScale = scale.get();\n return {\n canZoomIn: currentScale < maxScaleRef.current,\n canZoomOut: currentScale > 1,\n isClean: isCleanState(),\n isZoomed: currentScale > 1,\n rotation: normalizeRotation(rotate.get()),\n };\n }, [isCleanState, rotate, scale]);\n\n const [derived, setDerived] = useState<DerivedState>(computeDerived);\n\n const syncDerived = useCallback(() => {\n setDerived((prev) => {\n const next = computeDerived();\n if (\n prev.canZoomIn === next.canZoomIn &&\n prev.canZoomOut === next.canZoomOut &&\n prev.isClean === next.isClean &&\n prev.isZoomed === next.isZoomed &&\n prev.rotation === next.rotation\n ) {\n return prev;\n }\n return next;\n });\n }, [computeDerived]);\n\n useEffect(() => {\n const unsubscribers = [scale, rotate, flipX, flipY].map((value) =>\n value.on('change', syncDerived),\n );\n syncDerived();\n return () => {\n for (const unsubscribe of unsubscribers) unsubscribe();\n };\n }, [flipX, flipY, rotate, scale, syncDerived]);\n\n const getFitRect = useCallback(\n () =>\n computeFit(\n naturalRef.current,\n viewportRef.current,\n normalizeRotation(rotate.get()),\n fillViewportRef.current,\n ),\n [rotate],\n );\n\n const applyTransform = useCallback(\n (next: TransformState, fitRect: Rect) => {\n const clamped = clampPan(next, fitRect, viewportRef.current);\n // .jump(), not .set(): a surviving spring on these same values (e.g. a\n // dragEnd clamp-back or wheel snap-back still in flight) would otherwise\n // keep animating toward its own target and silently overwrite this\n // instant write on its next tick — motion's set() never stops an\n // active animation, only jump() does.\n scale.jump(next.scale);\n x.jump(clamped.x);\n y.jump(clamped.y);\n },\n [scale, x, y],\n );\n\n // Wheel/pinch stays on the instant applyTransform for 1:1 gesture tracking;\n // stepped inputs (toolbar/keyboard zoom, double-click) animate instead.\n const animateTransform = useCallback(\n (next: TransformState, fitRect: Rect) => {\n const clamped = clampPan(next, fitRect, viewportRef.current);\n animate(scale, next.scale, RESET_TRANSITION);\n animate(x, clamped.x, RESET_TRANSITION);\n animate(y, clamped.y, RESET_TRANSITION);\n },\n [scale, x, y],\n );\n\n const zoomBy = useCallback(\n (factor: number) => {\n if (closing()) return;\n const currentScale = scale.get();\n const targetScale = clampScale(currentScale * factor, maxScaleRef.current);\n const fitRect = getFitRect();\n const anchor: Point = { x: viewportRef.current.width / 2, y: viewportRef.current.height / 2 };\n const next = anchoredZoom(\n { scale: currentScale, x: x.get(), y: y.get() },\n targetScale,\n anchor,\n fitRect,\n );\n animateTransform(next, fitRect);\n },\n [animateTransform, closing, getFitRect, scale, x, y],\n );\n\n const zoomIn = useCallback(() => zoomBy(ZOOM_STEP), [zoomBy]);\n const zoomOut = useCallback(() => zoomBy(1 / ZOOM_STEP), [zoomBy]);\n\n const handleDoubleClick = useCallback(\n (point: Point) => {\n if (closing()) return;\n const currentScale = scale.get();\n const fitRect = getFitRect();\n const target = doubleClickTarget(\n currentScale,\n naturalRef.current,\n fitRect,\n normalizeRotation(rotate.get()),\n );\n const targetScale = clampScale(target, maxScaleRef.current);\n const next = anchoredZoom(\n { scale: currentScale, x: x.get(), y: y.get() },\n targetScale,\n point,\n fitRect,\n );\n animateTransform(next, fitRect);\n },\n [animateTransform, closing, getFitRect, rotate, scale, x, y],\n );\n\n const handleWheel = useCallback(\n (event: WheelLikeEvent) => {\n event.preventDefault?.();\n if (closing()) return;\n\n if (idleTimerRef.current !== null) clearTimeout(idleTimerRef.current);\n idleTimerRef.current = setTimeout(() => {\n idleTimerRef.current = null;\n closeAccumRef.current = 0;\n disarmedRef.current = false;\n }, WHEEL_IDLE_MS);\n\n const currentScale = scale.get();\n const isPinch = !!(event.ctrlKey || event.metaKey);\n const zoomed = currentScale > 1;\n\n if (isPinch || zoomed) {\n disarmedRef.current = true;\n closeAccumRef.current = 0;\n\n const rawTarget = currentScale * wheelZoomFactor(event.deltaY);\n\n if (rawTarget <= 1) {\n animate(scale, 1, RESET_TRANSITION);\n animate(x, 0, RESET_TRANSITION);\n animate(y, 0, RESET_TRANSITION);\n return;\n }\n\n const targetScale = clampScale(rawTarget, maxScaleRef.current);\n const fitRect = getFitRect();\n const anchor: Point = { x: event.clientX, y: event.clientY };\n const next = anchoredZoom(\n { scale: currentScale, x: x.get(), y: y.get() },\n targetScale,\n anchor,\n fitRect,\n );\n applyTransform(next, fitRect);\n return;\n }\n\n if (disarmedRef.current || !isCleanState()) return;\n\n closeAccumRef.current += Math.abs(event.deltaY);\n if (closeAccumRef.current >= WHEEL_CLOSE_THRESHOLD) {\n closeAccumRef.current = 0;\n onCloseRequestRef.current?.();\n }\n },\n [applyTransform, closing, getFitRect, isCleanState, scale, x, y],\n );\n\n const rotateBy = useCallback(\n (delta: 90 | -90) => {\n if (closing()) return;\n rotate.jump(normalizeRotation(rotate.get() + delta));\n scale.jump(1);\n x.jump(0);\n y.jump(0);\n },\n [closing, rotate, scale, x, y],\n );\n\n const rotateLeft = useCallback(() => rotateBy(-90), [rotateBy]);\n const rotateRight = useCallback(() => rotateBy(90), [rotateBy]);\n\n const flipHorizontal = useCallback(() => {\n if (closing()) return;\n flipX.set(!flipX.get());\n }, [closing, flipX]);\n\n const flipVertical = useCallback(() => {\n if (closing()) return;\n flipY.set(!flipY.get());\n }, [closing, flipY]);\n\n const reset = useCallback(() => {\n if (closing()) return;\n animate(scale, 1, RESET_TRANSITION);\n animate(x, 0, RESET_TRANSITION);\n animate(y, 0, RESET_TRANSITION);\n animate(rotate, 0, RESET_TRANSITION);\n flipX.set(false);\n flipY.set(false);\n }, [closing, flipX, flipY, rotate, scale, x, y]);\n\n const dragBy = useCallback(\n (delta: Point) => {\n // A pointer can still be down when close starts (e.g. pinch to just\n // over 1x — inside isClean's epsilon, so Esc/wheel reads 'close' —\n // while the same gesture is still panning). Gated for consistency\n // with the other entry points even though .set() here can't cancel\n // the close spring outright, only cause a self-correcting flicker.\n if (closing()) return;\n const fitRect = getFitRect();\n const bounds = panBounds({ scale: scale.get(), x: 0, y: 0 }, fitRect, viewportRef.current);\n x.set(rubberBand(x.get() + delta.x, bounds.x.min, bounds.x.max));\n y.set(rubberBand(y.get() + delta.y, bounds.y.min, bounds.y.max));\n },\n [closing, getFitRect, scale, x, y],\n );\n\n const dragEnd = useCallback(() => {\n if (closing()) return;\n const fitRect = getFitRect();\n const clamped = clampPan(\n { scale: scale.get(), x: x.get(), y: y.get() },\n fitRect,\n viewportRef.current,\n );\n animate(x, clamped.x, RESET_TRANSITION);\n animate(y, clamped.y, RESET_TRANSITION);\n }, [closing, getFitRect, scale, x, y]);\n\n const escIntent = useCallback(\n (): 'reset' | 'close' => (isCleanState() ? 'close' : 'reset'),\n [isCleanState],\n );\n\n const setViewport = useCallback(\n (next: Size) => {\n viewportRef.current = next;\n const fitRect = computeFit(\n naturalRef.current,\n next,\n normalizeRotation(rotate.get()),\n fillViewportRef.current,\n );\n const clamped = clampPan({ scale: scale.get(), x: x.get(), y: y.get() }, fitRect, next);\n x.set(clamped.x);\n y.set(clamped.y);\n },\n [rotate, scale, x, y],\n );\n\n const setNatural = useCallback(\n (next: Size) => {\n naturalRef.current = next;\n const fitRect = computeFit(\n next,\n viewportRef.current,\n normalizeRotation(rotate.get()),\n fillViewportRef.current,\n );\n const clamped = clampPan(\n { scale: scale.get(), x: x.get(), y: y.get() },\n fitRect,\n viewportRef.current,\n );\n x.set(clamped.x);\n y.set(clamped.y);\n },\n [rotate, scale, x, y],\n );\n\n return {\n canZoomIn: derived.canZoomIn,\n canZoomOut: derived.canZoomOut,\n dragBy,\n dragEnd,\n escIntent,\n flipHorizontal,\n flipVertical,\n flipX,\n flipY,\n handleDoubleClick,\n handleWheel,\n isClean: derived.isClean,\n isZoomed: derived.isZoomed,\n reset,\n resetCloseTracking,\n rotate,\n rotateLeft,\n rotateRight,\n rotation: derived.rotation,\n scale,\n setNatural,\n setViewport,\n x,\n y,\n zoomIn,\n zoomOut,\n };\n};\n\nexport type { Point, Rotation, Size } from './geometry';\n"],"mappings":"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"}
1
+ {"version":3,"file":"useZoomPan.mjs","names":[],"sources":["../../../src/Image/viewer/useZoomPan.ts"],"sourcesContent":["import type { MotionValue } from 'motion/react';\nimport { animate, motionValue } from 'motion/react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport type { Point, Rect, Rotation, Size, TransformState, ZoomPolicy } from './geometry';\nimport {\n anchoredZoom,\n clampPan,\n clampScale,\n computeFit,\n DEFAULT_AUTO_ZOOM_THRESHOLD,\n DEFAULT_MAX_SCALE,\n doubleClickTarget,\n MIN_SCALE,\n naturalScale,\n normalizeRotation,\n normalizeWheelDelta,\n panBounds,\n resolveInitialScale,\n rubberBand,\n wheelZoomFactor,\n} from './geometry';\n\nconst WHEEL_CLOSE_THRESHOLD = 100;\nconst WHEEL_IDLE_MS = 300;\nconst ZOOM_STEP = 1.5;\nconst RESET_TRANSITION = { damping: 30, stiffness: 300, type: 'spring' as const };\nconst CLEAN_EPSILON = 0.01;\n\nexport interface WheelLikeEvent {\n clientX: number;\n clientY: number;\n ctrlKey?: boolean;\n deltaMode?: number;\n deltaY: number;\n metaKey?: boolean;\n preventDefault?: () => void;\n}\n\nexport interface UseZoomPanOptions {\n autoZoomThreshold?: number;\n defaultZoom?: ZoomPolicy;\n fillViewport?: boolean;\n isClosing?: () => boolean;\n isTransitioning?: () => boolean;\n maxScale?: number;\n natural: Size;\n onCloseRequest?: () => void;\n viewport: Size;\n}\n\nexport interface UseZoomPanResult {\n canZoomIn: boolean;\n canZoomOut: boolean;\n dragBy: (delta: Point) => void;\n dragEnd: () => void;\n escIntent: () => 'reset' | 'close';\n flipHorizontal: () => void;\n flipVertical: () => void;\n flipX: MotionValue<boolean>;\n flipY: MotionValue<boolean>;\n getInitialScale: () => number;\n handleDoubleClick: (point: Point) => void;\n handleWheel: (event: WheelLikeEvent) => void;\n isClean: boolean;\n isZoomed: boolean;\n reset: () => void;\n resetCloseTracking: () => void;\n rotate: MotionValue<number>;\n rotateLeft: () => void;\n rotateRight: () => void;\n rotation: Rotation;\n scale: MotionValue<number>;\n setNatural: (natural: Size) => void;\n setViewport: (viewport: Size) => void;\n toggleActualSize: () => void;\n x: MotionValue<number>;\n y: MotionValue<number>;\n zoomIn: () => void;\n zoomOut: () => void;\n}\n\ninterface DerivedState {\n canZoomIn: boolean;\n canZoomOut: boolean;\n isClean: boolean;\n isZoomed: boolean;\n rotation: Rotation;\n}\n\nexport const useZoomPan = ({\n natural,\n viewport,\n maxScale,\n onCloseRequest,\n isClosing,\n isTransitioning,\n fillViewport,\n defaultZoom,\n autoZoomThreshold,\n}: UseZoomPanOptions): UseZoomPanResult => {\n const naturalRef = useRef(natural);\n const viewportRef = useRef(viewport);\n const maxScaleRef = useRef(maxScale ?? DEFAULT_MAX_SCALE);\n maxScaleRef.current = maxScale ?? DEFAULT_MAX_SCALE;\n const fillViewportRef = useRef(fillViewport ?? false);\n fillViewportRef.current = fillViewport ?? false;\n const policyRef = useRef(defaultZoom ?? 'auto');\n policyRef.current = defaultZoom ?? 'auto';\n const thresholdRef = useRef(autoZoomThreshold ?? DEFAULT_AUTO_ZOOM_THRESHOLD);\n thresholdRef.current = autoZoomThreshold ?? DEFAULT_AUTO_ZOOM_THRESHOLD;\n\n const computeInitialScale = useCallback((rotation: Rotation = 0) => {\n const fitRect = computeFit(\n naturalRef.current,\n viewportRef.current,\n rotation,\n fillViewportRef.current,\n );\n return resolveInitialScale(\n policyRef.current,\n naturalRef.current,\n fitRect,\n rotation,\n thresholdRef.current,\n );\n }, []);\n\n const [initialScaleSeed] = useState(computeInitialScale);\n const initialScaleRef = useRef(initialScaleSeed);\n const getInitialScale = useCallback(() => initialScaleRef.current, []);\n\n const [{ scale, x, y, rotate, flipX, flipY }] = useState(() => ({\n flipX: motionValue(false),\n flipY: motionValue(false),\n rotate: motionValue(0),\n scale: motionValue(initialScaleRef.current),\n x: motionValue(0),\n y: motionValue(0),\n }));\n\n // The ceiling has to clear the opening scale, otherwise a very large image\n // (naturalScale > maxScale) is clamped below the 100% it was asked to open at.\n const effectiveMaxScale = useCallback(\n () => Math.max(maxScaleRef.current, initialScaleRef.current),\n [],\n );\n\n const onCloseRequestRef = useRef(onCloseRequest);\n onCloseRequestRef.current = onCloseRequest;\n\n const isClosingRef = useRef(isClosing);\n isClosingRef.current = isClosing;\n\n const isTransitioningRef = useRef(isTransitioning);\n isTransitioningRef.current = isTransitioning;\n\n const closeAccumRef = useRef(0);\n const disarmedRef = useRef(false);\n const idleTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const resetCloseTracking = useCallback(() => {\n if (idleTimerRef.current !== null) {\n clearTimeout(idleTimerRef.current);\n idleTimerRef.current = null;\n }\n closeAccumRef.current = 0;\n disarmedRef.current = false;\n }, []);\n\n // The close FLIP spring animates these same scale/x/y values. Any of\n // these entry points still firing during the ~300ms close window would\n // either fight that spring visually or, for wheel/reset specifically,\n // race escIntent()/isCleanState() into cancelling the close outright.\n const closing = useCallback(() => isClosingRef.current?.() ?? false, []);\n\n // Three questions that used to share one answer, and stop sharing it the\n // moment the viewer can open at something other than fit:\n // isAtFitFloor — no zoom-out left, so a further scroll down has\n // nowhere to go and becomes the dismiss gesture.\n // isOrientationClean — no rotation/flip to lose, so dismissing is safe.\n // Guards the wheel the same way layered Esc does:\n // state the user built is never thrown away by a\n // gesture that merely ran out of room.\n // isCleanState — both of the above *and* untouched zoom, i.e. \"the\n // user hasn't changed anything at all\", which is what\n // lets Esc/click close outright and lets the close\n // animation FLIP back to the thumbnail instead of fade.\n // All three coincide only while initialScale === MIN_SCALE.\n const isAtFitFloor = useCallback(() => scale.get() <= MIN_SCALE + CLEAN_EPSILON, [scale]);\n\n const isOrientationClean = useCallback(\n () => Math.abs(rotate.get()) < CLEAN_EPSILON && !flipX.get() && !flipY.get(),\n [flipX, flipY, rotate],\n );\n\n const isCleanState = useCallback(\n () => Math.abs(scale.get() - initialScaleRef.current) < CLEAN_EPSILON && isOrientationClean(),\n [isOrientationClean, scale],\n );\n\n const computeDerived = useCallback((): DerivedState => {\n const currentScale = scale.get();\n return {\n canZoomIn: currentScale < effectiveMaxScale(),\n canZoomOut: currentScale > MIN_SCALE,\n isClean: isCleanState(),\n isZoomed: currentScale > MIN_SCALE,\n rotation: normalizeRotation(rotate.get()),\n };\n }, [effectiveMaxScale, isCleanState, rotate, scale]);\n\n const [derived, setDerived] = useState<DerivedState>(computeDerived);\n\n const syncDerived = useCallback(() => {\n setDerived((prev) => {\n const next = computeDerived();\n if (\n prev.canZoomIn === next.canZoomIn &&\n prev.canZoomOut === next.canZoomOut &&\n prev.isClean === next.isClean &&\n prev.isZoomed === next.isZoomed &&\n prev.rotation === next.rotation\n ) {\n return prev;\n }\n return next;\n });\n }, [computeDerived]);\n\n useEffect(() => {\n const unsubscribers = [scale, rotate, flipX, flipY].map((value) =>\n value.on('change', syncDerived),\n );\n syncDerived();\n return () => {\n for (const unsubscribe of unsubscribers) unsubscribe();\n };\n }, [flipX, flipY, rotate, scale, syncDerived]);\n\n const getFitRect = useCallback(\n () =>\n computeFit(\n naturalRef.current,\n viewportRef.current,\n normalizeRotation(rotate.get()),\n fillViewportRef.current,\n ),\n [rotate],\n );\n\n const applyTransform = useCallback(\n (next: TransformState, fitRect: Rect) => {\n const clamped = clampPan(next, fitRect, viewportRef.current);\n // .jump(), not .set(): a surviving spring on these same values (e.g. a\n // dragEnd clamp-back or wheel snap-back still in flight) would otherwise\n // keep animating toward its own target and silently overwrite this\n // instant write on its next tick — motion's set() never stops an\n // active animation, only jump() does.\n scale.jump(next.scale);\n x.jump(clamped.x);\n y.jump(clamped.y);\n },\n [scale, x, y],\n );\n\n // Wheel/pinch stays on the instant applyTransform for 1:1 gesture tracking;\n // stepped inputs (toolbar/keyboard zoom, double-click) animate instead.\n const animateTransform = useCallback(\n (next: TransformState, fitRect: Rect) => {\n const clamped = clampPan(next, fitRect, viewportRef.current);\n animate(scale, next.scale, RESET_TRANSITION);\n animate(x, clamped.x, RESET_TRANSITION);\n animate(y, clamped.y, RESET_TRANSITION);\n },\n [scale, x, y],\n );\n\n const zoomBy = useCallback(\n (factor: number) => {\n if (closing()) return;\n const currentScale = scale.get();\n const targetScale = clampScale(currentScale * factor, effectiveMaxScale());\n const fitRect = getFitRect();\n const anchor: Point = { x: viewportRef.current.width / 2, y: viewportRef.current.height / 2 };\n const next = anchoredZoom(\n { scale: currentScale, x: x.get(), y: y.get() },\n targetScale,\n anchor,\n fitRect,\n );\n animateTransform(next, fitRect);\n },\n [animateTransform, closing, effectiveMaxScale, getFitRect, scale, x, y],\n );\n\n const zoomIn = useCallback(() => zoomBy(ZOOM_STEP), [zoomBy]);\n const zoomOut = useCallback(() => zoomBy(1 / ZOOM_STEP), [zoomBy]);\n\n const handleDoubleClick = useCallback(\n (point: Point) => {\n if (closing()) return;\n const currentScale = scale.get();\n const fitRect = getFitRect();\n const target = doubleClickTarget(\n currentScale,\n naturalRef.current,\n fitRect,\n normalizeRotation(rotate.get()),\n );\n const targetScale = clampScale(target, effectiveMaxScale());\n const next = anchoredZoom(\n { scale: currentScale, x: x.get(), y: y.get() },\n targetScale,\n point,\n fitRect,\n );\n animateTransform(next, fitRect);\n },\n [animateTransform, closing, effectiveMaxScale, getFitRect, rotate, scale, x, y],\n );\n\n const toggleActualSize = useCallback(() => {\n if (closing()) return;\n const currentScale = scale.get();\n const fitRect = getFitRect();\n const actual = naturalScale(naturalRef.current, fitRect, normalizeRotation(rotate.get()));\n const atActual = Math.abs(currentScale - actual) < CLEAN_EPSILON;\n const targetScale = clampScale(atActual ? MIN_SCALE : actual, effectiveMaxScale());\n const anchor: Point = { x: viewportRef.current.width / 2, y: viewportRef.current.height / 2 };\n const next = anchoredZoom(\n { scale: currentScale, x: x.get(), y: y.get() },\n targetScale,\n anchor,\n fitRect,\n );\n animateTransform(next, fitRect);\n }, [animateTransform, closing, effectiveMaxScale, getFitRect, rotate, scale, x, y]);\n\n const handleWheel = useCallback(\n (event: WheelLikeEvent) => {\n event.preventDefault?.();\n if (closing()) return;\n\n if (idleTimerRef.current !== null) clearTimeout(idleTimerRef.current);\n idleTimerRef.current = setTimeout(() => {\n idleTimerRef.current = null;\n closeAccumRef.current = 0;\n disarmedRef.current = false;\n }, WHEEL_IDLE_MS);\n\n const delta = normalizeWheelDelta(event.deltaY, event.deltaMode, viewportRef.current.height);\n\n const currentScale = scale.get();\n const isPinch = !!(event.ctrlKey || event.metaKey);\n // Zooming in is never gated on the current scale: gating it was what made\n // a plain wheel inert at the zoom floor, which reads as enormous damping.\n // Only scrolling *down* while already at the floor has nowhere left to go,\n // and that is precisely where the dismiss gesture takes over.\n const zoomingIn = delta < 0;\n\n if (isPinch || zoomingIn || !isAtFitFloor()) {\n disarmedRef.current = true;\n closeAccumRef.current = 0;\n\n const rawTarget = currentScale * wheelZoomFactor(delta);\n\n if (rawTarget <= MIN_SCALE) {\n animate(scale, MIN_SCALE, RESET_TRANSITION);\n animate(x, 0, RESET_TRANSITION);\n animate(y, 0, RESET_TRANSITION);\n return;\n }\n\n const targetScale = clampScale(rawTarget, effectiveMaxScale());\n const fitRect = getFitRect();\n const anchor: Point = { x: event.clientX, y: event.clientY };\n const next = anchoredZoom(\n { scale: currentScale, x: x.get(), y: y.get() },\n targetScale,\n anchor,\n fitRect,\n );\n applyTransform(next, fitRect);\n return;\n }\n\n // Deliberately not isCleanState(): an image that opened at 100% and was\n // scrolled back down to fit has \"changed\" by that measure, yet it is\n // exactly where the dismiss gesture belongs. Only orientation is worth\n // protecting here.\n if (disarmedRef.current || !isOrientationClean()) return;\n\n closeAccumRef.current += Math.abs(delta);\n if (closeAccumRef.current >= WHEEL_CLOSE_THRESHOLD) {\n closeAccumRef.current = 0;\n onCloseRequestRef.current?.();\n }\n },\n [\n applyTransform,\n closing,\n effectiveMaxScale,\n getFitRect,\n isAtFitFloor,\n isOrientationClean,\n scale,\n x,\n y,\n ],\n );\n\n const rotateBy = useCallback(\n (delta: 90 | -90) => {\n if (closing()) return;\n rotate.jump(normalizeRotation(rotate.get() + delta));\n scale.jump(1);\n x.jump(0);\n y.jump(0);\n },\n [closing, rotate, scale, x, y],\n );\n\n const rotateLeft = useCallback(() => rotateBy(-90), [rotateBy]);\n const rotateRight = useCallback(() => rotateBy(90), [rotateBy]);\n\n const flipHorizontal = useCallback(() => {\n if (closing()) return;\n flipX.set(!flipX.get());\n }, [closing, flipX]);\n\n const flipVertical = useCallback(() => {\n if (closing()) return;\n flipY.set(!flipY.get());\n }, [closing, flipY]);\n\n const reset = useCallback(() => {\n if (closing()) return;\n // Back to how the viewer opened, which is not necessarily fit.\n animate(scale, initialScaleRef.current, RESET_TRANSITION);\n animate(x, 0, RESET_TRANSITION);\n animate(y, 0, RESET_TRANSITION);\n animate(rotate, 0, RESET_TRANSITION);\n flipX.set(false);\n flipY.set(false);\n }, [closing, flipX, flipY, rotate, scale, x, y]);\n\n const dragBy = useCallback(\n (delta: Point) => {\n // A pointer can still be down when close starts (e.g. pinch to just\n // over 1x — inside isClean's epsilon, so Esc/wheel reads 'close' —\n // while the same gesture is still panning). Gated for consistency\n // with the other entry points even though .set() here can't cancel\n // the close spring outright, only cause a self-correcting flicker.\n if (closing()) return;\n const fitRect = getFitRect();\n const bounds = panBounds({ scale: scale.get(), x: 0, y: 0 }, fitRect, viewportRef.current);\n x.set(rubberBand(x.get() + delta.x, bounds.x.min, bounds.x.max));\n y.set(rubberBand(y.get() + delta.y, bounds.y.min, bounds.y.max));\n },\n [closing, getFitRect, scale, x, y],\n );\n\n const dragEnd = useCallback(() => {\n if (closing()) return;\n const fitRect = getFitRect();\n const clamped = clampPan(\n { scale: scale.get(), x: x.get(), y: y.get() },\n fitRect,\n viewportRef.current,\n );\n animate(x, clamped.x, RESET_TRANSITION);\n animate(y, clamped.y, RESET_TRANSITION);\n }, [closing, getFitRect, scale, x, y]);\n\n const escIntent = useCallback(\n (): 'reset' | 'close' => (isCleanState() ? 'close' : 'reset'),\n [isCleanState],\n );\n\n const setViewport = useCallback(\n (next: Size) => {\n viewportRef.current = next;\n const fitRect = computeFit(\n naturalRef.current,\n next,\n normalizeRotation(rotate.get()),\n fillViewportRef.current,\n );\n const clamped = clampPan({ scale: scale.get(), x: x.get(), y: y.get() }, fitRect, next);\n x.set(clamped.x);\n y.set(clamped.y);\n },\n [rotate, scale, x, y],\n );\n\n const setNatural = useCallback(\n (next: Size) => {\n const wasClean = isCleanState();\n naturalRef.current = next;\n const rotation = normalizeRotation(rotate.get());\n initialScaleRef.current = computeInitialScale(rotation);\n\n // A dual-source entry opens on the thumbnail's intrinsic size and only\n // learns the hi-res one here, which can move the opening scale (a 400px\n // stand-in is fit-sized; the 2000px original it becomes is not). Re-land\n // only if the user hasn't taken over — and never mid-transition, where\n // .jump() would kill the open FLIP's spring instead of joining it.\n if (wasClean && !closing() && !isTransitioningRef.current?.()) {\n scale.jump(initialScaleRef.current);\n }\n\n const fitRect = computeFit(next, viewportRef.current, rotation, fillViewportRef.current);\n const clamped = clampPan(\n { scale: scale.get(), x: x.get(), y: y.get() },\n fitRect,\n viewportRef.current,\n );\n x.set(clamped.x);\n y.set(clamped.y);\n },\n [closing, computeInitialScale, isCleanState, rotate, scale, x, y],\n );\n\n return {\n canZoomIn: derived.canZoomIn,\n canZoomOut: derived.canZoomOut,\n dragBy,\n dragEnd,\n escIntent,\n flipHorizontal,\n flipVertical,\n flipX,\n flipY,\n getInitialScale,\n handleDoubleClick,\n handleWheel,\n isClean: derived.isClean,\n isZoomed: derived.isZoomed,\n reset,\n resetCloseTracking,\n rotate,\n rotateLeft,\n rotateRight,\n rotation: derived.rotation,\n scale,\n setNatural,\n setViewport,\n toggleActualSize,\n x,\n y,\n zoomIn,\n zoomOut,\n };\n};\n\nexport type { Point, Rotation, Size, ZoomPolicy } from './geometry';\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { visit } from "../../node_modules/.bun/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
2
+ import { visit } from "../../node_modules/.pnpm/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
3
3
  import { useMemo } from "react";
4
4
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { defaultUrlTransform } from "react-markdown";
@@ -1,4 +1,4 @@
1
- import { visit } from "../../node_modules/.bun/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
1
+ import { visit } from "../../node_modules/.pnpm/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
2
2
  //#region src/Markdown/plugins/rehypeCustomFootnotes.ts
3
3
  const rehypeCustomFootnotes = () => (tree, file) => {
4
4
  const linksData = file.data.footnoteLinks || {};
@@ -1,4 +1,4 @@
1
- import { Node } from "../../node_modules/.bun/@types_unist@3.0.3/node_modules/@types/unist/index.mjs";
1
+ import { Node } from "../../node_modules/.pnpm/@types_unist@3.0.3/node_modules/@types/unist/index.mjs";
2
2
  //#region src/Markdown/plugins/rehypeKatexDir.d.ts
3
3
  declare const rehypeKatexDir: () => (tree: Node) => void;
4
4
  //#endregion
@@ -1,4 +1,4 @@
1
- import { visit } from "../../node_modules/.bun/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
1
+ import { visit } from "../../node_modules/.pnpm/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
2
2
  //#region src/Markdown/plugins/rehypeKatexDir.ts
3
3
  const rehypeKatexDir = () => (tree) => {
4
4
  visit(tree, "element", (node) => {
@@ -1,4 +1,4 @@
1
- import { Root } from "../../node_modules/.bun/@types_hast@3.0.5/node_modules/@types/hast/index.mjs";
1
+ import { Root } from "../../node_modules/.pnpm/@types_hast@3.0.5/node_modules/@types/hast/index.mjs";
2
2
  //#region src/Markdown/plugins/rehypeStreamAnimated.d.ts
3
3
  interface StreamAnimatedRuntime {
4
4
  births: number[];
@@ -1,4 +1,4 @@
1
- import { visit } from "../../node_modules/.bun/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
1
+ import { visit } from "../../node_modules/.pnpm/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
2
2
  import { getNow } from "../../utils/getNow.mjs";
3
3
  //#region src/Markdown/plugins/rehypeStreamAnimated.ts
4
4
  const WORD_SEGMENT_RE = /\s+|\S+/g;
@@ -1,4 +1,4 @@
1
- import { visit } from "../../node_modules/.bun/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
1
+ import { visit } from "../../node_modules/.pnpm/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
2
2
  //#region src/Markdown/plugins/remarkBr.ts
3
3
  /**
4
4
  * Remark plugin to handle <br> and <br/> tags in markdown text
@@ -1,4 +1,4 @@
1
- import { visit } from "../../node_modules/.bun/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
1
+ import { visit } from "../../node_modules/.pnpm/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
2
2
  //#region src/Markdown/plugins/remarkColor.ts
3
3
  /**
4
4
  * Remark plugin to handle color syntax in markdown code spans
@@ -1,5 +1,5 @@
1
- import { SKIP } from "../../node_modules/.bun/unist-util-visit-parents@6.0.2/node_modules/unist-util-visit-parents/lib/index.mjs";
2
- import { visit } from "../../node_modules/.bun/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
1
+ import { SKIP } from "../../node_modules/.pnpm/unist-util-visit-parents@6.0.2/node_modules/unist-util-visit-parents/lib/index.mjs";
2
+ import { visit } from "../../node_modules/.pnpm/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
3
3
  //#region src/Markdown/plugins/remarkCustomFootnotes.ts
4
4
  const remarkCustomFootnotes = () => (tree, file) => {
5
5
  const footnoteLinks = /* @__PURE__ */ new Map();
@@ -1,4 +1,4 @@
1
- import { visit } from "../../node_modules/.bun/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
1
+ import { visit } from "../../node_modules/.pnpm/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
2
2
  //#region src/Markdown/plugins/remarkGfmPlus.ts
3
3
  const DEFAULT_ALLOW_HTML_TAGS = [
4
4
  "sub",
@@ -1,4 +1,4 @@
1
- import { visit } from "../../node_modules/.bun/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
1
+ import { visit } from "../../node_modules/.pnpm/unist-util-visit@5.1.0/node_modules/unist-util-visit/lib/index.mjs";
2
2
  //#region src/Markdown/plugins/remarkVideo.ts
3
3
  /**
4
4
  * Remark plugin to handle <video> tags in markdown text
@@ -61,24 +61,44 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
61
61
  min-width: 0;
62
62
  min-height: 0;
63
63
 
64
- /* Elevated, not container: in dark themes container sits within 2 points of the page
65
- background, so a panel with no border and a black-on-black cast loses its edge entirely. */
66
- background: ${cssVar.colorBgElevated};
67
-
68
- /* An edge-anchored panel casts along its placement axis, not downward like a centred
69
- dialog would. Direction classes set the sign, weight classes set the opacity, so the
70
- two compose without a class per combination. */
64
+ /* Container, not elevated: the antd-based Drawer paints its panel on container, and in dark
65
+ themes elevated is a visibly lighter step the two drawers must read as the same surface. */
66
+ background: ${cssVar.colorBgContainer};
67
+
68
+ /* Geometry and alphas are antd's boxShadowDrawer{Left,Right,Up,Down} verbatim, so both drawers
69
+ cast identically. antd builds those by scaling colorShadow's *own* alpha by 8/12/5%, and
70
+ colorShadow flips from opaque black to rgba(255,255,255,0.2) in dark — hence the color-mix
71
+ against the raw var rather than a literal black (colorShadow has no AliasToken typing, so
72
+ cssVar cannot reach it). An edge-anchored panel casts along its placement axis rather than
73
+ downward like a centred dialog would: direction classes set the sign, weight classes scale
74
+ the alpha, so the two compose without a class per combination. */
71
75
  box-shadow:
72
- calc(var(--drawer-cast-x, 0) * 6px) calc(var(--drawer-cast-y, 0) * 6px) 24px 0
73
- rgb(0 0 0 / var(--drawer-cast-far, 8%)),
74
- calc(var(--drawer-cast-x, 0) * 2px) calc(var(--drawer-cast-y, 0) * 2px) 6px 0
75
- rgb(0 0 0 / var(--drawer-cast-near, 4%));
76
+ calc(var(--drawer-cast-x, 0) * 6px) calc(var(--drawer-cast-y, 0) * 6px) 16px 0
77
+ color-mix(
78
+ in srgb,
79
+ var(--ant-color-shadow, #000) calc(8% * var(--drawer-cast-alpha, 1)),
80
+ transparent
81
+ ),
82
+ calc(var(--drawer-cast-x, 0) * 3px) calc(var(--drawer-cast-y, 0) * 3px) 6px -4px
83
+ color-mix(
84
+ in srgb,
85
+ var(--ant-color-shadow, #000) calc(12% * var(--drawer-cast-alpha, 1)),
86
+ transparent
87
+ ),
88
+ calc(var(--drawer-cast-x, 0) * 9px) calc(var(--drawer-cast-y, 0) * 9px) 28px 8px
89
+ color-mix(
90
+ in srgb,
91
+ var(--ant-color-shadow, #000) calc(5% * var(--drawer-cast-alpha, 1)),
92
+ transparent
93
+ );
76
94
 
77
95
  transition: transform 300ms cubic-bezier(0.32, 0.72, 0, 1);
78
96
  `,
79
97
  panelLeft: css`
80
98
  --drawer-cast-x: 1;
81
99
 
100
+ border-inline-end: var(--drawer-edge-width, 1px) solid ${cssVar.colorBorder};
101
+
82
102
  &[data-starting-style],
83
103
  &[data-ending-style] {
84
104
  transform: translateX(-100%);
@@ -87,6 +107,8 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
87
107
  panelRight: css`
88
108
  --drawer-cast-x: -1;
89
109
 
110
+ border-inline-start: var(--drawer-edge-width, 1px) solid ${cssVar.colorBorder};
111
+
90
112
  &[data-starting-style],
91
113
  &[data-ending-style] {
92
114
  transform: translateX(100%);
@@ -95,6 +117,8 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
95
117
  panelTop: css`
96
118
  --drawer-cast-y: 1;
97
119
 
120
+ border-block-end: var(--drawer-edge-width, 1px) solid ${cssVar.colorBorder};
121
+
98
122
  &[data-starting-style],
99
123
  &[data-ending-style] {
100
124
  transform: translateY(-100%);
@@ -103,6 +127,8 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
103
127
  panelBottom: css`
104
128
  --drawer-cast-y: -1;
105
129
 
130
+ border-block-start: var(--drawer-edge-width, 1px) solid ${cssVar.colorBorder};
131
+
106
132
  &[data-starting-style],
107
133
  &[data-ending-style] {
108
134
  transform: translateY(100%);
@@ -125,16 +151,14 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
125
151
  border-start-end-radius: 12px;
126
152
  `,
127
153
  panelFlush: css`
128
- --drawer-cast-far: 0%;
129
- --drawer-cast-near: 0%;
154
+ --drawer-cast-alpha: 0;
155
+ --drawer-edge-width: 0;
130
156
  `,
131
157
  panelBoosted: css`
132
- --drawer-cast-far: 14%;
133
- --drawer-cast-near: 7%;
158
+ --drawer-cast-alpha: 1.75;
134
159
  `,
135
160
  panelRecessed: css`
136
- --drawer-cast-far: 4%;
137
- --drawer-cast-near: 2%;
161
+ --drawer-cast-alpha: 0.5;
138
162
  `,
139
163
  header: css`
140
164
  display: flex;
@@ -263,11 +287,9 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
263
287
 
264
288
  padding-block: 12px;
265
289
  padding-inline: 16px;
266
- border-inline-end: 1px solid ${cssVar.colorSplit};
290
+ border-inline-end: 1px solid ${cssVar.colorBorderSecondary};
267
291
 
268
- /* A translucent fill reads as a secondary surface against whatever the panel is, where the
269
- page-level layout colour would punch a hole through an elevated panel in dark themes. */
270
- background: ${cssVar.colorFillTertiary};
292
+ background: ${cssVar.colorBgLayout};
271
293
  `,
272
294
  sidebarContent: css`
273
295
  overflow: hidden auto;
@@ -1 +1 @@
1
- {"version":3,"file":"style.mjs","names":[],"sources":["../../../src/base-ui/Drawer/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n backdrop: css`\n position: fixed;\n z-index: 1200;\n inset: 0;\n\n background: ${cssVar.colorBgMask};\n\n transition: opacity 180ms cubic-bezier(0.32, 0.72, 0, 1);\n\n &[data-starting-style],\n &[data-ending-style] {\n opacity: 0;\n }\n `,\n\n popup: css`\n pointer-events: none;\n\n position: fixed;\n z-index: 1201;\n\n display: flex;\n\n /* clamp here rather than on the panel, so an oversized size prop shrinks the\n box instead of detaching the panel from its anchored edge */\n max-width: 100dvw;\n max-height: 100dvh;\n `,\n\n popupLeft: css`\n inset-block: 0;\n inset-inline-start: 0;\n `,\n\n popupRight: css`\n inset-block: 0;\n inset-inline-end: 0;\n `,\n\n popupTop: css`\n inset-block-start: 0;\n inset-inline: 0;\n `,\n\n popupBottom: css`\n inset-block-end: 0;\n inset-inline: 0;\n `,\n\n panel: css`\n pointer-events: auto;\n\n position: relative;\n\n /* push offset rides on CSS vars so [data-starting-style] can override the whole transform */\n transform: translate(var(--drawer-push-x, 0), var(--drawer-push-y, 0));\n\n overflow: hidden;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n box-sizing: border-box;\n min-width: 0;\n min-height: 0;\n\n /* Elevated, not container: in dark themes container sits within 2 points of the page\n background, so a panel with no border and a black-on-black cast loses its edge entirely. */\n background: ${cssVar.colorBgElevated};\n\n /* An edge-anchored panel casts along its placement axis, not downward like a centred\n dialog would. Direction classes set the sign, weight classes set the opacity, so the\n two compose without a class per combination. */\n box-shadow:\n calc(var(--drawer-cast-x, 0) * 6px) calc(var(--drawer-cast-y, 0) * 6px) 24px 0\n rgb(0 0 0 / var(--drawer-cast-far, 8%)),\n calc(var(--drawer-cast-x, 0) * 2px) calc(var(--drawer-cast-y, 0) * 2px) 6px 0\n rgb(0 0 0 / var(--drawer-cast-near, 4%));\n\n transition: transform 300ms cubic-bezier(0.32, 0.72, 0, 1);\n `,\n\n panelLeft: css`\n --drawer-cast-x: 1;\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateX(-100%);\n }\n `,\n\n panelRight: css`\n --drawer-cast-x: -1;\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateX(100%);\n }\n `,\n\n panelTop: css`\n --drawer-cast-y: 1;\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateY(-100%);\n }\n `,\n\n panelBottom: css`\n --drawer-cast-y: -1;\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateY(100%);\n }\n `,\n\n /* Only the edges facing content get rounded; the anchored edge stays flush with the viewport.\n Kept apart from the direction classes so a flush panel can drop the radius by omitting the\n class rather than by out-specifying it. */\n panelRoundedLeft: css`\n border-start-end-radius: 12px;\n border-end-end-radius: 12px;\n `,\n\n panelRoundedRight: css`\n border-start-start-radius: 12px;\n border-end-start-radius: 12px;\n `,\n\n panelRoundedTop: css`\n border-end-start-radius: 12px;\n border-end-end-radius: 12px;\n `,\n\n panelRoundedBottom: css`\n border-start-start-radius: 12px;\n border-start-end-radius: 12px;\n `,\n\n /* Filling the viewport leaves nothing to cast onto — the shadow would only dirty the edge. */\n panelFlush: css`\n --drawer-cast-far: 0%;\n --drawer-cast-near: 0%;\n `,\n\n /* Without a backdrop the panel has to earn its separation from live content behind it. */\n panelBoosted: css`\n --drawer-cast-far: 14%;\n --drawer-cast-near: 7%;\n `,\n\n /* A pushed ancestor has receded behind its child; stacking full-weight casts would silt up. */\n panelRecessed: css`\n --drawer-cast-far: 4%;\n --drawer-cast-near: 2%;\n `,\n\n header: css`\n display: flex;\n flex: none;\n gap: 8px;\n align-items: center;\n justify-content: space-between;\n\n min-height: 56px;\n padding-block: 12px;\n padding-inline: 16px;\n border-block-end: 1px solid ${cssVar.colorSplit};\n `,\n\n containerInner: css`\n display: flex;\n flex: 1;\n gap: 8px;\n align-items: center;\n justify-content: space-between;\n\n width: 100%;\n margin-inline: auto;\n `,\n\n containerInnerFooter: css`\n justify-content: flex-end;\n `,\n\n title: css`\n margin: 0;\n\n font-size: 17px;\n font-weight: 600;\n line-height: 1.4;\n color: ${cssVar.colorText};\n letter-spacing: -0.005em;\n `,\n\n extra: css`\n display: flex;\n flex: none;\n gap: 4px;\n align-items: center;\n\n margin-inline-end: -4px;\n `,\n\n extraFloating: css`\n position: absolute;\n z-index: 1;\n inset-block-start: 12px;\n inset-inline-end: 12px;\n\n margin-inline-end: 0;\n `,\n\n close: css`\n cursor: pointer;\n\n position: relative;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: 8px;\n\n color: ${cssVar.colorTextTertiary};\n\n background: transparent;\n\n transition:\n color 160ms cubic-bezier(0.32, 0.72, 0, 1),\n background 160ms cubic-bezier(0.32, 0.72, 0, 1),\n transform 160ms cubic-bezier(0.32, 0.72, 0, 1);\n\n /* Restores the 40px target the 32px visual box gives up, without nudging the header layout. */\n &::after {\n content: '';\n position: absolute;\n inset: -4px;\n }\n\n &:hover {\n transform: scale(1.04);\n color: ${cssVar.colorText};\n background: ${cssVar.colorFillSecondary};\n }\n\n &:active {\n transform: scale(0.96);\n }\n\n &:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px ${cssVar.colorPrimaryBorder};\n }\n `,\n\n content: css`\n overflow: hidden auto;\n display: flex;\n flex: 1;\n min-height: 0;\n `,\n\n bodyContent: css`\n display: flex;\n flex-direction: column;\n\n width: 100%;\n min-height: 100%;\n margin-inline: auto;\n padding-block: 12px;\n padding-inline: 16px;\n `,\n\n contentSidebar: css`\n overflow: hidden;\n `,\n\n bodyContentSidebar: css`\n flex-direction: row;\n height: 100%;\n min-height: 0;\n padding: 0;\n `,\n\n sidebar: css`\n overflow: hidden auto;\n flex: none;\n\n padding-block: 12px;\n padding-inline: 16px;\n border-inline-end: 1px solid ${cssVar.colorSplit};\n\n /* A translucent fill reads as a secondary surface against whatever the panel is, where the\n page-level layout colour would punch a hole through an elevated panel in dark themes. */\n background: ${cssVar.colorFillTertiary};\n `,\n\n sidebarContent: css`\n overflow: hidden auto;\n flex: 1;\n\n min-width: 0;\n padding-block: 12px;\n padding-inline: 16px;\n `,\n\n footer: css`\n display: flex;\n flex: none;\n gap: 8px;\n align-items: center;\n justify-content: flex-end;\n\n padding-block: 12px;\n padding-inline: 16px;\n border-block-start: 1px solid ${cssVar.colorSplit};\n `,\n}));\n"],"mappings":";;AAEA,MAAa,SAAS,oBAAoB,EAAE,KAAK,cAAc;CAC7D,UAAU,GAAG;;;;;kBAKG,OAAO,YAAY;;;;;;;;;CAUnC,OAAO,GAAG;;;;;;;;;;;;;CAcV,WAAW,GAAG;;;;CAKd,YAAY,GAAG;;;;CAKf,UAAU,GAAG;;;;CAKb,aAAa,GAAG;;;;CAKhB,OAAO,GAAG;;;;;;;;;;;;;;;;;;;kBAmBM,OAAO,gBAAgB;;;;;;;;;;;;;CAcvC,WAAW,GAAG;;;;;;;;CASd,YAAY,GAAG;;;;;;;;CASf,UAAU,GAAG;;;;;;;;CASb,aAAa,GAAG;;;;;;;;CAYhB,kBAAkB,GAAG;;;;CAKrB,mBAAmB,GAAG;;;;CAKtB,iBAAiB,GAAG;;;;CAKpB,oBAAoB,GAAG;;;;CAMvB,YAAY,GAAG;;;;CAMf,cAAc,GAAG;;;;CAMjB,eAAe,GAAG;;;;CAKlB,QAAQ,GAAG;;;;;;;;;;kCAUqB,OAAO,WAAW;;CAGlD,gBAAgB,GAAG;;;;;;;;;;CAWnB,sBAAsB,GAAG;;;CAIzB,OAAO,GAAG;;;;;;aAMC,OAAO,UAAU;;;CAI5B,OAAO,GAAG;;;;;;;;CASV,eAAe,GAAG;;;;;;;;CASlB,OAAO,GAAG;;;;;;;;;;;;;;;aAeC,OAAO,kBAAkB;;;;;;;;;;;;;;;;;;eAkBvB,OAAO,UAAU;oBACZ,OAAO,mBAAmB;;;;;;;;;8BAShB,OAAO,mBAAmB;;;CAItD,SAAS,GAAG;;;;;;CAOZ,aAAa,GAAG;;;;;;;;;;CAWhB,gBAAgB,GAAG;;;CAInB,oBAAoB,GAAG;;;;;;CAOvB,SAAS,GAAG;;;;;;mCAMqB,OAAO,WAAW;;;;kBAInC,OAAO,kBAAkB;;CAGzC,gBAAgB,GAAG;;;;;;;;CASnB,QAAQ,GAAG;;;;;;;;;oCASuB,OAAO,WAAW;;AAEtD,EAAE"}
1
+ {"version":3,"file":"style.mjs","names":[],"sources":["../../../src/base-ui/Drawer/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n backdrop: css`\n position: fixed;\n z-index: 1200;\n inset: 0;\n\n background: ${cssVar.colorBgMask};\n\n transition: opacity 180ms cubic-bezier(0.32, 0.72, 0, 1);\n\n &[data-starting-style],\n &[data-ending-style] {\n opacity: 0;\n }\n `,\n\n popup: css`\n pointer-events: none;\n\n position: fixed;\n z-index: 1201;\n\n display: flex;\n\n /* clamp here rather than on the panel, so an oversized size prop shrinks the\n box instead of detaching the panel from its anchored edge */\n max-width: 100dvw;\n max-height: 100dvh;\n `,\n\n popupLeft: css`\n inset-block: 0;\n inset-inline-start: 0;\n `,\n\n popupRight: css`\n inset-block: 0;\n inset-inline-end: 0;\n `,\n\n popupTop: css`\n inset-block-start: 0;\n inset-inline: 0;\n `,\n\n popupBottom: css`\n inset-block-end: 0;\n inset-inline: 0;\n `,\n\n panel: css`\n pointer-events: auto;\n\n position: relative;\n\n /* push offset rides on CSS vars so [data-starting-style] can override the whole transform */\n transform: translate(var(--drawer-push-x, 0), var(--drawer-push-y, 0));\n\n overflow: hidden;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n box-sizing: border-box;\n min-width: 0;\n min-height: 0;\n\n /* Container, not elevated: the antd-based Drawer paints its panel on container, and in dark\n themes elevated is a visibly lighter step the two drawers must read as the same surface. */\n background: ${cssVar.colorBgContainer};\n\n /* Geometry and alphas are antd's boxShadowDrawer{Left,Right,Up,Down} verbatim, so both drawers\n cast identically. antd builds those by scaling colorShadow's *own* alpha by 8/12/5%, and\n colorShadow flips from opaque black to rgba(255,255,255,0.2) in dark — hence the color-mix\n against the raw var rather than a literal black (colorShadow has no AliasToken typing, so\n cssVar cannot reach it). An edge-anchored panel casts along its placement axis rather than\n downward like a centred dialog would: direction classes set the sign, weight classes scale\n the alpha, so the two compose without a class per combination. */\n box-shadow:\n calc(var(--drawer-cast-x, 0) * 6px) calc(var(--drawer-cast-y, 0) * 6px) 16px 0\n color-mix(\n in srgb,\n var(--ant-color-shadow, #000) calc(8% * var(--drawer-cast-alpha, 1)),\n transparent\n ),\n calc(var(--drawer-cast-x, 0) * 3px) calc(var(--drawer-cast-y, 0) * 3px) 6px -4px\n color-mix(\n in srgb,\n var(--ant-color-shadow, #000) calc(12% * var(--drawer-cast-alpha, 1)),\n transparent\n ),\n calc(var(--drawer-cast-x, 0) * 9px) calc(var(--drawer-cast-y, 0) * 9px) 28px 8px\n color-mix(\n in srgb,\n var(--ant-color-shadow, #000) calc(5% * var(--drawer-cast-alpha, 1)),\n transparent\n );\n\n transition: transform 300ms cubic-bezier(0.32, 0.72, 0, 1);\n `,\n\n panelLeft: css`\n --drawer-cast-x: 1;\n\n border-inline-end: var(--drawer-edge-width, 1px) solid ${cssVar.colorBorder};\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateX(-100%);\n }\n `,\n\n panelRight: css`\n --drawer-cast-x: -1;\n\n border-inline-start: var(--drawer-edge-width, 1px) solid ${cssVar.colorBorder};\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateX(100%);\n }\n `,\n\n panelTop: css`\n --drawer-cast-y: 1;\n\n border-block-end: var(--drawer-edge-width, 1px) solid ${cssVar.colorBorder};\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateY(-100%);\n }\n `,\n\n panelBottom: css`\n --drawer-cast-y: -1;\n\n border-block-start: var(--drawer-edge-width, 1px) solid ${cssVar.colorBorder};\n\n &[data-starting-style],\n &[data-ending-style] {\n transform: translateY(100%);\n }\n `,\n\n /* Only the edges facing content get rounded; the anchored edge stays flush with the viewport.\n Kept apart from the direction classes so a flush panel can drop the radius by omitting the\n class rather than by out-specifying it. */\n panelRoundedLeft: css`\n border-start-end-radius: 12px;\n border-end-end-radius: 12px;\n `,\n\n panelRoundedRight: css`\n border-start-start-radius: 12px;\n border-end-start-radius: 12px;\n `,\n\n panelRoundedTop: css`\n border-end-start-radius: 12px;\n border-end-end-radius: 12px;\n `,\n\n panelRoundedBottom: css`\n border-start-start-radius: 12px;\n border-start-end-radius: 12px;\n `,\n\n /* Filling the viewport leaves nothing to cast onto or to divide from — the shadow and the edge\n rule would only dirty the seam against the viewport. */\n panelFlush: css`\n --drawer-cast-alpha: 0;\n --drawer-edge-width: 0;\n `,\n\n /* Without a backdrop the panel has to earn its separation from live content behind it. */\n panelBoosted: css`\n --drawer-cast-alpha: 1.75;\n `,\n\n /* A pushed ancestor has receded behind its child; stacking full-weight casts would silt up. */\n panelRecessed: css`\n --drawer-cast-alpha: 0.5;\n `,\n\n header: css`\n display: flex;\n flex: none;\n gap: 8px;\n align-items: center;\n justify-content: space-between;\n\n min-height: 56px;\n padding-block: 12px;\n padding-inline: 16px;\n border-block-end: 1px solid ${cssVar.colorSplit};\n `,\n\n containerInner: css`\n display: flex;\n flex: 1;\n gap: 8px;\n align-items: center;\n justify-content: space-between;\n\n width: 100%;\n margin-inline: auto;\n `,\n\n containerInnerFooter: css`\n justify-content: flex-end;\n `,\n\n title: css`\n margin: 0;\n\n font-size: 17px;\n font-weight: 600;\n line-height: 1.4;\n color: ${cssVar.colorText};\n letter-spacing: -0.005em;\n `,\n\n extra: css`\n display: flex;\n flex: none;\n gap: 4px;\n align-items: center;\n\n margin-inline-end: -4px;\n `,\n\n extraFloating: css`\n position: absolute;\n z-index: 1;\n inset-block-start: 12px;\n inset-inline-end: 12px;\n\n margin-inline-end: 0;\n `,\n\n close: css`\n cursor: pointer;\n\n position: relative;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: 8px;\n\n color: ${cssVar.colorTextTertiary};\n\n background: transparent;\n\n transition:\n color 160ms cubic-bezier(0.32, 0.72, 0, 1),\n background 160ms cubic-bezier(0.32, 0.72, 0, 1),\n transform 160ms cubic-bezier(0.32, 0.72, 0, 1);\n\n /* Restores the 40px target the 32px visual box gives up, without nudging the header layout. */\n &::after {\n content: '';\n position: absolute;\n inset: -4px;\n }\n\n &:hover {\n transform: scale(1.04);\n color: ${cssVar.colorText};\n background: ${cssVar.colorFillSecondary};\n }\n\n &:active {\n transform: scale(0.96);\n }\n\n &:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px ${cssVar.colorPrimaryBorder};\n }\n `,\n\n content: css`\n overflow: hidden auto;\n display: flex;\n flex: 1;\n min-height: 0;\n `,\n\n bodyContent: css`\n display: flex;\n flex-direction: column;\n\n width: 100%;\n min-height: 100%;\n margin-inline: auto;\n padding-block: 12px;\n padding-inline: 16px;\n `,\n\n contentSidebar: css`\n overflow: hidden;\n `,\n\n bodyContentSidebar: css`\n flex-direction: row;\n height: 100%;\n min-height: 0;\n padding: 0;\n `,\n\n sidebar: css`\n overflow: hidden auto;\n flex: none;\n\n padding-block: 12px;\n padding-inline: 16px;\n border-inline-end: 1px solid ${cssVar.colorBorderSecondary};\n\n background: ${cssVar.colorBgLayout};\n `,\n\n sidebarContent: css`\n overflow: hidden auto;\n flex: 1;\n\n min-width: 0;\n padding-block: 12px;\n padding-inline: 16px;\n `,\n\n footer: css`\n display: flex;\n flex: none;\n gap: 8px;\n align-items: center;\n justify-content: flex-end;\n\n padding-block: 12px;\n padding-inline: 16px;\n border-block-start: 1px solid ${cssVar.colorSplit};\n `,\n}));\n"],"mappings":";;AAEA,MAAa,SAAS,oBAAoB,EAAE,KAAK,cAAc;CAC7D,UAAU,GAAG;;;;;kBAKG,OAAO,YAAY;;;;;;;;;CAUnC,OAAO,GAAG;;;;;;;;;;;;;CAcV,WAAW,GAAG;;;;CAKd,YAAY,GAAG;;;;CAKf,UAAU,GAAG;;;;CAKb,aAAa,GAAG;;;;CAKhB,OAAO,GAAG;;;;;;;;;;;;;;;;;;;kBAmBM,OAAO,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCxC,WAAW,GAAG;;;6DAG6C,OAAO,YAAY;;;;;;;CAQ9E,YAAY,GAAG;;;+DAG8C,OAAO,YAAY;;;;;;;CAQhF,UAAU,GAAG;;;4DAG6C,OAAO,YAAY;;;;;;;CAQ7E,aAAa,GAAG;;;8DAG4C,OAAO,YAAY;;;;;;;CAW/E,kBAAkB,GAAG;;;;CAKrB,mBAAmB,GAAG;;;;CAKtB,iBAAiB,GAAG;;;;CAKpB,oBAAoB,GAAG;;;;CAOvB,YAAY,GAAG;;;;CAMf,cAAc,GAAG;;;CAKjB,eAAe,GAAG;;;CAIlB,QAAQ,GAAG;;;;;;;;;;kCAUqB,OAAO,WAAW;;CAGlD,gBAAgB,GAAG;;;;;;;;;;CAWnB,sBAAsB,GAAG;;;CAIzB,OAAO,GAAG;;;;;;aAMC,OAAO,UAAU;;;CAI5B,OAAO,GAAG;;;;;;;;CASV,eAAe,GAAG;;;;;;;;CASlB,OAAO,GAAG;;;;;;;;;;;;;;;aAeC,OAAO,kBAAkB;;;;;;;;;;;;;;;;;;eAkBvB,OAAO,UAAU;oBACZ,OAAO,mBAAmB;;;;;;;;;8BAShB,OAAO,mBAAmB;;;CAItD,SAAS,GAAG;;;;;;CAOZ,aAAa,GAAG;;;;;;;;;;CAWhB,gBAAgB,GAAG;;;CAInB,oBAAoB,GAAG;;;;;;CAOvB,SAAS,GAAG;;;;;;mCAMqB,OAAO,qBAAqB;;kBAE7C,OAAO,cAAc;;CAGrC,gBAAgB,GAAG;;;;;;;;CASnB,QAAQ,GAAG;;;;;;;;;oCASuB,OAAO,WAAW;;AAEtD,EAAE"}
@@ -1,6 +1,7 @@
1
1
  //#region src/eslint/index.ts
2
2
  const DEPRECATED_UI_COMPONENTS = [
3
3
  "Button",
4
+ "Drawer",
4
5
  "Modal",
5
6
  "Segmented",
6
7
  "Select",
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/eslint/index.ts"],"sourcesContent":["const DEPRECATED_UI_COMPONENTS = ['Button', 'Modal', 'Segmented', 'Select', 'Tabs'];\n\nexport const restrictedImports = {\n rules: {\n 'no-restricted-imports': [\n 'error',\n {\n paths: [\n {\n importNames: DEPRECATED_UI_COMPONENTS,\n message:\n 'The antd-based wrapper is deprecated. Import from \"@lobehub/ui/base-ui\" instead.',\n name: '@lobehub/ui',\n },\n {\n importNames: ['createStyles'],\n message:\n '`createStyles` is banned in this project. Use `createStaticStyles` from \"antd-style\" instead.',\n name: 'antd-style',\n },\n {\n importNames: DEPRECATED_UI_COMPONENTS,\n message:\n 'Direct antd import is deprecated. Import from \"@lobehub/ui\" or \"@lobehub/ui/base-ui\" instead.',\n name: 'antd',\n },\n ],\n },\n ],\n },\n};\n\nexport default [restrictedImports];\n"],"mappings":";AAAA,MAAM,2BAA2B;CAAC;CAAU;CAAS;CAAa;CAAU;AAAM;AAElF,MAAa,oBAAoB,EAC/B,OAAO,EACL,yBAAyB,CACvB,SACA,EACE,OAAO;CACL;EACE,aAAa;EACb,SACE;EACF,MAAM;CACR;CACA;EACE,aAAa,CAAC,cAAc;EAC5B,SACE;EACF,MAAM;CACR;CACA;EACE,aAAa;EACb,SACE;EACF,MAAM;CACR;AACF,EACF,CACF,EACF,EACF;AAEA,IAAA,iBAAe,CAAC,iBAAiB"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/eslint/index.ts"],"sourcesContent":["const DEPRECATED_UI_COMPONENTS = ['Button', 'Drawer', 'Modal', 'Segmented', 'Select', 'Tabs'];\n\nexport const restrictedImports = {\n rules: {\n 'no-restricted-imports': [\n 'error',\n {\n paths: [\n {\n importNames: DEPRECATED_UI_COMPONENTS,\n message:\n 'The antd-based wrapper is deprecated. Import from \"@lobehub/ui/base-ui\" instead.',\n name: '@lobehub/ui',\n },\n {\n importNames: ['createStyles'],\n message:\n '`createStyles` is banned in this project. Use `createStaticStyles` from \"antd-style\" instead.',\n name: 'antd-style',\n },\n {\n importNames: DEPRECATED_UI_COMPONENTS,\n message:\n 'Direct antd import is deprecated. Import from \"@lobehub/ui\" or \"@lobehub/ui/base-ui\" instead.',\n name: 'antd',\n },\n ],\n },\n ],\n },\n};\n\nexport default [restrictedImports];\n"],"mappings":";AAAA,MAAM,2BAA2B;CAAC;CAAU;CAAU;CAAS;CAAa;CAAU;AAAM;AAE5F,MAAa,oBAAoB,EAC/B,OAAO,EACL,yBAAyB,CACvB,SACA,EACE,OAAO;CACL;EACE,aAAa;EACb,SACE;EACF,MAAM;CACR;CACA;EACE,aAAa,CAAC,cAAc;EAC5B,SACE;EACF,MAAM;CACR;CACA;EACE,aAAa;EACb,SACE;EACF,MAAM;CACR;AACF,EACF,CACF,EACF,EACF;AAEA,IAAA,iBAAe,CAAC,iBAAiB"}
@@ -1,5 +1,6 @@
1
1
  //#region src/i18n/resources/en/image.d.ts
2
2
  declare const _default: {
3
+ readonly 'image.actualSize': "Actual Size";
3
4
  readonly 'image.close': "Close";
4
5
  readonly 'image.copy': "Copy";
5
6
  readonly 'image.copyFailed': "Copy Failed";
@@ -7,6 +8,7 @@ declare const _default: {
7
8
  readonly 'image.download': "Download";
8
9
  readonly 'image.downloadFailed': "Download Failed";
9
10
  readonly 'image.downloadSuccess': "Download Success";
11
+ readonly 'image.fitToScreen': "Fit to Screen";
10
12
  readonly 'image.flipHorizontal': "Flip Horizontal";
11
13
  readonly 'image.flipVertical': "Flip Vertical";
12
14
  readonly 'image.more': "More";
@@ -16,7 +18,6 @@ declare const _default: {
16
18
  readonly 'image.rotateRight': "Rotate Right";
17
19
  readonly 'image.zoomIn': "Zoom In";
18
20
  readonly 'image.zoomOut': "Zoom Out";
19
- readonly 'image.zoomReset': "Reset Zoom";
20
21
  };
21
22
  //#endregion
22
23
  export { _default as default };
@@ -1,5 +1,6 @@
1
1
  //#region src/i18n/resources/en/image.ts
2
2
  var image_default = {
3
+ "image.actualSize": "Actual Size",
3
4
  "image.close": "Close",
4
5
  "image.copy": "Copy",
5
6
  "image.copyFailed": "Copy Failed",
@@ -7,6 +8,7 @@ var image_default = {
7
8
  "image.download": "Download",
8
9
  "image.downloadFailed": "Download Failed",
9
10
  "image.downloadSuccess": "Download Success",
11
+ "image.fitToScreen": "Fit to Screen",
10
12
  "image.flipHorizontal": "Flip Horizontal",
11
13
  "image.flipVertical": "Flip Vertical",
12
14
  "image.more": "More",
@@ -15,8 +17,7 @@ var image_default = {
15
17
  "image.rotateLeft": "Rotate Left",
16
18
  "image.rotateRight": "Rotate Right",
17
19
  "image.zoomIn": "Zoom In",
18
- "image.zoomOut": "Zoom Out",
19
- "image.zoomReset": "Reset Zoom"
20
+ "image.zoomOut": "Zoom Out"
20
21
  };
21
22
  //#endregion
22
23
  export { image_default as default };
@@ -1 +1 @@
1
- {"version":3,"file":"image.mjs","names":[],"sources":["../../../../src/i18n/resources/en/image.ts"],"sourcesContent":["export default {\n 'image.close': 'Close',\n 'image.copy': 'Copy',\n 'image.copyFailed': 'Copy Failed',\n 'image.copySuccess': 'Copy Success',\n 'image.download': 'Download',\n 'image.downloadFailed': 'Download Failed',\n 'image.downloadSuccess': 'Download Success',\n 'image.flipHorizontal': 'Flip Horizontal',\n 'image.flipVertical': 'Flip Vertical',\n 'image.more': 'More',\n 'image.next': 'Next',\n 'image.prev': 'Previous',\n 'image.rotateLeft': 'Rotate Left',\n 'image.rotateRight': 'Rotate Right',\n 'image.zoomIn': 'Zoom In',\n 'image.zoomOut': 'Zoom Out',\n 'image.zoomReset': 'Reset Zoom',\n} as const;\n"],"mappings":";AAAA,IAAA,gBAAe;CACb,eAAe;CACf,cAAc;CACd,oBAAoB;CACpB,qBAAqB;CACrB,kBAAkB;CAClB,wBAAwB;CACxB,yBAAyB;CACzB,wBAAwB;CACxB,sBAAsB;CACtB,cAAc;CACd,cAAc;CACd,cAAc;CACd,oBAAoB;CACpB,qBAAqB;CACrB,gBAAgB;CAChB,iBAAiB;CACjB,mBAAmB;AACrB"}
1
+ {"version":3,"file":"image.mjs","names":[],"sources":["../../../../src/i18n/resources/en/image.ts"],"sourcesContent":["export default {\n 'image.actualSize': 'Actual Size',\n 'image.close': 'Close',\n 'image.copy': 'Copy',\n 'image.copyFailed': 'Copy Failed',\n 'image.copySuccess': 'Copy Success',\n 'image.download': 'Download',\n 'image.downloadFailed': 'Download Failed',\n 'image.downloadSuccess': 'Download Success',\n 'image.fitToScreen': 'Fit to Screen',\n 'image.flipHorizontal': 'Flip Horizontal',\n 'image.flipVertical': 'Flip Vertical',\n 'image.more': 'More',\n 'image.next': 'Next',\n 'image.prev': 'Previous',\n 'image.rotateLeft': 'Rotate Left',\n 'image.rotateRight': 'Rotate Right',\n 'image.zoomIn': 'Zoom In',\n 'image.zoomOut': 'Zoom Out',\n} as const;\n"],"mappings":";AAAA,IAAA,gBAAe;CACb,oBAAoB;CACpB,eAAe;CACf,cAAc;CACd,oBAAoB;CACpB,qBAAqB;CACrB,kBAAkB;CAClB,wBAAwB;CACxB,yBAAyB;CACzB,qBAAqB;CACrB,wBAAwB;CACxB,sBAAsB;CACtB,cAAc;CACd,cAAc;CACd,cAAc;CACd,oBAAoB;CACpB,qBAAqB;CACrB,gBAAgB;CAChB,iBAAiB;AACnB"}
@@ -1,5 +1,6 @@
1
1
  //#region src/i18n/resources/zhCn/image.d.ts
2
2
  declare const _default: {
3
+ readonly 'image.actualSize': "实际尺寸";
3
4
  readonly 'image.close': "关闭";
4
5
  readonly 'image.copy': "复制";
5
6
  readonly 'image.copyFailed': "复制失败";
@@ -7,6 +8,7 @@ declare const _default: {
7
8
  readonly 'image.download': "下载";
8
9
  readonly 'image.downloadFailed': "下载失败";
9
10
  readonly 'image.downloadSuccess': "下载成功";
11
+ readonly 'image.fitToScreen': "适应屏幕";
10
12
  readonly 'image.flipHorizontal': "水平翻转";
11
13
  readonly 'image.flipVertical': "垂直翻转";
12
14
  readonly 'image.more': "更多";
@@ -16,7 +18,6 @@ declare const _default: {
16
18
  readonly 'image.rotateRight': "向右旋转";
17
19
  readonly 'image.zoomIn': "放大";
18
20
  readonly 'image.zoomOut': "缩小";
19
- readonly 'image.zoomReset': "重置缩放";
20
21
  };
21
22
  //#endregion
22
23
  export { _default as default };
@@ -1,5 +1,6 @@
1
1
  //#region src/i18n/resources/zhCn/image.ts
2
2
  var image_default = {
3
+ "image.actualSize": "实际尺寸",
3
4
  "image.close": "关闭",
4
5
  "image.copy": "复制",
5
6
  "image.copyFailed": "复制失败",
@@ -7,6 +8,7 @@ var image_default = {
7
8
  "image.download": "下载",
8
9
  "image.downloadFailed": "下载失败",
9
10
  "image.downloadSuccess": "下载成功",
11
+ "image.fitToScreen": "适应屏幕",
10
12
  "image.flipHorizontal": "水平翻转",
11
13
  "image.flipVertical": "垂直翻转",
12
14
  "image.more": "更多",
@@ -15,8 +17,7 @@ var image_default = {
15
17
  "image.rotateLeft": "向左旋转",
16
18
  "image.rotateRight": "向右旋转",
17
19
  "image.zoomIn": "放大",
18
- "image.zoomOut": "缩小",
19
- "image.zoomReset": "重置缩放"
20
+ "image.zoomOut": "缩小"
20
21
  };
21
22
  //#endregion
22
23
  export { image_default as default };
@@ -1 +1 @@
1
- {"version":3,"file":"image.mjs","names":[],"sources":["../../../../src/i18n/resources/zhCn/image.ts"],"sourcesContent":["export default {\n 'image.close': '关闭',\n 'image.copy': '复制',\n 'image.copyFailed': '复制失败',\n 'image.copySuccess': '复制成功',\n 'image.download': '下载',\n 'image.downloadFailed': '下载失败',\n 'image.downloadSuccess': '下载成功',\n 'image.flipHorizontal': '水平翻转',\n 'image.flipVertical': '垂直翻转',\n 'image.more': '更多',\n 'image.next': '下一张',\n 'image.prev': '上一张',\n 'image.rotateLeft': '向左旋转',\n 'image.rotateRight': '向右旋转',\n 'image.zoomIn': '放大',\n 'image.zoomOut': '缩小',\n 'image.zoomReset': '重置缩放',\n} as const;\n"],"mappings":";AAAA,IAAA,gBAAe;CACb,eAAe;CACf,cAAc;CACd,oBAAoB;CACpB,qBAAqB;CACrB,kBAAkB;CAClB,wBAAwB;CACxB,yBAAyB;CACzB,wBAAwB;CACxB,sBAAsB;CACtB,cAAc;CACd,cAAc;CACd,cAAc;CACd,oBAAoB;CACpB,qBAAqB;CACrB,gBAAgB;CAChB,iBAAiB;CACjB,mBAAmB;AACrB"}
1
+ {"version":3,"file":"image.mjs","names":[],"sources":["../../../../src/i18n/resources/zhCn/image.ts"],"sourcesContent":["export default {\n 'image.actualSize': '实际尺寸',\n 'image.close': '关闭',\n 'image.copy': '复制',\n 'image.copyFailed': '复制失败',\n 'image.copySuccess': '复制成功',\n 'image.download': '下载',\n 'image.downloadFailed': '下载失败',\n 'image.downloadSuccess': '下载成功',\n 'image.fitToScreen': '适应屏幕',\n 'image.flipHorizontal': '水平翻转',\n 'image.flipVertical': '垂直翻转',\n 'image.more': '更多',\n 'image.next': '下一张',\n 'image.prev': '上一张',\n 'image.rotateLeft': '向左旋转',\n 'image.rotateRight': '向右旋转',\n 'image.zoomIn': '放大',\n 'image.zoomOut': '缩小',\n} as const;\n"],"mappings":";AAAA,IAAA,gBAAe;CACb,oBAAoB;CACpB,eAAe;CACf,cAAc;CACd,oBAAoB;CACpB,qBAAqB;CACrB,kBAAkB;CAClB,wBAAwB;CACxB,yBAAyB;CACzB,qBAAqB;CACrB,wBAAwB;CACxB,sBAAsB;CACtB,cAAc;CACd,cAAc;CACd,cAAc;CACd,oBAAoB;CACpB,qBAAqB;CACrB,gBAAgB;CAChB,iBAAiB;AACnB"}
package/es/index.d.mts CHANGED
@@ -186,7 +186,7 @@ import HtmlPreview from "./HtmlPreview/HtmlPreview.mjs";
186
186
  import { HtmlPreviewIframe } from "./HtmlPreview/Iframe.mjs";
187
187
  import { AUTO_HEIGHT_MESSAGE_TYPE } from "./HtmlPreview/injectAutoHeightScript.mjs";
188
188
  import "./HtmlPreview/index.mjs";
189
- import { ImageProps, PreviewGroupProps } from "./Image/type.mjs";
189
+ import { ImagePreviewOptions, ImageProps, PreviewGroupProps } from "./Image/type.mjs";
190
190
  import PreviewGroup from "./Image/PreviewGroup.mjs";
191
191
  import Image from "./Image/index.mjs";
192
192
  import A from "./A/index.mjs";
@@ -309,4 +309,4 @@ import { LayoutSidebarInner } from "./Layout/components/LayoutSidebarInner.mjs";
309
309
  import { LayoutToc } from "./Layout/components/LayoutToc.mjs";
310
310
  import Layout from "./Layout/index.mjs";
311
311
  import { ErrorBoundary, ErrorBoundaryProps } from "react-error-boundary";
312
- export { A, type AProps, Accordion, AccordionItem, type AccordionItemProps, type AccordionProps, ActionIcon, ActionIconGroup, type ActionIconGroupEvent, type MenuItemType as ActionIconGroupItemType, type ActionIconGroupProps, type ActionIconProps, type ActionIconSize, Alert, type AlertProps, AutoComplete, type AutoCompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type BaseMenuItemType, Block, type BlockProps, Burger, type BurgerProps, Button, type ButtonProps, type CDN, CLASSNAMES, Center, type CenterProps, Checkbox, CheckboxGroup, type CheckboxGroupOption, type CheckboxGroupProps, type CheckboxProps, CodeDiff, type CodeDiffProps, CodeEditor, type CodeEditorProps, Collapse, type CollapseItemType, type CollapseProps, type ColorPalettes, type ColorPalettesAlpha, ColorSwatches, type ColorSwatchesProps, type ColorToken, type Config, ConfigProvider, type ContextMenuCheckboxItem, ContextMenuHost, type ContextMenuInterceptor, type ContextMenuItem, ContextMenuTrigger, CopyButton, type CopyButtonProps, DatePicker, type DatePickerProps, type DiffViewMode, type DivProps, DownloadButton, type DownloadButtonProps, DraggablePanel, DraggablePanelBody, type DraggablePanelBodyProps, DraggablePanelContainer, type DraggablePanelContainerProps, DraggablePanelFooter, type DraggablePanelFooterProps, DraggablePanelHeader, type DraggablePanelHeaderProps, type DraggablePanelProps, DraggableSideNav, type DraggableSideNavProps, Drawer, type DrawerProps, Dropdown, type DropdownItem, DropdownMenu, type DropdownMenuCheckboxItem, DropdownMenuCheckboxItemIndicator, DropdownMenuCheckboxItemPrimitive, DropdownMenuFooter, type DropdownMenuFooterProps, DropdownMenuGroup, DropdownMenuGroupLabel, type DropdownMenuGroupLabelProps, DropdownMenuHeader, type DropdownMenuHeaderProps, DropdownMenuItem, DropdownMenuItemContent, type DropdownMenuItemContentProps, DropdownMenuItemExtra, type DropdownMenuItemExtraProps, DropdownMenuItemIcon, type DropdownMenuItemIconProps, DropdownMenuItemLabel, type DropdownMenuItemLabelProps, type DropdownMenuItemProps, type MenuItemType as DropdownMenuItemType, type DropdownMenuPlacement, DropdownMenuPopup, type DropdownMenuPopupProps, DropdownMenuPortal, type DropdownMenuPortalProps, DropdownMenuPositioner, type DropdownMenuPositionerProps, type DropdownMenuProps, DropdownMenuRoot, DropdownMenuScrollViewport, type DropdownMenuScrollViewportProps, DropdownMenuSeparator, type DropdownMenuSeparatorProps, DropdownMenuSubmenuArrow, type DropdownMenuSubmenuArrowProps, DropdownMenuSubmenuRoot, DropdownMenuSubmenuTrigger, type DropdownMenuSubmenuTriggerProps, DropdownMenuTrigger, type DropdownMenuTriggerProps, type DropdownProps, EditableText, type EditableTextProps, EditorSlashMenu, type EditorSlashMenuGroup, type EditorSlashMenuItems, type EditorSlashMenuOption, EmojiPicker, type EmojiPickerProps, Empty, type EmptyProps, ErrorBoundary, type ErrorBoundaryProps, FileTypeIcon, type FileTypeIconProps, _default as FlexBasic, type FlexBasicProps, _default as Flexbox, type FlexboxProps, FluentEmoji, type FluentEmojiProps, FontLoader, type FontLoaderProps, Footer, type FooterProps, Form, FormGroup, type FormGroupItemType, type FormGroupProps, type FormInstance, FormItem, type FormItemProps, FormModal, type FormModalProps, type FormProps, FormSubmitFooter, type FormSubmitFooterProps, FormTitle, type FormTitleProps, Freeze, type FreezeProps, type GenericItemType, Grid, type GridProps, GroupAvatar, type GroupAvatarProps, GuideCard, type GuideCardProps, DEFAULT_HEIGHT as HTML_PREVIEW_DEFAULT_HEIGHT, DEFAULT_SANDBOX as HTML_PREVIEW_DEFAULT_SANDBOX, AUTO_HEIGHT_MESSAGE_TYPE as HTML_PREVIEW_RESIZE_MESSAGE, Header, type HeaderProps, Highlighter, type HighlighterProps, Hotkey, HotkeyInput, type HotkeyInputProps, type HotkeyProps, HtmlPreview, HtmlPreviewIframe, type HtmlPreviewIframeProps, type HtmlPreviewMode, type HtmlPreviewProps, type HtmlPreviewStreamingMode, I18nProvider, type I18nProviderProps, Icon, type IconProps, IconProvider, type IconSize, Image, type ImageProps, ImageSelect, type ImageSelectItem, type ImageSelectProps, type ImgProps, type ImperativeModalProps, Input, InputNumber, type InputNumberProps, InputOPT, type InputOPTProps, InputPassword, type InputPasswordProps, type InputProps, type ItemType, KeyMapEnum, LOBE_THEME_APP_ID, Layout, LayoutFooter, type LayoutFooterProps, LayoutHeader, type LayoutHeaderProps, LayoutMain, type LayoutMainProps, type LayoutProps, LayoutSidebar, LayoutSidebarInner, type LayoutSidebarInnerProps, type LayoutSidebarProps, LayoutToc, type LayoutTocProps, List, ListItem, type ListItemProps, type ListProps, type LobeCustomStylish, type LobeCustomToken, I18nProvider as LobeUIProvider, Markdown, type MarkdownProps, MaskShadow, type MaskShadowProps, MaterialFileTypeIcon, type MaterialFileTypeIconProps, Menu, type MenuCheckboxItemType, type MenuInfo, type MenuItemType, type MenuProps, Mermaid, type MermaidProps, Meta, type MetaProps, Modal, ModalHost, type ModalHostProps, type ModalInstance, type ModalProps, ModalProvider, MotionComponent, type MotionComponentType, MotionProvider, NeuralNetworkLoading, type NeuralNetworkLoadingProps, NeutralColors, NeutralColorsObj, PatchDiff, type PatchDiffProps, type Placement, type PlacementConfig, Popover, PopoverArrow, type PopoverArrowAtomProps, PopoverArrowIcon, PopoverBackdrop, type PopoverContextValue, PopoverGroup, type PopoverPlacement, PopoverPopup, type PopoverPopupAtomProps, PopoverPortal, type PopoverPortalAtomProps, PopoverPositioner, type PopoverPositionerAtomProps, type PopoverProps, PopoverProvider, PopoverRoot, type PopoverTrigger, PopoverTriggerElement, type PopoverTriggerElementProps, PopoverViewport, type PopoverViewportAtomProps, type PresetColorKey, type PresetColorType, type PresetSystemColorKey, type PresetSystemColorType, PreviewGroup, type PreviewGroupProps, PrimaryColors, PrimaryColorsObj, type RawModalComponent, type RawModalComponentProps, type RawModalInstance, type RawModalKeyOptions, type RawModalOptions, ScrollArea, ScrollAreaContent, type ScrollAreaContentProps, ScrollAreaCorner, type ScrollAreaCornerProps, type ScrollAreaProps, ScrollAreaRoot, type ScrollAreaRootProps, ScrollAreaScrollbar, type ScrollAreaScrollbarProps, ScrollAreaThumb, type ScrollAreaThumbProps, ScrollAreaViewport, type ScrollAreaViewportProps, ScrollShadow, type ScrollShadowProps, SearchBar, type SearchBarProps, SearchResultCards, type SearchResultCardsProps, Segmented, type SegmentedProps, Select, type SelectProps, _default$1 as ShikiLobeTheme, SideNav, type SideNavProps, Skeleton, SkeletonAvatar, type SkeletonAvatarProps, SkeletonBlock, type SkeletonBlockProps, SkeletonButton, type SkeletonButtonProps, SkeletonParagraph, type SkeletonParagraphProps, type SkeletonProps, SkeletonTags, type SkeletonTagsProps, SkeletonTitle, type SkeletonTitleProps, SliderWithInput, type SliderWithInputProps, Snippet, type SnippetProps, SortableList, type SortableListProps, type SpanProps, type SvgProps, SyntaxHighlighter, type SyntaxHighlighterProps, SyntaxMermaid, type SyntaxMermaidProps, type SystemColorToken, Tabs, type TabsProps, Tag, type TagProps, Text, TextArea, type TextAreaProps, type TextProps, ThemeProvider, type ThemeProviderProps, ThemeSwitch, type ThemeSwitchProps, type ToastAPI, ToastHost, type ToastHostProps, type ToastInstance, type ToastOptions, type ToastPosition, type ToastPromiseOptions, type ToastProps, type ToastType, Toc, type TocProps, Tooltip, TooltipGroup, type TooltipProps, type Trigger, Typography, type TypographyProps, Video, type VideoProps, closeContextMenu, combineKeys, copyToClipboard, createModal, createRawModal, findCustomThemeName, genCdnUrl, generateColorNeutralPalette, generateColorPalette, highlighterThemes, containsScript as htmlPreviewContainsScript, isFullHtmlDocument, isHtmlContentClosed, generateCustomStylish as lobeCustomStylish, generateCustomToken as lobeCustomToken, staticStylish as lobeStaticStylish, styles as menuSharedStyles, mermaidThemes, neutralColors, neutralColorsSwatches, placementMap, preprocessMarkdownContent, preventDefault, preventDefaultAndStopPropagation, primaryColors, primaryColorsSwatches, rehypeCustomFootnotes, rehypeKatexDir, rehypeStreamAnimated, remarkBr, remarkColor, remarkCustomFootnotes, remarkGfmPlus, remarkVideo, renderDropdownMenuItems, setContextMenuInterceptor, showContextMenu, stopPropagation, toFloatingUIPlacement, toast, updateContextMenuItems, useAppElement, useCdnFn, useModalContext, useMotionComponent, usePopoverContext, usePopoverPortalContainer, useToast, useTranslation };
312
+ export { A, type AProps, Accordion, AccordionItem, type AccordionItemProps, type AccordionProps, ActionIcon, ActionIconGroup, type ActionIconGroupEvent, type MenuItemType as ActionIconGroupItemType, type ActionIconGroupProps, type ActionIconProps, type ActionIconSize, Alert, type AlertProps, AutoComplete, type AutoCompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type BaseMenuItemType, Block, type BlockProps, Burger, type BurgerProps, Button, type ButtonProps, type CDN, CLASSNAMES, Center, type CenterProps, Checkbox, CheckboxGroup, type CheckboxGroupOption, type CheckboxGroupProps, type CheckboxProps, CodeDiff, type CodeDiffProps, CodeEditor, type CodeEditorProps, Collapse, type CollapseItemType, type CollapseProps, type ColorPalettes, type ColorPalettesAlpha, ColorSwatches, type ColorSwatchesProps, type ColorToken, type Config, ConfigProvider, type ContextMenuCheckboxItem, ContextMenuHost, type ContextMenuInterceptor, type ContextMenuItem, ContextMenuTrigger, CopyButton, type CopyButtonProps, DatePicker, type DatePickerProps, type DiffViewMode, type DivProps, DownloadButton, type DownloadButtonProps, DraggablePanel, DraggablePanelBody, type DraggablePanelBodyProps, DraggablePanelContainer, type DraggablePanelContainerProps, DraggablePanelFooter, type DraggablePanelFooterProps, DraggablePanelHeader, type DraggablePanelHeaderProps, type DraggablePanelProps, DraggableSideNav, type DraggableSideNavProps, Drawer, type DrawerProps, Dropdown, type DropdownItem, DropdownMenu, type DropdownMenuCheckboxItem, DropdownMenuCheckboxItemIndicator, DropdownMenuCheckboxItemPrimitive, DropdownMenuFooter, type DropdownMenuFooterProps, DropdownMenuGroup, DropdownMenuGroupLabel, type DropdownMenuGroupLabelProps, DropdownMenuHeader, type DropdownMenuHeaderProps, DropdownMenuItem, DropdownMenuItemContent, type DropdownMenuItemContentProps, DropdownMenuItemExtra, type DropdownMenuItemExtraProps, DropdownMenuItemIcon, type DropdownMenuItemIconProps, DropdownMenuItemLabel, type DropdownMenuItemLabelProps, type DropdownMenuItemProps, type MenuItemType as DropdownMenuItemType, type DropdownMenuPlacement, DropdownMenuPopup, type DropdownMenuPopupProps, DropdownMenuPortal, type DropdownMenuPortalProps, DropdownMenuPositioner, type DropdownMenuPositionerProps, type DropdownMenuProps, DropdownMenuRoot, DropdownMenuScrollViewport, type DropdownMenuScrollViewportProps, DropdownMenuSeparator, type DropdownMenuSeparatorProps, DropdownMenuSubmenuArrow, type DropdownMenuSubmenuArrowProps, DropdownMenuSubmenuRoot, DropdownMenuSubmenuTrigger, type DropdownMenuSubmenuTriggerProps, DropdownMenuTrigger, type DropdownMenuTriggerProps, type DropdownProps, EditableText, type EditableTextProps, EditorSlashMenu, type EditorSlashMenuGroup, type EditorSlashMenuItems, type EditorSlashMenuOption, EmojiPicker, type EmojiPickerProps, Empty, type EmptyProps, ErrorBoundary, type ErrorBoundaryProps, FileTypeIcon, type FileTypeIconProps, _default as FlexBasic, type FlexBasicProps, _default as Flexbox, type FlexboxProps, FluentEmoji, type FluentEmojiProps, FontLoader, type FontLoaderProps, Footer, type FooterProps, Form, FormGroup, type FormGroupItemType, type FormGroupProps, type FormInstance, FormItem, type FormItemProps, FormModal, type FormModalProps, type FormProps, FormSubmitFooter, type FormSubmitFooterProps, FormTitle, type FormTitleProps, Freeze, type FreezeProps, type GenericItemType, Grid, type GridProps, GroupAvatar, type GroupAvatarProps, GuideCard, type GuideCardProps, DEFAULT_HEIGHT as HTML_PREVIEW_DEFAULT_HEIGHT, DEFAULT_SANDBOX as HTML_PREVIEW_DEFAULT_SANDBOX, AUTO_HEIGHT_MESSAGE_TYPE as HTML_PREVIEW_RESIZE_MESSAGE, Header, type HeaderProps, Highlighter, type HighlighterProps, Hotkey, HotkeyInput, type HotkeyInputProps, type HotkeyProps, HtmlPreview, HtmlPreviewIframe, type HtmlPreviewIframeProps, type HtmlPreviewMode, type HtmlPreviewProps, type HtmlPreviewStreamingMode, I18nProvider, type I18nProviderProps, Icon, type IconProps, IconProvider, type IconSize, Image, type ImagePreviewOptions, type ImageProps, ImageSelect, type ImageSelectItem, type ImageSelectProps, type ImgProps, type ImperativeModalProps, Input, InputNumber, type InputNumberProps, InputOPT, type InputOPTProps, InputPassword, type InputPasswordProps, type InputProps, type ItemType, KeyMapEnum, LOBE_THEME_APP_ID, Layout, LayoutFooter, type LayoutFooterProps, LayoutHeader, type LayoutHeaderProps, LayoutMain, type LayoutMainProps, type LayoutProps, LayoutSidebar, LayoutSidebarInner, type LayoutSidebarInnerProps, type LayoutSidebarProps, LayoutToc, type LayoutTocProps, List, ListItem, type ListItemProps, type ListProps, type LobeCustomStylish, type LobeCustomToken, I18nProvider as LobeUIProvider, Markdown, type MarkdownProps, MaskShadow, type MaskShadowProps, MaterialFileTypeIcon, type MaterialFileTypeIconProps, Menu, type MenuCheckboxItemType, type MenuInfo, type MenuItemType, type MenuProps, Mermaid, type MermaidProps, Meta, type MetaProps, Modal, ModalHost, type ModalHostProps, type ModalInstance, type ModalProps, ModalProvider, MotionComponent, type MotionComponentType, MotionProvider, NeuralNetworkLoading, type NeuralNetworkLoadingProps, NeutralColors, NeutralColorsObj, PatchDiff, type PatchDiffProps, type Placement, type PlacementConfig, Popover, PopoverArrow, type PopoverArrowAtomProps, PopoverArrowIcon, PopoverBackdrop, type PopoverContextValue, PopoverGroup, type PopoverPlacement, PopoverPopup, type PopoverPopupAtomProps, PopoverPortal, type PopoverPortalAtomProps, PopoverPositioner, type PopoverPositionerAtomProps, type PopoverProps, PopoverProvider, PopoverRoot, type PopoverTrigger, PopoverTriggerElement, type PopoverTriggerElementProps, PopoverViewport, type PopoverViewportAtomProps, type PresetColorKey, type PresetColorType, type PresetSystemColorKey, type PresetSystemColorType, PreviewGroup, type PreviewGroupProps, PrimaryColors, PrimaryColorsObj, type RawModalComponent, type RawModalComponentProps, type RawModalInstance, type RawModalKeyOptions, type RawModalOptions, ScrollArea, ScrollAreaContent, type ScrollAreaContentProps, ScrollAreaCorner, type ScrollAreaCornerProps, type ScrollAreaProps, ScrollAreaRoot, type ScrollAreaRootProps, ScrollAreaScrollbar, type ScrollAreaScrollbarProps, ScrollAreaThumb, type ScrollAreaThumbProps, ScrollAreaViewport, type ScrollAreaViewportProps, ScrollShadow, type ScrollShadowProps, SearchBar, type SearchBarProps, SearchResultCards, type SearchResultCardsProps, Segmented, type SegmentedProps, Select, type SelectProps, _default$1 as ShikiLobeTheme, SideNav, type SideNavProps, Skeleton, SkeletonAvatar, type SkeletonAvatarProps, SkeletonBlock, type SkeletonBlockProps, SkeletonButton, type SkeletonButtonProps, SkeletonParagraph, type SkeletonParagraphProps, type SkeletonProps, SkeletonTags, type SkeletonTagsProps, SkeletonTitle, type SkeletonTitleProps, SliderWithInput, type SliderWithInputProps, Snippet, type SnippetProps, SortableList, type SortableListProps, type SpanProps, type SvgProps, SyntaxHighlighter, type SyntaxHighlighterProps, SyntaxMermaid, type SyntaxMermaidProps, type SystemColorToken, Tabs, type TabsProps, Tag, type TagProps, Text, TextArea, type TextAreaProps, type TextProps, ThemeProvider, type ThemeProviderProps, ThemeSwitch, type ThemeSwitchProps, type ToastAPI, ToastHost, type ToastHostProps, type ToastInstance, type ToastOptions, type ToastPosition, type ToastPromiseOptions, type ToastProps, type ToastType, Toc, type TocProps, Tooltip, TooltipGroup, type TooltipProps, type Trigger, Typography, type TypographyProps, Video, type VideoProps, closeContextMenu, combineKeys, copyToClipboard, createModal, createRawModal, findCustomThemeName, genCdnUrl, generateColorNeutralPalette, generateColorPalette, highlighterThemes, containsScript as htmlPreviewContainsScript, isFullHtmlDocument, isHtmlContentClosed, generateCustomStylish as lobeCustomStylish, generateCustomToken as lobeCustomToken, staticStylish as lobeStaticStylish, styles as menuSharedStyles, mermaidThemes, neutralColors, neutralColorsSwatches, placementMap, preprocessMarkdownContent, preventDefault, preventDefaultAndStopPropagation, primaryColors, primaryColorsSwatches, rehypeCustomFootnotes, rehypeKatexDir, rehypeStreamAnimated, remarkBr, remarkColor, remarkCustomFootnotes, remarkGfmPlus, remarkVideo, renderDropdownMenuItems, setContextMenuInterceptor, showContextMenu, stopPropagation, toFloatingUIPlacement, toast, updateContextMenuItems, useAppElement, useCdnFn, useModalContext, useMotionComponent, usePopoverContext, usePopoverPortalContainer, useToast, useTranslation };
@@ -1,4 +1,4 @@
1
- import { MDXComponents } from "../../node_modules/.bun/@types_mdx@2.0.14/node_modules/@types/mdx/types.mjs";
1
+ import { MDXComponents } from "../../node_modules/.pnpm/@types_mdx@2.0.14/node_modules/@types/mdx/types.mjs";
2
2
  //#region src/mdx/mdxComponents/index.d.ts
3
3
  declare const mdxComponents: MDXComponents;
4
4
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { Data as Data$1, Node as Node$1 } from "../../../../@types_unist@3.0.3/node_modules/@types/unist/index.mjs";
2
- //#region node_modules/.bun/@types+hast@3.0.5/node_modules/@types/hast/index.d.ts
2
+ //#region node_modules/.pnpm/@types+hast@3.0.5/node_modules/@types/hast/index.d.ts
3
3
  // ## Interfaces
4
4
  /**
5
5
  * Info associated with hast nodes by the ecosystem.
@@ -1,4 +1,4 @@
1
- //#region node_modules/.bun/@types+mdx@2.0.14/node_modules/@types/mdx/types.d.ts
1
+ //#region node_modules/.pnpm/@types+mdx@2.0.14/node_modules/@types/mdx/types.d.ts
2
2
  // Internal helper types
3
3
  /**
4
4
  * This is the global JSX.ElementType if it’s defined, otherwise never.
@@ -1,4 +1,4 @@
1
- //#region node_modules/.bun/@types+unist@3.0.3/node_modules/@types/unist/index.d.ts
1
+ //#region node_modules/.pnpm/@types+unist@3.0.3/node_modules/@types/unist/index.d.ts
2
2
  // ## Interfaces
3
3
  /**
4
4
  * Info associated with nodes by the ecosystem.
@@ -1,4 +1,4 @@
1
- //#region node_modules/.bun/unist-util-is@6.0.1/node_modules/unist-util-is/lib/index.js
1
+ //#region node_modules/.pnpm/unist-util-is@6.0.1/node_modules/unist-util-is/lib/index.js
2
2
  /**
3
3
  * Generate an assertion from a test.
4
4
  *