@lobehub/ui 5.24.0 → 5.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/es/A/index.mjs +2 -1
  2. package/es/A/index.mjs.map +1 -1
  3. package/es/Accordion/AccordionItem.mjs +0 -1
  4. package/es/Accordion/AccordionItem.mjs.map +1 -1
  5. package/es/ActionIcon/components/utils.mjs +7 -9
  6. package/es/ActionIcon/components/utils.mjs.map +1 -1
  7. package/es/Checkbox/CheckboxGroup.mjs +4 -2
  8. package/es/Checkbox/CheckboxGroup.mjs.map +1 -1
  9. package/es/CodeDiff/CodeDiff.mjs +20 -18
  10. package/es/CodeDiff/CodeDiff.mjs.map +1 -1
  11. package/es/CodeDiff/PatchDiff.mjs +18 -16
  12. package/es/CodeDiff/PatchDiff.mjs.map +1 -1
  13. package/es/CopyButton/CopyButton.mjs +2 -1
  14. package/es/CopyButton/CopyButton.mjs.map +1 -1
  15. package/es/Highlighter/LangSelect.mjs +41 -40
  16. package/es/Highlighter/LangSelect.mjs.map +1 -1
  17. package/es/Highlighter/SyntaxHighlighter/StaticRenderer.mjs +2 -1
  18. package/es/Highlighter/SyntaxHighlighter/StaticRenderer.mjs.map +1 -1
  19. package/es/HotkeyInput/HotkeyInput.mjs +3 -1
  20. package/es/HotkeyInput/HotkeyInput.mjs.map +1 -1
  21. package/es/HtmlPreview/const.mjs +1 -1
  22. package/es/HtmlPreview/const.mjs.map +1 -1
  23. package/es/Icon/components/utils.mjs +7 -9
  24. package/es/Icon/components/utils.mjs.map +1 -1
  25. package/es/Image/Image.mjs +138 -37
  26. package/es/Image/Image.mjs.map +1 -1
  27. package/es/Image/PreviewGroup.d.mts +1 -0
  28. package/es/Image/PreviewGroup.mjs +33 -10
  29. package/es/Image/PreviewGroup.mjs.map +1 -1
  30. package/es/Image/index.d.mts +2 -2
  31. package/es/Image/index.mjs +1 -1
  32. package/es/Image/style.mjs +126 -71
  33. package/es/Image/style.mjs.map +1 -1
  34. package/es/Image/type.d.mts +14 -17
  35. package/es/Image/viewer/GalleryNav.mjs +44 -0
  36. package/es/Image/viewer/GalleryNav.mjs.map +1 -0
  37. package/es/Image/viewer/ImageViewer.mjs +275 -0
  38. package/es/Image/viewer/ImageViewer.mjs.map +1 -0
  39. package/es/Image/viewer/PreviewOutlet.mjs +19 -0
  40. package/es/Image/viewer/PreviewOutlet.mjs.map +1 -0
  41. package/es/Image/viewer/Toolbar.mjs +184 -0
  42. package/es/Image/viewer/Toolbar.mjs.map +1 -0
  43. package/es/Image/viewer/ViewerChrome.mjs +54 -0
  44. package/es/Image/viewer/ViewerChrome.mjs.map +1 -0
  45. package/es/Image/viewer/geometry.mjs +85 -0
  46. package/es/Image/viewer/geometry.mjs.map +1 -0
  47. package/es/Image/viewer/registry.d.mts +2 -0
  48. package/es/Image/viewer/registry.mjs +52 -0
  49. package/es/Image/viewer/registry.mjs.map +1 -0
  50. package/es/Image/viewer/useChromeIdle.mjs +72 -0
  51. package/es/Image/viewer/useChromeIdle.mjs.map +1 -0
  52. package/es/Image/viewer/useFinalFocus.mjs +10 -0
  53. package/es/Image/viewer/useFinalFocus.mjs.map +1 -0
  54. package/es/Image/viewer/useFlipTransition.mjs +321 -0
  55. package/es/Image/viewer/useFlipTransition.mjs.map +1 -0
  56. package/es/Image/viewer/useGalleryNav.mjs +89 -0
  57. package/es/Image/viewer/useGalleryNav.mjs.map +1 -0
  58. package/es/Image/viewer/useRefitTransition.mjs +47 -0
  59. package/es/Image/viewer/useRefitTransition.mjs.map +1 -0
  60. package/es/Image/viewer/useViewerGestures.mjs +148 -0
  61. package/es/Image/viewer/useViewerGestures.mjs.map +1 -0
  62. package/es/Image/viewer/useZoomPan.mjs +346 -0
  63. package/es/Image/viewer/useZoomPan.mjs.map +1 -0
  64. package/es/Img/index.mjs +2 -1
  65. package/es/Img/index.mjs.map +1 -1
  66. package/es/Markdown/SyntaxMarkdown/StreamdownRender.mjs +2 -1
  67. package/es/Markdown/SyntaxMarkdown/StreamdownRender.mjs.map +1 -1
  68. package/es/Markdown/SyntaxMarkdown/useSmoothStreamContent.mjs +2 -2
  69. package/es/Markdown/SyntaxMarkdown/useSmoothStreamContent.mjs.map +1 -1
  70. package/es/Modal/RawModalStackItem.mjs +6 -5
  71. package/es/Modal/RawModalStackItem.mjs.map +1 -1
  72. package/es/Modal/imperative.mjs +4 -2
  73. package/es/Modal/imperative.mjs.map +1 -1
  74. package/es/NeuralNetworkLoading/NeuralNetworkLoading.mjs +1 -1
  75. package/es/NeuralNetworkLoading/NeuralNetworkLoading.mjs.map +1 -1
  76. package/es/ScrollShadow/ScrollShadow.mjs +13 -12
  77. package/es/ScrollShadow/ScrollShadow.mjs.map +1 -1
  78. package/es/Skeleton/SkeletonButton.mjs +2 -1
  79. package/es/Skeleton/SkeletonButton.mjs.map +1 -1
  80. package/es/SortableList/SortableList.mjs +5 -1
  81. package/es/SortableList/SortableList.mjs.map +1 -1
  82. package/es/Text/Text.mjs +22 -21
  83. package/es/Text/Text.mjs.map +1 -1
  84. package/es/ThemeProvider/ThemeProvider.mjs +3 -2
  85. package/es/ThemeProvider/ThemeProvider.mjs.map +1 -1
  86. package/es/awesome/GradientButton/GradientButton.mjs +1 -3
  87. package/es/awesome/GradientButton/GradientButton.mjs.map +1 -1
  88. package/es/awesome/Spotlight/Spotlight.mjs +2 -1
  89. package/es/awesome/Spotlight/Spotlight.mjs.map +1 -1
  90. package/es/base-ui/Button/Button.mjs +13 -11
  91. package/es/base-ui/Button/Button.mjs.map +1 -1
  92. package/es/base-ui/Button/SplitButton.mjs +2 -1
  93. package/es/base-ui/Button/SplitButton.mjs.map +1 -1
  94. package/es/base-ui/ContextMenu/ContextMenuTrigger.mjs +2 -1
  95. package/es/base-ui/ContextMenu/ContextMenuTrigger.mjs.map +1 -1
  96. package/es/base-ui/ContextMenu/renderItems.mjs +2 -1
  97. package/es/base-ui/ContextMenu/renderItems.mjs.map +1 -1
  98. package/es/base-ui/Drawer/Drawer.d.mts +6 -0
  99. package/es/base-ui/Drawer/Drawer.mjs +152 -0
  100. package/es/base-ui/Drawer/Drawer.mjs.map +1 -0
  101. package/es/base-ui/Drawer/DrawerLayerContext.mjs +10 -0
  102. package/es/base-ui/Drawer/DrawerLayerContext.mjs.map +1 -0
  103. package/es/base-ui/Drawer/DrawerPushContext.mjs +27 -0
  104. package/es/base-ui/Drawer/DrawerPushContext.mjs.map +1 -0
  105. package/es/base-ui/Drawer/atoms.d.mts +58 -0
  106. package/es/base-ui/Drawer/atoms.mjs +262 -0
  107. package/es/base-ui/Drawer/atoms.mjs.map +1 -0
  108. package/es/base-ui/Drawer/constants.d.mts +17 -0
  109. package/es/base-ui/Drawer/constants.mjs +72 -0
  110. package/es/base-ui/Drawer/constants.mjs.map +1 -0
  111. package/es/base-ui/Drawer/index.d.mts +5 -0
  112. package/es/base-ui/Drawer/style.mjs +295 -0
  113. package/es/base-ui/Drawer/style.mjs.map +1 -0
  114. package/es/base-ui/Drawer/type.d.mts +65 -0
  115. package/es/base-ui/DropdownMenu/DropdownMenu.mjs +2 -1
  116. package/es/base-ui/DropdownMenu/DropdownMenu.mjs.map +1 -1
  117. package/es/base-ui/DropdownMenu/atoms.mjs +2 -1
  118. package/es/base-ui/DropdownMenu/atoms.mjs.map +1 -1
  119. package/es/base-ui/DropdownMenu/renderItems.mjs +2 -1
  120. package/es/base-ui/DropdownMenu/renderItems.mjs.map +1 -1
  121. package/es/base-ui/FloatingSheet/FloatingSheet.mjs +4 -1
  122. package/es/base-ui/FloatingSheet/FloatingSheet.mjs.map +1 -1
  123. package/es/base-ui/Input/style.d.mts +1 -1
  124. package/es/base-ui/Modal/atoms.mjs +7 -5
  125. package/es/base-ui/Modal/atoms.mjs.map +1 -1
  126. package/es/base-ui/Modal/imperative.mjs +2 -1
  127. package/es/base-ui/Modal/imperative.mjs.map +1 -1
  128. package/es/base-ui/Popover/atoms.mjs +2 -1
  129. package/es/base-ui/Popover/atoms.mjs.map +1 -1
  130. package/es/base-ui/Popover/context.mjs +4 -2
  131. package/es/base-ui/Popover/context.mjs.map +1 -1
  132. package/es/base-ui/Select/atoms.mjs +2 -1
  133. package/es/base-ui/Select/atoms.mjs.map +1 -1
  134. package/es/base-ui/Toast/hostGuard.mjs +26 -0
  135. package/es/base-ui/Toast/hostGuard.mjs.map +1 -0
  136. package/es/base-ui/Toast/imperative.mjs +43 -20
  137. package/es/base-ui/Toast/imperative.mjs.map +1 -1
  138. package/es/base-ui/Toast/pendingQueue.mjs +30 -0
  139. package/es/base-ui/Toast/pendingQueue.mjs.map +1 -0
  140. package/es/base-ui/index.d.mts +6 -1
  141. package/es/base-ui/index.mjs +5 -2
  142. package/es/brand/LobeChat/index.mjs +0 -1
  143. package/es/brand/LobeChat/index.mjs.map +1 -1
  144. package/es/brand/LobeHub/index.mjs +0 -1
  145. package/es/brand/LobeHub/index.mjs.map +1 -1
  146. package/es/brand/Logo3d/index.mjs +2 -1
  147. package/es/brand/Logo3d/index.mjs.map +1 -1
  148. package/es/chat/ChatItem/components/Actions.mjs +5 -4
  149. package/es/chat/ChatItem/components/Actions.mjs.map +1 -1
  150. package/es/chat/ChatList/ChatList.mjs +2 -1
  151. package/es/chat/ChatList/ChatList.mjs.map +1 -1
  152. package/es/color/ColorScales/ScaleRow.mjs +0 -2
  153. package/es/color/ColorScales/ScaleRow.mjs.map +1 -1
  154. package/es/hooks/useMermaid.mjs +2 -1
  155. package/es/hooks/useMermaid.mjs.map +1 -1
  156. package/es/i18n/resources/en/image.d.mts +5 -0
  157. package/es/i18n/resources/en/image.mjs +6 -1
  158. package/es/i18n/resources/en/image.mjs.map +1 -1
  159. package/es/i18n/resources/zhCn/image.d.mts +5 -0
  160. package/es/i18n/resources/zhCn/image.mjs +6 -1
  161. package/es/i18n/resources/zhCn/image.mjs.map +1 -1
  162. package/es/index.mjs +8 -8
  163. package/package.json +1 -1
  164. package/es/Image/components/Preview.mjs +0 -23
  165. package/es/Image/components/Preview.mjs.map +0 -1
  166. package/es/Image/components/Toolbar.mjs +0 -128
  167. package/es/Image/components/Toolbar.mjs.map +0 -1
  168. package/es/Image/components/usePreview.mjs +0 -58
  169. package/es/Image/components/usePreview.mjs.map +0 -1
  170. package/es/Image/components/usePreviewGroup.mjs +0 -57
  171. package/es/Image/components/usePreviewGroup.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"style.mjs","names":["lobeStaticStylish"],"sources":["../../src/Image/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\nimport { cva } from 'class-variance-authority';\n\nimport { lobeStaticStylish } from '@/styles';\n\nconst prefixCls = 'ant';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => {\n return {\n actionsHidden: css`\n cursor: pointer;\n\n position: absolute;\n z-index: 1;\n inset-block-start: 0;\n inset-inline-end: 0;\n\n opacity: 0;\n `,\n actionsVisible: css`\n cursor: pointer;\n\n position: absolute;\n z-index: 1;\n inset-block-start: 0;\n inset-inline-end: 0;\n\n opacity: 1;\n `,\n borderless: lobeStaticStylish.variantBorderlessWithoutHover,\n filled: css`\n ${lobeStaticStylish.variantOutlinedWithoutHover};\n ${lobeStaticStylish.variantFilledWithoutHover};\n `,\n image: css`\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: auto;\n height: auto;\n `,\n mask: css`\n ${lobeStaticStylish.blur};\n backdrop-filter: blur(8px);\n `,\n outlined: lobeStaticStylish.variantOutlinedWithoutHover,\n preview: css`\n .${prefixCls}-image-preview-mask {\n background: color-mix(in srgb, ${cssVar.colorBgLayout} 90%, transparent);\n }\n\n .${prefixCls}-image-preview-close {\n color: ${cssVar.colorTextDescription};\n background: ${cssVar.colorBgContainer};\n box-shadow: ${cssVar.boxShadowTertiary};\n\n svg {\n stroke: ${cssVar.colorTextDescription};\n }\n\n &:hover {\n color: ${cssVar.colorText};\n background: ${cssVar.colorBgContainer};\n\n svg {\n stroke: ${cssVar.colorText};\n }\n }\n }\n\n .${prefixCls}-image-preview-img {\n width: 100%;\n }\n\n .${prefixCls}-image-preview-switch {\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 32px;\n height: 32px;\n padding: 0;\n\n color: ${cssVar.colorTextDescription};\n\n background: ${cssVar.colorBgContainer};\n box-shadow: ${cssVar.boxShadowTertiary};\n\n svg {\n transform: scale(0.75);\n }\n\n &:hover {\n color: ${cssVar.colorText};\n background: ${cssVar.colorBgContainer};\n }\n }\n\n .${prefixCls}-image-preview-switch-disabled {\n display: none;\n }\n\n .ant-image-preview-progress {\n color: ${cssVar.colorTextDescription};\n }\n\n img {\n min-width: 100%;\n }\n `,\n root: css`\n cursor: pointer;\n user-select: none;\n\n position: relative;\n\n overflow: hidden;\n\n width: fit-content;\n border-radius: ${cssVar.borderRadius};\n\n line-height: 1;\n\n .${prefixCls}-image-cover {\n display: none !important;\n }\n\n &:hover {\n .actions-hidden {\n opacity: 1;\n }\n }\n `,\n toolbar: css`\n ${lobeStaticStylish.variantOutlinedWithoutHover};\n padding: 4px;\n border-color: ${cssVar.colorFillTertiary};\n border-radius: ${cssVar.borderRadiusLG};\n `,\n\n wrapper: css`\n position: relative;\n overflow: hidden;\n max-width: 100%;\n height: auto;\n `,\n };\n});\n\nexport const variants = cva(styles.root, {\n defaultVariants: {\n variant: 'filled',\n },\n\n variants: {\n variant: {\n filled: styles.filled,\n outlined: styles.outlined,\n borderless: styles.borderless,\n },\n },\n});\n\nexport const FALLBACK_DARK =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjU2IiBoZWlnaHQ9IjI1NiIgdmlld0JveD0iMCAwIDI1NiAyNTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyNTYiIGhlaWdodD0iMjU2IiBmaWxsPSIjM0IzQjNCIi8+CjxwYXRoIGQ9Ik0xNTYuODg4IDkxLjAwMkgxMDAuMTEyQzk1LjYzMjkgOTEuMDAyIDkyLjAwMTUgOTQuNjMzNCA5Mi4wMDE1IDk5LjExMjdWMTU1Ljg4OEM5Mi4wMDE1IDE2MC4zNjcgOTUuNjMyOSAxNjMuOTk5IDEwMC4xMTIgMTYzLjk5OUgxNTYuODg4QzE2MS4zNjcgMTYzLjk5OSAxNjQuOTk4IDE2MC4zNjcgMTY0Ljk5OCAxNTUuODg4Vjk5LjExMjdDMTY0Ljk5OCA5NC42MzM0IDE2MS4zNjcgOTEuMDAyIDE1Ni44ODggOTEuMDAyWiIgc3Ryb2tlPSIjNjI2MjYyIiBzdHJva2Utd2lkdGg9IjguMTEwNzciIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMTY0Ljk5OCAxMzkuNjY4TDE1Mi40ODQgMTI3LjE1M0MxNTAuOTYyIDEyNS42MzIgMTQ4LjkgMTI0Ljc3OCAxNDYuNzQ5IDEyNC43NzhDMTQ0LjU5OSAxMjQuNzc4IDE0Mi41MzYgMTI1LjYzMiAxNDEuMDE1IDEyNy4xNTNMMTA0LjE2OCAxNjRNMTE2LjMzNCAxMjMuNDQ1QzEyMC44MTMgMTIzLjQ0NSAxMjQuNDQ1IDExOS44MTQgMTI0LjQ0NSAxMTUuMzM0QzEyNC40NDUgMTEwLjg1NSAxMjAuODEzIDEwNy4yMjQgMTE2LjMzNCAxMDcuMjI0QzExMS44NTUgMTA3LjIyNCAxMDguMjIzIDExMC44NTUgMTA4LjIyMyAxMTUuMzM0QzEwOC4yMjMgMTE5LjgxNCAxMTEuODU1IDEyMy40NDUgMTE2LjMzNCAxMjMuNDQ1WiIgc3Ryb2tlPSIjNjI2MjYyIiBzdHJva2Utd2lkdGg9IjguMTEwNzciIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8L3N2Zz4K';\nexport const FALLBACK_LIGHT =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjU2IiBoZWlnaHQ9IjI1NiIgdmlld0JveD0iMCAwIDI1NiAyNTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyNTYiIGhlaWdodD0iMjU2IiBmaWxsPSIjRUNFQ0VDIi8+CjxwYXRoIGQ9Ik0xNTYuODg4IDkxLjAwMkgxMDAuMTEyQzk1LjYzMjkgOTEuMDAyIDkyLjAwMTUgOTQuNjMzNCA5Mi4wMDE1IDk5LjExMjdWMTU1Ljg4OEM5Mi4wMDE1IDE2MC4zNjcgOTUuNjMyOSAxNjMuOTk5IDEwMC4xMTIgMTYzLjk5OUgxNTYuODg4QzE2MS4zNjcgMTYzLjk5OSAxNjQuOTk4IDE2MC4zNjcgMTY0Ljk5OCAxNTUuODg4Vjk5LjExMjdDMTY0Ljk5OCA5NC42MzM0IDE2MS4zNjcgOTEuMDAyIDE1Ni44ODggOTEuMDAyWiIgc3Ryb2tlPSIjRDdEN0Q3IiBzdHJva2Utd2lkdGg9IjguMTEwNzciIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMTY0Ljk5OCAxMzkuNjY4TDE1Mi40ODQgMTI3LjE1M0MxNTAuOTYyIDEyNS42MzIgMTQ4LjkgMTI0Ljc3OCAxNDYuNzQ5IDEyNC43NzhDMTQ0LjU5OSAxMjQuNzc4IDE0Mi41MzYgMTI1LjYzMiAxNDEuMDE1IDEyNy4xNTNMMTA0LjE2OCAxNjRNMTE2LjMzNCAxMjMuNDQ1QzEyMC44MTMgMTIzLjQ0NSAxMjQuNDQ1IDExOS44MTQgMTI0LjQ0NSAxMTUuMzM0QzEyNC40NDUgMTEwLjg1NSAxMjAuODEzIDEwNy4yMjQgMTE2LjMzNCAxMDcuMjI0QzExMS44NTUgMTA3LjIyNCAxMDguMjIzIDExMC44NTUgMTA4LjIyMyAxMTUuMzM0QzEwOC4yMjMgMTE5LjgxNCAxMTEuODU1IDEyMy40NDUgMTE2LjMzNCAxMjMuNDQ1WiIgc3Ryb2tlPSIjRDdEN0Q3IiBzdHJva2Utd2lkdGg9IjguMTEwNzciIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8L3N2Zz4K';\n"],"mappings":";;;;AAKA,MAAM,YAAY;AAElB,MAAa,SAAS,oBAAoB,EAAE,KAAK,aAAa;CAC5D,OAAO;EACL,eAAe,GAAG;;;;;;;;;;EAUlB,gBAAgB,GAAG;;;;;;;;;;EAUnB,YAAYA,cAAkB;EAC9B,QAAQ,GAAG;QACPA,cAAkB,4BAA4B;QAC9CA,cAAkB,0BAA0B;;EAEhD,OAAO,GAAG;;;;;;;;EAQV,MAAM,GAAG;QACLA,cAAkB,KAAK;;;EAG3B,UAAUA,cAAkB;EAC5B,SAAS,GAAG;SACP,UAAU;yCACsB,OAAO,cAAc;;;SAGrD,UAAU;iBACF,OAAO,qBAAqB;sBACvB,OAAO,iBAAiB;sBACxB,OAAO,kBAAkB;;;oBAG3B,OAAO,qBAAqB;;;;mBAI7B,OAAO,UAAU;wBACZ,OAAO,iBAAiB;;;sBAG1B,OAAO,UAAU;;;;;SAK9B,UAAU;;;;SAIV,UAAU;;;;;;;;;iBASF,OAAO,qBAAqB;;sBAEvB,OAAO,iBAAiB;sBACxB,OAAO,kBAAkB;;;;;;;mBAO5B,OAAO,UAAU;wBACZ,OAAO,iBAAiB;;;;SAIvC,UAAU;;;;;iBAKF,OAAO,qBAAqB;;;;;;;EAOzC,MAAM,GAAG;;;;;;;;;uBASU,OAAO,aAAa;;;;SAIlC,UAAU;;;;;;;;;;EAUf,SAAS,GAAG;QACRA,cAAkB,4BAA4B;;sBAEhC,OAAO,kBAAkB;uBACxB,OAAO,eAAe;;EAGzC,SAAS,GAAG;;;;;;CAMd;AACF,CAAC;AAED,MAAa,WAAW,IAAI,OAAO,MAAM;CACvC,iBAAiB,EACf,SAAS,SACX;CAEA,UAAU,EACR,SAAS;EACP,QAAQ,OAAO;EACf,UAAU,OAAO;EACjB,YAAY,OAAO;CACrB,EACF;AACF,CAAC;AAED,MAAa,gBACX;AACF,MAAa,iBACX"}
1
+ {"version":3,"file":"style.mjs","names":["lobeStaticStylish"],"sources":["../../src/Image/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\nimport { cva } from 'class-variance-authority';\n\nimport { lobeStaticStylish } from '@/styles';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => {\n // Bare viewer controls float directly over arbitrary image content; the\n // theme-side halo (light halo around dark icons in light mode and vice\n // versa) is what keeps them readable without a container panel.\n const controlHalo = `drop-shadow(0 0 2px ${cssVar.colorBgLayout}) drop-shadow(0 1px 6px ${cssVar.colorBgLayout})`;\n return {\n actionsHidden: css`\n cursor: pointer;\n\n position: absolute;\n z-index: 1;\n inset-block-start: 0;\n inset-inline-end: 0;\n\n opacity: 0;\n `,\n actionsVisible: css`\n cursor: pointer;\n\n position: absolute;\n z-index: 1;\n inset-block-start: 0;\n inset-inline-end: 0;\n\n opacity: 1;\n `,\n borderless: lobeStaticStylish.variantBorderlessWithoutHover,\n filled: css`\n ${lobeStaticStylish.variantOutlinedWithoutHover};\n ${lobeStaticStylish.variantFilledWithoutHover};\n `,\n image: css`\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: auto;\n height: auto;\n `,\n outlined: lobeStaticStylish.variantOutlinedWithoutHover,\n previewable: css`\n cursor: zoom-in;\n `,\n root: css`\n cursor: pointer;\n user-select: none;\n\n position: relative;\n\n overflow: hidden;\n\n width: fit-content;\n border-radius: ${cssVar.borderRadius};\n\n line-height: 1;\n\n &:hover {\n .actions-hidden {\n opacity: 1;\n }\n }\n `,\n toolbar: css`\n pointer-events: auto;\n\n position: absolute;\n inset-block-end: 16px;\n inset-inline-start: 50%;\n transform: translateX(-50%);\n `,\n // The glass lives on the icon row, not the toolbar itself: tooltips and\n // the more-menu portal into the toolbar element, and an ancestor\n // backdrop-filter/filter would distort those popups too.\n toolbarRow: css`\n padding-block: 4px;\n padding-inline: 6px;\n border-radius: 999px;\n\n background: color-mix(in srgb, ${cssVar.colorBgLayout} 60%, transparent);\n backdrop-filter: blur(12px);\n `,\n toolbarPercentage: css`\n cursor: pointer;\n user-select: none;\n\n min-width: 44px;\n height: 36px;\n padding-inline: 8px;\n border-radius: 999px;\n\n font-size: 12px;\n font-variant-numeric: tabular-nums;\n color: ${cssVar.colorTextTertiary};\n\n transition:\n color 400ms ${cssVar.motionEaseOut},\n background 100ms ${cssVar.motionEaseOut};\n\n &:hover {\n color: ${cssVar.colorTextSecondary};\n background: ${cssVar.colorFillTertiary};\n }\n `,\n\n viewerBackdrop: css`\n position: fixed;\n inset: 0;\n\n opacity: 0;\n background: color-mix(in srgb, ${cssVar.colorBgLayout} 90%, transparent);\n backdrop-filter: blur(8px);\n `,\n viewerChrome: css`\n pointer-events: none;\n position: absolute;\n inset: 0;\n opacity: 0;\n `,\n viewerChromeIdle: css`\n pointer-events: none;\n position: absolute;\n inset: 0;\n transition:\n opacity 200ms ${cssVar.motionEaseOut},\n visibility 200ms;\n\n &[data-idle-hidden] {\n visibility: hidden;\n opacity: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n viewerClose: css`\n pointer-events: auto;\n\n position: absolute;\n inset-block-start: 16px;\n inset-inline-end: 16px;\n\n filter: ${controlHalo};\n `,\n viewerCounter: css`\n pointer-events: none;\n\n position: absolute;\n inset-block-start: 16px;\n inset-inline-start: 50%;\n transform: translateX(-50%);\n\n padding-block: 4px;\n padding-inline: 12px;\n border-radius: 999px;\n\n font-size: 12px;\n font-variant-numeric: tabular-nums;\n color: ${cssVar.colorTextSecondary};\n\n background: color-mix(in srgb, ${cssVar.colorBgLayout} 60%, transparent);\n backdrop-filter: blur(12px);\n `,\n viewerImage: css`\n will-change: transform;\n cursor: zoom-out;\n user-select: none;\n\n position: absolute;\n transform-origin: center center;\n\n object-fit: contain;\n\n -webkit-user-drag: none;\n `,\n viewerNavButton: css`\n pointer-events: auto;\n\n position: absolute;\n inset-block-start: 50%;\n transform: translateY(-50%);\n\n filter: ${controlHalo};\n `,\n viewerNavNext: css`\n inset-inline-end: 16px;\n `,\n viewerNavPrev: css`\n inset-inline-start: 16px;\n `,\n viewerPopup: css`\n position: fixed;\n inset: 0;\n overflow: hidden;\n outline: none;\n `,\n wrapper: css`\n position: relative;\n overflow: hidden;\n max-width: 100%;\n height: auto;\n `,\n };\n});\n\nexport const variants = cva(styles.root, {\n defaultVariants: {\n variant: 'filled',\n },\n\n variants: {\n variant: {\n filled: styles.filled,\n outlined: styles.outlined,\n borderless: styles.borderless,\n },\n },\n});\n\nexport const FALLBACK_DARK =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjU2IiBoZWlnaHQ9IjI1NiIgdmlld0JveD0iMCAwIDI1NiAyNTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyNTYiIGhlaWdodD0iMjU2IiBmaWxsPSIjM0IzQjNCIi8+CjxwYXRoIGQ9Ik0xNTYuODg4IDkxLjAwMkgxMDAuMTEyQzk1LjYzMjkgOTEuMDAyIDkyLjAwMTUgOTQuNjMzNCA5Mi4wMDE1IDk5LjExMjdWMTU1Ljg4OEM5Mi4wMDE1IDE2MC4zNjcgOTUuNjMyOSAxNjMuOTk5IDEwMC4xMTIgMTYzLjk5OUgxNTYuODg4QzE2MS4zNjcgMTYzLjk5OSAxNjQuOTk4IDE2MC4zNjcgMTY0Ljk5OCAxNTUuODg4Vjk5LjExMjdDMTY0Ljk5OCA5NC42MzM0IDE2MS4zNjcgOTEuMDAyIDE1Ni44ODggOTEuMDAyWiIgc3Ryb2tlPSIjNjI2MjYyIiBzdHJva2Utd2lkdGg9IjguMTEwNzciIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMTY0Ljk5OCAxMzkuNjY4TDE1Mi40ODQgMTI3LjE1M0MxNTAuOTYyIDEyNS42MzIgMTQ4LjkgMTI0Ljc3OCAxNDYuNzQ5IDEyNC43NzhDMTQ0LjU5OSAxMjQuNzc4IDE0Mi41MzYgMTI1LjYzMiAxNDEuMDE1IDEyNy4xNTNMMTA0LjE2OCAxNjRNMTE2LjMzNCAxMjMuNDQ1QzEyMC44MTMgMTIzLjQ0NSAxMjQuNDQ1IDExOS44MTQgMTI0LjQ0NSAxMTUuMzM0QzEyNC40NDUgMTEwLjg1NSAxMjAuODEzIDEwNy4yMjQgMTE2LjMzNCAxMDcuMjI0QzExMS44NTUgMTA3LjIyNCAxMDguMjIzIDExMC44NTUgMTA4LjIyMyAxMTUuMzM0QzEwOC4yMjMgMTE5LjgxNCAxMTEuODU1IDEyMy40NDUgMTE2LjMzNCAxMjMuNDQ1WiIgc3Ryb2tlPSIjNjI2MjYyIiBzdHJva2Utd2lkdGg9IjguMTEwNzciIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8L3N2Zz4K';\nexport const FALLBACK_LIGHT =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjU2IiBoZWlnaHQ9IjI1NiIgdmlld0JveD0iMCAwIDI1NiAyNTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyNTYiIGhlaWdodD0iMjU2IiBmaWxsPSIjRUNFQ0VDIi8+CjxwYXRoIGQ9Ik0xNTYuODg4IDkxLjAwMkgxMDAuMTEyQzk1LjYzMjkgOTEuMDAyIDkyLjAwMTUgOTQuNjMzNCA5Mi4wMDE1IDk5LjExMjdWMTU1Ljg4OEM5Mi4wMDE1IDE2MC4zNjcgOTUuNjMyOSAxNjMuOTk5IDEwMC4xMTIgMTYzLjk5OUgxNTYuODg4QzE2MS4zNjcgMTYzLjk5OSAxNjQuOTk4IDE2MC4zNjcgMTY0Ljk5OCAxNTUuODg4Vjk5LjExMjdDMTY0Ljk5OCA5NC42MzM0IDE2MS4zNjcgOTEuMDAyIDE1Ni44ODggOTEuMDAyWiIgc3Ryb2tlPSIjRDdEN0Q3IiBzdHJva2Utd2lkdGg9IjguMTEwNzciIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMTY0Ljk5OCAxMzkuNjY4TDE1Mi40ODQgMTI3LjE1M0MxNTAuOTYyIDEyNS42MzIgMTQ4LjkgMTI0Ljc3OCAxNDYuNzQ5IDEyNC43NzhDMTQ0LjU5OSAxMjQuNzc4IDE0Mi41MzYgMTI1LjYzMiAxNDEuMDE1IDEyNy4xNTNMMTA0LjE2OCAxNjRNMTE2LjMzNCAxMjMuNDQ1QzEyMC44MTMgMTIzLjQ0NSAxMjQuNDQ1IDExOS44MTQgMTI0LjQ0NSAxMTUuMzM0QzEyNC40NDUgMTEwLjg1NSAxMjAuODEzIDEwNy4yMjQgMTE2LjMzNCAxMDcuMjI0QzExMS44NTUgMTA3LjIyNCAxMDguMjIzIDExMC44NTUgMTA4LjIyMyAxMTUuMzM0QzEwOC4yMjMgMTE5LjgxNCAxMTEuODU1IDEyMy40NDUgMTE2LjMzNCAxMjMuNDQ1WiIgc3Ryb2tlPSIjRDdEN0Q3IiBzdHJva2Utd2lkdGg9IjguMTEwNzciIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8L3N2Zz4K';\n"],"mappings":";;;;AAKA,MAAa,SAAS,oBAAoB,EAAE,KAAK,aAAa;CAI5D,MAAM,cAAc,uBAAuB,OAAO,cAAc,0BAA0B,OAAO,cAAc;CAC/G,OAAO;EACL,eAAe,GAAG;;;;;;;;;;EAUlB,gBAAgB,GAAG;;;;;;;;;;EAUnB,YAAYA,cAAkB;EAC9B,QAAQ,GAAG;QACPA,cAAkB,4BAA4B;QAC9CA,cAAkB,0BAA0B;;EAEhD,OAAO,GAAG;;;;;;;;EAQV,UAAUA,cAAkB;EAC5B,aAAa,GAAG;;;EAGhB,MAAM,GAAG;;;;;;;;;uBASU,OAAO,aAAa;;;;;;;;;;EAUvC,SAAS,GAAG;;;;;;;;EAWZ,YAAY,GAAG;;;;;uCAKoB,OAAO,cAAc;;;EAGxD,mBAAmB,GAAG;;;;;;;;;;;eAWX,OAAO,kBAAkB;;;sBAGlB,OAAO,cAAc;2BAChB,OAAO,cAAc;;;iBAG/B,OAAO,mBAAmB;sBACrB,OAAO,kBAAkB;;;EAI3C,gBAAgB,GAAG;;;;;uCAKgB,OAAO,cAAc;;;EAGxD,cAAc,GAAG;;;;;;EAMjB,kBAAkB,GAAG;;;;;wBAKD,OAAO,cAAc;;;;;;;;;;;;EAYzC,aAAa,GAAG;;;;;;;gBAOJ,YAAY;;EAExB,eAAe,GAAG;;;;;;;;;;;;;;eAcP,OAAO,mBAAmB;;uCAEF,OAAO,cAAc;;;EAGxD,aAAa,GAAG;;;;;;;;;;;;EAYhB,iBAAiB,GAAG;;;;;;;gBAOR,YAAY;;EAExB,eAAe,GAAG;;;EAGlB,eAAe,GAAG;;;EAGlB,aAAa,GAAG;;;;;;EAMhB,SAAS,GAAG;;;;;;CAMd;AACF,CAAC;AAED,MAAa,WAAW,IAAI,OAAO,MAAM;CACvC,iBAAiB,EACf,SAAS,SACX;CAEA,UAAU,EACR,SAAS;EACP,QAAQ,OAAO;EACf,UAAU,OAAO;EACjB,YAAY,OAAO;CACrB,EACF;AACF,CAAC;AAED,MAAa,gBACX;AACF,MAAa,iBACX"}
@@ -1,27 +1,19 @@
1
- import { CSSProperties, ReactNode, Ref } from "react";
2
- import { ImageProps } from "antd";
3
- import { PreviewConfig } from "antd/es/image/index.js";
4
- import { GroupPreviewConfig } from "antd/es/image/PreviewGroup.js";
1
+ import { CSSProperties, ComponentProps, ReactNode, Ref } from "react";
5
2
  //#region src/Image/type.d.ts
6
- interface PreviewGroupPreviewOptions extends GroupPreviewConfig {
3
+ interface ImagePreviewOptions {
4
+ maxScale?: number;
5
+ onOpenChange?: (open: boolean) => void;
6
+ src?: string;
7
7
  toolbarAddon?: ReactNode;
8
8
  }
9
- interface PreviewGroupProps {
10
- children?: ReactNode;
11
- enable?: boolean;
12
- items?: string[];
13
- preview?: boolean | PreviewGroupPreviewOptions;
14
- }
15
- interface ImagePreviewOptions extends PreviewConfig {
16
- toolbarAddon?: ReactNode;
17
- }
18
- interface ImageProps$1 extends Omit<ImageProps, 'preview'> {
9
+ type ImageProps = Omit<ComponentProps<'img'>, 'width' | 'height'> & {
19
10
  actions?: ReactNode;
20
11
  alwaysShowActions?: boolean;
21
12
  classNames?: {
22
13
  image?: string;
23
14
  wrapper?: string;
24
15
  };
16
+ height?: number | string;
25
17
  isLoading?: boolean;
26
18
  maxHeight?: number | string;
27
19
  maxWidth?: number | string;
@@ -35,9 +27,14 @@ interface ImageProps$1 extends Omit<ImageProps, 'preview'> {
35
27
  image?: CSSProperties;
36
28
  wrapper?: CSSProperties;
37
29
  };
38
- toolbarAddon?: ReactNode;
39
30
  variant?: 'borderless' | 'filled' | 'outlined';
31
+ width?: number | string;
32
+ };
33
+ interface PreviewGroupProps {
34
+ children?: ReactNode;
35
+ enable?: boolean;
36
+ preview?: boolean | ImagePreviewOptions;
40
37
  }
41
38
  //#endregion
42
- export { ImagePreviewOptions, ImageProps$1 as ImageProps, PreviewGroupPreviewOptions, PreviewGroupProps };
39
+ export { ImagePreviewOptions, ImageProps, PreviewGroupProps };
43
40
  //# sourceMappingURL=type.d.mts.map
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import Center from "../../Flex/Center.mjs";
3
+ import ActionIcon from "../../ActionIcon/ActionIcon.mjs";
4
+ import { useTranslation } from "../../i18n/useTranslation.mjs";
5
+ import { styles } from "../style.mjs";
6
+ import image_default from "../../i18n/resources/en/image.mjs";
7
+ import { memo } from "react";
8
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
+ import { cx } from "antd-style";
10
+ import { ChevronLeft, ChevronRight } from "lucide-react";
11
+ //#region src/Image/viewer/GalleryNav.tsx
12
+ const GalleryNav = memo(({ current, hasNext, hasPrev, next, prev, total }) => {
13
+ const { t } = useTranslation(image_default);
14
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
15
+ hasPrev && /* @__PURE__ */ jsx(ActionIcon, {
16
+ className: cx(styles.viewerNavButton, styles.viewerNavPrev),
17
+ icon: ChevronLeft,
18
+ size: "large",
19
+ title: t("image.prev"),
20
+ onClick: prev
21
+ }),
22
+ hasNext && /* @__PURE__ */ jsx(ActionIcon, {
23
+ className: cx(styles.viewerNavButton, styles.viewerNavNext),
24
+ icon: ChevronRight,
25
+ size: "large",
26
+ title: t("image.next"),
27
+ onClick: next
28
+ }),
29
+ /* @__PURE__ */ jsxs(Center, {
30
+ horizontal: true,
31
+ className: styles.viewerCounter,
32
+ children: [
33
+ current + 1,
34
+ " / ",
35
+ total
36
+ ]
37
+ })
38
+ ] });
39
+ });
40
+ GalleryNav.displayName = "GalleryNav";
41
+ //#endregion
42
+ export { GalleryNav as default };
43
+
44
+ //# sourceMappingURL=GalleryNav.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GalleryNav.mjs","names":["imageMessages"],"sources":["../../../src/Image/viewer/GalleryNav.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { memo } from 'react';\n\nimport ActionIcon from '@/ActionIcon';\nimport { Center } from '@/Flex';\nimport imageMessages from '@/i18n/resources/en/image';\nimport { useTranslation } from '@/i18n/useTranslation';\n\nimport { styles } from '../style';\n\nexport interface GalleryNavProps {\n current: number;\n hasNext: boolean;\n hasPrev: boolean;\n next: () => void;\n prev: () => void;\n total: number;\n}\n\nconst GalleryNav = memo<GalleryNavProps>(({ current, hasNext, hasPrev, next, prev, total }) => {\n const { t } = useTranslation(imageMessages);\n\n return (\n <>\n {hasPrev && (\n <ActionIcon\n className={cx(styles.viewerNavButton, styles.viewerNavPrev)}\n icon={ChevronLeft}\n size={'large'}\n title={t('image.prev')}\n onClick={prev}\n />\n )}\n {hasNext && (\n <ActionIcon\n className={cx(styles.viewerNavButton, styles.viewerNavNext)}\n icon={ChevronRight}\n size={'large'}\n title={t('image.next')}\n onClick={next}\n />\n )}\n <Center horizontal className={styles.viewerCounter}>\n {current + 1} / {total}\n </Center>\n </>\n );\n});\n\nGalleryNav.displayName = 'GalleryNav';\n\nexport default GalleryNav;\n"],"mappings":";;;;;;;;;;;AAsBA,MAAM,aAAa,MAAuB,EAAE,SAAS,SAAS,SAAS,MAAM,MAAM,YAAY;CAC7F,MAAM,EAAE,MAAM,eAAeA,aAAa;CAE1C,OACE,qBAAA,YAAA,EAAA,UAAA;EACG,WACC,oBAAC,YAAD;GACE,WAAW,GAAG,OAAO,iBAAiB,OAAO,aAAa;GAC1D,MAAM;GACN,MAAM;GACN,OAAO,EAAE,YAAY;GACrB,SAAS;EACV,CAAA;EAEF,WACC,oBAAC,YAAD;GACE,WAAW,GAAG,OAAO,iBAAiB,OAAO,aAAa;GAC1D,MAAM;GACN,MAAM;GACN,OAAO,EAAE,YAAY;GACrB,SAAS;EACV,CAAA;EAEH,qBAAC,QAAD;GAAQ,YAAA;GAAW,WAAW,OAAO;GAArC,UAAA;IACG,UAAU;IAAE;IAAI;GACX;;CACR,EAAA,CAAA;AAEN,CAAC;AAED,WAAW,cAAc"}
@@ -0,0 +1,275 @@
1
+ "use client";
2
+ import { MotionComponent } from "../../MotionProvider/index.mjs";
3
+ import { useAppElement } from "../../ThemeProvider/AppElementContext.mjs";
4
+ import { useLayerZIndex } from "../../base-ui/zIndex/useLayerZIndex.mjs";
5
+ import { styles } from "../style.mjs";
6
+ import { ToastHost } from "../../base-ui/Toast/imperative.mjs";
7
+ import { computeFit, unrotatedRect } from "./geometry.mjs";
8
+ import { beginClosePreview, endClosePreview } from "./registry.mjs";
9
+ import { useFinalFocus } from "./useFinalFocus.mjs";
10
+ import { useFlipTransition } from "./useFlipTransition.mjs";
11
+ import { useViewerGestures } from "./useViewerGestures.mjs";
12
+ import { readNatural, useGalleryNav } from "./useGalleryNav.mjs";
13
+ import { useRefitTransition } from "./useRefitTransition.mjs";
14
+ import { useZoomPan } from "./useZoomPan.mjs";
15
+ import ViewerChrome from "./ViewerChrome.mjs";
16
+ import { memo, use, useCallback, useEffect, useMemo, useRef, useState } from "react";
17
+ import { jsx, jsxs } from "react/jsx-runtime";
18
+ import { useMergeRefs } from "react-merge-refs";
19
+ import { Dialog } from "@base-ui/react/dialog";
20
+ //#region src/Image/viewer/ImageViewer.tsx
21
+ const readViewport = () => ({
22
+ height: window.innerHeight,
23
+ width: window.innerWidth
24
+ });
25
+ const prefersReducedMotion = () => window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
26
+ const ImageViewer = memo(({ entries, index, openerFocusElement, token }) => {
27
+ const openerEntry = entries[index];
28
+ const appElement = useAppElement();
29
+ const motionComponent = use(MotionComponent);
30
+ const [animated] = useState(() => !!motionComponent && !prefersReducedMotion());
31
+ const { ref: layerRef, zIndex } = useLayerZIndex("modal");
32
+ const [currentIndex, setCurrentIndex] = useState(index);
33
+ const currentEntry = entries[currentIndex];
34
+ const currentEntryRef = useRef(currentEntry);
35
+ currentEntryRef.current = currentEntry;
36
+ const [source, setSource] = useState(openerEntry.src);
37
+ const [natural, setNatural] = useState(() => readNatural(openerEntry.element));
38
+ const [viewport, setViewport] = useState(readViewport);
39
+ const closeRef = useRef(null);
40
+ const requestClose = useCallback(() => closeRef.current?.(), []);
41
+ const isClosingIndirectRef = useRef(() => false);
42
+ const isClosingIndirect = useCallback(() => isClosingIndirectRef.current(), []);
43
+ const fillViewport = Boolean(currentEntry.previewSrc && currentEntry.previewSrc !== currentEntry.src);
44
+ const { canZoomIn, canZoomOut, dragBy, dragEnd, escIntent, flipHorizontal, flipVertical, flipX, flipY, handleDoubleClick, handleWheel, isClean, isZoomed, reset, resetCloseTracking, rotate, rotateLeft, rotateRight, rotation, scale, setNatural: syncZoomNatural, setViewport: syncZoomViewport, x, y, zoomIn, zoomOut } = useZoomPan({
45
+ fillViewport,
46
+ isClosing: isClosingIndirect,
47
+ maxScale: currentEntry.options.maxScale,
48
+ natural,
49
+ onCloseRequest: requestClose,
50
+ viewport
51
+ });
52
+ const fitRect = useMemo(() => computeFit(natural, viewport, rotation, fillViewport), [
53
+ natural,
54
+ viewport,
55
+ rotation,
56
+ fillViewport
57
+ ]);
58
+ const fitRectRef = useRef(fitRect);
59
+ fitRectRef.current = fitRect;
60
+ const getFitRect = useCallback(() => fitRectRef.current, []);
61
+ const imageRect = useMemo(() => unrotatedRect(fitRect, rotation), [fitRect, rotation]);
62
+ const viewportRef = useRef(viewport);
63
+ viewportRef.current = viewport;
64
+ const getViewportWidth = useCallback(() => viewportRef.current.width, []);
65
+ const getCloseSource = useCallback(() => currentEntryRef.current.element, []);
66
+ const transform = useMemo(() => ({
67
+ flipX,
68
+ flipY,
69
+ rotate,
70
+ scale,
71
+ x,
72
+ y
73
+ }), [
74
+ flipX,
75
+ flipY,
76
+ rotate,
77
+ scale,
78
+ x,
79
+ y
80
+ ]);
81
+ const handleClosed = useCallback(() => endClosePreview(token), [token]);
82
+ const { backdropRef, chromeRef, close, imageRef: flipImageRef, isClosing, isTransitioning, switchTo } = useFlipTransition({
83
+ animated,
84
+ getCloseSource,
85
+ getFitRect,
86
+ getViewportWidth,
87
+ onClosed: handleClosed,
88
+ source: openerEntry.element,
89
+ transform
90
+ });
91
+ isClosingIndirectRef.current = isClosing;
92
+ useRefitTransition({
93
+ animated,
94
+ fillViewport,
95
+ isTransitioning,
96
+ natural,
97
+ rotation,
98
+ scale,
99
+ viewport,
100
+ x,
101
+ y
102
+ });
103
+ const finalFocus = useFinalFocus(openerFocusElement);
104
+ const isCleanRef = useRef(isClean);
105
+ isCleanRef.current = isClean;
106
+ const handleClose = useCallback(() => {
107
+ beginClosePreview(token);
108
+ close({ fade: !isCleanRef.current });
109
+ }, [close, token]);
110
+ closeRef.current = handleClose;
111
+ const handleDialogOpenChange = useCallback((open, eventDetails) => {
112
+ if (open) return;
113
+ if (isClosing()) return;
114
+ if (eventDetails.reason === "escape-key" && escIntent() === "reset") {
115
+ eventDetails.cancel();
116
+ reset();
117
+ return;
118
+ }
119
+ handleClose();
120
+ }, [
121
+ escIntent,
122
+ handleClose,
123
+ isClosing,
124
+ reset
125
+ ]);
126
+ const gestures = useViewerGestures({
127
+ dragBy,
128
+ dragEnd,
129
+ handleDoubleClick,
130
+ handleWheel,
131
+ isClean,
132
+ isZoomed,
133
+ onClose: handleClose,
134
+ reset,
135
+ zoomIn,
136
+ zoomOut
137
+ });
138
+ const { hasNext, hasPrev, next, prev } = useGalleryNav({
139
+ cancelPendingClose: gestures.cancelPendingClose,
140
+ currentIndex,
141
+ entries,
142
+ flipX,
143
+ flipY,
144
+ resetCloseTracking,
145
+ rotate,
146
+ scale,
147
+ setCurrentIndex,
148
+ setNatural,
149
+ setSource,
150
+ switchTo,
151
+ syncZoomNatural,
152
+ x,
153
+ y
154
+ });
155
+ const popupNodeRef = useRef(null);
156
+ const popupRef = useMergeRefs([
157
+ layerRef,
158
+ gestures.popupRef,
159
+ popupNodeRef
160
+ ]);
161
+ const imageRef = useMergeRefs([flipImageRef, gestures.imageRef]);
162
+ const handleLoad = useCallback((event) => {
163
+ const loaded = event.currentTarget;
164
+ if (!loaded.naturalWidth || !loaded.naturalHeight) return;
165
+ const next = {
166
+ height: loaded.naturalHeight,
167
+ width: loaded.naturalWidth
168
+ };
169
+ setNatural((prev) => prev.width === next.width && prev.height === next.height ? prev : next);
170
+ syncZoomNatural(next);
171
+ }, [syncZoomNatural]);
172
+ useEffect(() => {
173
+ const handleResize = () => {
174
+ const next = readViewport();
175
+ setViewport(next);
176
+ syncZoomViewport(next);
177
+ };
178
+ window.addEventListener("resize", handleResize);
179
+ return () => window.removeEventListener("resize", handleResize);
180
+ }, [syncZoomViewport]);
181
+ useEffect(() => {
182
+ const { previewSrc, src } = currentEntry;
183
+ if (!previewSrc || previewSrc === src) return;
184
+ let cancelled = false;
185
+ const loader = new window.Image();
186
+ const handleLoaded = () => {
187
+ if (!cancelled) setSource(previewSrc);
188
+ };
189
+ loader.addEventListener("load", handleLoaded);
190
+ loader.src = previewSrc;
191
+ return () => {
192
+ cancelled = true;
193
+ loader.removeEventListener("load", handleLoaded);
194
+ };
195
+ }, [currentEntry]);
196
+ useEffect(() => () => {
197
+ if (!openerEntry.element.isConnected) endClosePreview(token);
198
+ }, [openerEntry, token]);
199
+ return /* @__PURE__ */ jsx(Dialog.Root, {
200
+ modal: true,
201
+ open: true,
202
+ onOpenChange: handleDialogOpenChange,
203
+ children: /* @__PURE__ */ jsxs(Dialog.Portal, {
204
+ container: appElement ?? void 0,
205
+ children: [
206
+ /* @__PURE__ */ jsx(Dialog.Backdrop, {
207
+ className: styles.viewerBackdrop,
208
+ ref: backdropRef,
209
+ style: zIndex === void 0 ? void 0 : { zIndex },
210
+ onClick: gestures.onSurfaceClick
211
+ }),
212
+ /* @__PURE__ */ jsxs(Dialog.Popup, {
213
+ "aria-label": currentEntry.element.alt || void 0,
214
+ className: styles.viewerPopup,
215
+ finalFocus,
216
+ initialFocus: popupNodeRef,
217
+ ref: popupRef,
218
+ style: zIndex === void 0 ? void 0 : { zIndex: zIndex + 1 },
219
+ tabIndex: -1,
220
+ onClick: gestures.onSurfaceClick,
221
+ onPointerCancel: gestures.onPointerFinish,
222
+ onPointerDown: gestures.onPointerDown,
223
+ onPointerMove: gestures.onPointerMove,
224
+ onPointerUp: gestures.onPointerFinish,
225
+ children: [/* @__PURE__ */ jsx("img", {
226
+ alt: currentEntry.element.alt,
227
+ className: styles.viewerImage,
228
+ ref: imageRef,
229
+ src: source,
230
+ style: {
231
+ cursor: gestures.cursor,
232
+ height: imageRect.height,
233
+ left: imageRect.x,
234
+ top: imageRect.y,
235
+ width: imageRect.width
236
+ },
237
+ onClick: gestures.onImageClick,
238
+ onDoubleClick: gestures.onImageDoubleClick,
239
+ onLoad: handleLoad
240
+ }), /* @__PURE__ */ jsx(ViewerChrome, {
241
+ canZoomIn,
242
+ canZoomOut,
243
+ chromeRef,
244
+ current: currentIndex,
245
+ fitRect,
246
+ flipHorizontal,
247
+ flipVertical,
248
+ hasNext,
249
+ hasPrev,
250
+ natural,
251
+ next,
252
+ prev,
253
+ reset,
254
+ rotateLeft,
255
+ rotateRight,
256
+ rotation,
257
+ scale,
258
+ source,
259
+ toolbarAddon: currentEntry.options.toolbarAddon,
260
+ total: entries.length,
261
+ zoomIn,
262
+ zoomOut,
263
+ onClose: handleClose
264
+ })]
265
+ }),
266
+ /* @__PURE__ */ jsx(ToastHost, { root: appElement ?? void 0 })
267
+ ]
268
+ })
269
+ });
270
+ });
271
+ ImageViewer.displayName = "ImageViewer";
272
+ //#endregion
273
+ export { ImageViewer as default };
274
+
275
+ //# sourceMappingURL=ImageViewer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageViewer.mjs","names":[],"sources":["../../../src/Image/viewer/ImageViewer.tsx"],"sourcesContent":["'use client';\n\nimport { Dialog, type DialogRootProps } from '@base-ui/react/dialog';\nimport {\n memo,\n type SyntheticEvent,\n use,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useMergeRefs } from 'react-merge-refs';\n\nimport { ToastHost } from '@/base-ui/Toast';\nimport { useLayerZIndex } from '@/base-ui/zIndex';\nimport { MotionComponent } from '@/MotionProvider';\nimport { useAppElement } from '@/ThemeProvider';\n\nimport { styles } from '../style';\nimport { computeFit, type Size, unrotatedRect } from './geometry';\nimport { beginClosePreview, endClosePreview, type PreviewEntry } from './registry';\nimport { useFinalFocus } from './useFinalFocus';\nimport { useFlipTransition } from './useFlipTransition';\nimport { readNatural, useGalleryNav } from './useGalleryNav';\nimport { useRefitTransition } from './useRefitTransition';\nimport { useViewerGestures } from './useViewerGestures';\nimport { useZoomPan } from './useZoomPan';\nimport ViewerChrome from './ViewerChrome';\n\nexport interface ImageViewerProps {\n entries: PreviewEntry[];\n index: number;\n openerFocusElement: HTMLElement | null;\n token: number;\n}\n\nconst readViewport = (): Size => ({ height: window.innerHeight, width: window.innerWidth });\n\nconst prefersReducedMotion = () =>\n window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false;\n\nconst ImageViewer = memo<ImageViewerProps>(({ entries, index, openerFocusElement, token }) => {\n const openerEntry = entries[index];\n const appElement = useAppElement();\n const motionComponent = use(MotionComponent);\n const [animated] = useState(() => !!motionComponent && !prefersReducedMotion());\n\n const { ref: layerRef, zIndex } = useLayerZIndex<HTMLDivElement>('modal');\n\n const [currentIndex, setCurrentIndex] = useState(index);\n const currentEntry = entries[currentIndex];\n const currentEntryRef = useRef(currentEntry);\n currentEntryRef.current = currentEntry;\n\n const [source, setSource] = useState(openerEntry.src);\n const [natural, setNatural] = useState<Size>(() => readNatural(openerEntry.element));\n const [viewport, setViewport] = useState<Size>(readViewport);\n\n const closeRef = useRef<(() => void) | null>(null);\n const requestClose = useCallback(() => closeRef.current?.(), []);\n\n // useZoomPan needs to gate its wheel/toolbar entry points on close-in-flight,\n // but that state only exists once useFlipTransition (below) has run — and it\n // needs useZoomPan's own transform values first. Break the cycle with a\n // stable indirection: the ref is repointed at the real isClosing once it's\n // available, written directly during render like the other *Ref fields here.\n const isClosingIndirectRef = useRef<() => boolean>(() => false);\n const isClosingIndirect = useCallback(() => isClosingIndirectRef.current(), []);\n\n const fillViewport = Boolean(\n currentEntry.previewSrc && currentEntry.previewSrc !== currentEntry.src,\n );\n\n const {\n canZoomIn,\n canZoomOut,\n dragBy,\n dragEnd,\n escIntent,\n flipHorizontal,\n flipVertical,\n flipX,\n flipY,\n handleDoubleClick,\n handleWheel,\n isClean,\n isZoomed,\n reset,\n resetCloseTracking,\n rotate,\n rotateLeft,\n rotateRight,\n rotation,\n scale,\n setNatural: syncZoomNatural,\n setViewport: syncZoomViewport,\n x,\n y,\n zoomIn,\n zoomOut,\n } = useZoomPan({\n fillViewport,\n isClosing: isClosingIndirect,\n maxScale: currentEntry.options.maxScale,\n natural,\n onCloseRequest: requestClose,\n viewport,\n });\n\n const fitRect = useMemo(\n () => computeFit(natural, viewport, rotation, fillViewport),\n [natural, viewport, rotation, fillViewport],\n );\n const fitRectRef = useRef(fitRect);\n fitRectRef.current = fitRect;\n const getFitRect = useCallback(() => fitRectRef.current, []);\n\n const imageRect = useMemo(() => unrotatedRect(fitRect, rotation), [fitRect, rotation]);\n\n const viewportRef = useRef(viewport);\n viewportRef.current = viewport;\n const getViewportWidth = useCallback(() => viewportRef.current.width, []);\n\n const getCloseSource = useCallback(() => currentEntryRef.current.element, []);\n\n const transform = useMemo(\n () => ({ flipX, flipY, rotate, scale, x, y }),\n [flipX, flipY, rotate, scale, x, y],\n );\n const handleClosed = useCallback(() => endClosePreview(token), [token]);\n\n const {\n backdropRef,\n chromeRef,\n close,\n imageRef: flipImageRef,\n isClosing,\n isTransitioning,\n switchTo,\n } = useFlipTransition({\n animated,\n getCloseSource,\n getFitRect,\n getViewportWidth,\n onClosed: handleClosed,\n source: openerEntry.element,\n transform,\n });\n isClosingIndirectRef.current = isClosing;\n\n useRefitTransition({\n animated,\n fillViewport,\n isTransitioning,\n natural,\n rotation,\n scale,\n viewport,\n x,\n y,\n });\n const finalFocus = useFinalFocus(openerFocusElement);\n\n const isCleanRef = useRef(isClean);\n isCleanRef.current = isClean;\n\n const handleClose = useCallback(() => {\n beginClosePreview(token);\n close({ fade: !isCleanRef.current });\n }, [close, token]);\n closeRef.current = handleClose;\n\n const handleDialogOpenChange = useCallback<NonNullable<DialogRootProps['onOpenChange']>>(\n (open, eventDetails) => {\n if (open) return;\n // Base UI fires this on every Esc regardless of whether we're already\n // mid-close (our Dialog.Root's open prop never actually flips to\n // false), so without this guard a second Esc during the close window\n // reads escIntent() off the close spring's mid-flight scale, decides\n // 'reset', and cancels the close animation out from under itself.\n if (isClosing()) return;\n if (eventDetails.reason === 'escape-key' && escIntent() === 'reset') {\n eventDetails.cancel();\n reset();\n return;\n }\n handleClose();\n },\n [escIntent, handleClose, isClosing, reset],\n );\n\n const gestures = useViewerGestures({\n dragBy,\n dragEnd,\n handleDoubleClick,\n handleWheel,\n isClean,\n isZoomed,\n onClose: handleClose,\n reset,\n zoomIn,\n zoomOut,\n });\n\n const { hasNext, hasPrev, next, prev } = useGalleryNav({\n cancelPendingClose: gestures.cancelPendingClose,\n currentIndex,\n entries,\n flipX,\n flipY,\n resetCloseTracking,\n rotate,\n scale,\n setCurrentIndex,\n setNatural,\n setSource,\n switchTo,\n syncZoomNatural,\n x,\n y,\n });\n\n const popupNodeRef = useRef<HTMLDivElement | null>(null);\n const popupRef = useMergeRefs<HTMLDivElement>([layerRef, gestures.popupRef, popupNodeRef]);\n const imageRef = useMergeRefs<HTMLImageElement>([flipImageRef, gestures.imageRef]);\n\n const handleLoad = useCallback(\n (event: SyntheticEvent<HTMLImageElement>) => {\n const loaded = event.currentTarget;\n if (!loaded.naturalWidth || !loaded.naturalHeight) return;\n const next = { height: loaded.naturalHeight, width: loaded.naturalWidth };\n setNatural((prev) =>\n prev.width === next.width && prev.height === next.height ? prev : next,\n );\n syncZoomNatural(next);\n },\n [syncZoomNatural],\n );\n\n useEffect(() => {\n const handleResize = () => {\n const next = readViewport();\n setViewport(next);\n syncZoomViewport(next);\n };\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [syncZoomViewport]);\n\n useEffect(() => {\n const { previewSrc, src } = currentEntry;\n if (!previewSrc || previewSrc === src) return;\n let cancelled = false;\n const loader = new window.Image();\n const handleLoaded = () => {\n if (!cancelled) setSource(previewSrc);\n };\n loader.addEventListener('load', handleLoaded);\n loader.src = previewSrc;\n return () => {\n cancelled = true;\n loader.removeEventListener('load', handleLoaded);\n };\n }, [currentEntry]);\n\n useEffect(\n () => () => {\n const thumbnailWasRemoved = !openerEntry.element.isConnected;\n if (thumbnailWasRemoved) endClosePreview(token);\n },\n [openerEntry, token],\n );\n\n return (\n <Dialog.Root modal open onOpenChange={handleDialogOpenChange}>\n <Dialog.Portal container={appElement ?? undefined}>\n <Dialog.Backdrop\n className={styles.viewerBackdrop}\n ref={backdropRef}\n style={zIndex === undefined ? undefined : { zIndex }}\n onClick={gestures.onSurfaceClick}\n />\n <Dialog.Popup\n aria-label={currentEntry.element.alt || undefined}\n className={styles.viewerPopup}\n finalFocus={finalFocus}\n // Focus the popup itself instead of Base UI's default (the first\n // tabbable — the close button): a focus-visible close button pins\n // the idle auto-hide open forever and pops its tooltip on open.\n initialFocus={popupNodeRef}\n ref={popupRef}\n style={zIndex === undefined ? undefined : { zIndex: zIndex + 1 }}\n tabIndex={-1}\n onClick={gestures.onSurfaceClick}\n onPointerCancel={gestures.onPointerFinish}\n onPointerDown={gestures.onPointerDown}\n onPointerMove={gestures.onPointerMove}\n onPointerUp={gestures.onPointerFinish}\n >\n <img\n alt={currentEntry.element.alt}\n className={styles.viewerImage}\n ref={imageRef}\n src={source}\n style={{\n cursor: gestures.cursor,\n height: imageRect.height,\n left: imageRect.x,\n top: imageRect.y,\n width: imageRect.width,\n }}\n onClick={gestures.onImageClick}\n onDoubleClick={gestures.onImageDoubleClick}\n onLoad={handleLoad}\n />\n <ViewerChrome\n canZoomIn={canZoomIn}\n canZoomOut={canZoomOut}\n chromeRef={chromeRef}\n current={currentIndex}\n fitRect={fitRect}\n flipHorizontal={flipHorizontal}\n flipVertical={flipVertical}\n hasNext={hasNext}\n hasPrev={hasPrev}\n natural={natural}\n next={next}\n prev={prev}\n reset={reset}\n rotateLeft={rotateLeft}\n rotateRight={rotateRight}\n rotation={rotation}\n scale={scale}\n source={source}\n toolbarAddon={currentEntry.options.toolbarAddon}\n total={entries.length}\n zoomIn={zoomIn}\n zoomOut={zoomOut}\n onClose={handleClose}\n />\n </Dialog.Popup>\n <ToastHost root={appElement ?? undefined} />\n </Dialog.Portal>\n </Dialog.Root>\n );\n});\n\nImageViewer.displayName = 'ImageViewer';\n\nexport default ImageViewer;\n"],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { usePreviewSession } from "./registry.mjs";
3
+ import ImageViewer from "./ImageViewer.mjs";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/Image/viewer/PreviewOutlet.tsx
6
+ const PreviewOutlet = ({ elementRef }) => {
7
+ const session = usePreviewSession(elementRef);
8
+ if (!session) return null;
9
+ return /* @__PURE__ */ jsx(ImageViewer, {
10
+ entries: session.entries,
11
+ index: session.index,
12
+ openerFocusElement: session.openerFocusElement,
13
+ token: session.token
14
+ }, session.token);
15
+ };
16
+ //#endregion
17
+ export { PreviewOutlet as default };
18
+
19
+ //# sourceMappingURL=PreviewOutlet.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreviewOutlet.mjs","names":[],"sources":["../../../src/Image/viewer/PreviewOutlet.tsx"],"sourcesContent":["'use client';\n\nimport type { RefObject } from 'react';\n\nimport ImageViewer from './ImageViewer';\nimport { usePreviewSession } from './registry';\n\nexport interface PreviewOutletProps {\n elementRef: RefObject<HTMLImageElement | null>;\n}\n\nconst PreviewOutlet = ({ elementRef }: PreviewOutletProps) => {\n const session = usePreviewSession(elementRef);\n if (!session) return null;\n return (\n <ImageViewer\n entries={session.entries}\n index={session.index}\n key={session.token}\n openerFocusElement={session.openerFocusElement}\n token={session.token}\n />\n );\n};\n\nexport default PreviewOutlet;\n"],"mappings":";;;;;AAWA,MAAM,iBAAiB,EAAE,iBAAqC;CAC5D,MAAM,UAAU,kBAAkB,UAAU;CAC5C,IAAI,CAAC,SAAS,OAAO;CACrB,OACE,oBAAC,aAAD;EACE,SAAS,QAAQ;EACjB,OAAO,QAAQ;EAEf,oBAAoB,QAAQ;EAC5B,OAAO,QAAQ;CAChB,GAHM,QAAQ,KAGd;AAEL"}