@ryuzaki13/react-foundation-ui 1.0.15 → 1.0.17

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 (263) hide show
  1. package/dist/advanced-search/index.js +7 -7
  2. package/dist/badge/index.js +1 -1
  3. package/dist/base-table/index.js +1 -1
  4. package/dist/chunks/{TextEditorLexicalClient-jQ7V9jFm.js → TextEditorLexicalClient-B1kQnKrU.js} +3 -3
  5. package/dist/chunks/{TextEditorLexicalClient-jQ7V9jFm.js.map → TextEditorLexicalClient-B1kQnKrU.js.map} +1 -1
  6. package/dist/chunks/{badge-BfbLPk0z.js → badge-Cri0-kVK.js} +2 -2
  7. package/dist/chunks/{badge-BfbLPk0z.js.map → badge-Cri0-kVK.js.map} +1 -1
  8. package/dist/chunks/{base-table-CiYSRI_J.js → base-table-DghNJ6ss.js} +3 -3
  9. package/dist/chunks/{base-table-CiYSRI_J.js.map → base-table-DghNJ6ss.js.map} +1 -1
  10. package/dist/chunks/{flex-CPO6xlPR.js → flex-DYZ0IbU6.js} +76 -14
  11. package/dist/chunks/flex-DYZ0IbU6.js.map +1 -0
  12. package/dist/chunks/{grid-ByIIytjh.js → grid-dI94AAbi.js} +63 -45
  13. package/dist/chunks/grid-dI94AAbi.js.map +1 -0
  14. package/dist/chunks/{misc-1PxS8OWD.js → misc-ClXJygTj.js} +2 -2
  15. package/dist/chunks/{misc-1PxS8OWD.js.map → misc-ClXJygTj.js.map} +1 -1
  16. package/dist/chunks/{modal-4vYSSbAa.js → modal-QGp5CjB9.js} +4 -4
  17. package/dist/chunks/{modal-4vYSSbAa.js.map → modal-QGp5CjB9.js.map} +1 -1
  18. package/dist/chunks/{multi-select-r0ekR6Bh.js → multi-select-DkfdFYm4.js} +2 -2
  19. package/dist/chunks/{multi-select-r0ekR6Bh.js.map → multi-select-DkfdFYm4.js.map} +1 -1
  20. package/dist/chunks/{table-BR2VqeEg.js → table-tBQ_FOs3.js} +2 -2
  21. package/dist/chunks/{table-BR2VqeEg.js.map → table-tBQ_FOs3.js.map} +1 -1
  22. package/dist/errors/index.js +1 -1
  23. package/dist/expandable-action-panel/index.js +1 -1
  24. package/dist/flex/FlexCenter.d.ts +4 -5
  25. package/dist/flex/FlexCenter.d.ts.map +1 -1
  26. package/dist/flex/FlexContainer.d.ts.map +1 -1
  27. package/dist/flex/FlexItem.d.ts.map +1 -1
  28. package/dist/flex/FlexSpacer.d.ts +3 -2
  29. package/dist/flex/FlexSpacer.d.ts.map +1 -1
  30. package/dist/flex/index.js +1 -1
  31. package/dist/flex/types.d.ts +5 -3
  32. package/dist/flex/types.d.ts.map +1 -1
  33. package/dist/flex/useFlexClasses.d.ts +4 -4
  34. package/dist/flex/useFlexClasses.d.ts.map +1 -1
  35. package/dist/grid/GridContainer.d.ts.map +1 -1
  36. package/dist/grid/index.js +1 -1
  37. package/dist/grid/types.d.ts +5 -3
  38. package/dist/grid/types.d.ts.map +1 -1
  39. package/dist/grid/useGridClasses.d.ts +3 -3
  40. package/dist/grid/useGridClasses.d.ts.map +1 -1
  41. package/dist/image/index.d.ts +14 -5
  42. package/dist/image/index.d.ts.map +1 -1
  43. package/dist/image/index.js +258 -254
  44. package/dist/image/index.js.map +1 -1
  45. package/dist/image/lib/buildImageSources.d.ts +4 -0
  46. package/dist/image/lib/buildImageSources.d.ts.map +1 -0
  47. package/dist/image/lib/buildImageSrcSet.d.ts +4 -0
  48. package/dist/image/lib/buildImageSrcSet.d.ts.map +1 -0
  49. package/dist/image/lib/getImageCropPreviewStyle.d.ts +9 -0
  50. package/dist/image/lib/getImageCropPreviewStyle.d.ts.map +1 -0
  51. package/dist/image/lib/getImageSelectionKey.d.ts +4 -0
  52. package/dist/image/lib/getImageSelectionKey.d.ts.map +1 -0
  53. package/dist/image/model/imageCropTypes.d.ts +35 -0
  54. package/dist/image/model/imageCropTypes.d.ts.map +1 -0
  55. package/dist/image/model/imageSelectionTypes.d.ts +53 -0
  56. package/dist/image/model/imageSelectionTypes.d.ts.map +1 -0
  57. package/dist/image/model/imageTypes.d.ts +41 -0
  58. package/dist/image/model/imageTypes.d.ts.map +1 -0
  59. package/dist/image/model/useImageSelectionState.d.ts +7 -0
  60. package/dist/image/model/useImageSelectionState.d.ts.map +1 -0
  61. package/dist/image/ui/ImageCropper.d.ts +6 -12
  62. package/dist/image/ui/ImageCropper.d.ts.map +1 -1
  63. package/dist/image/ui/ImagePlaceholder.d.ts +1 -2
  64. package/dist/image/ui/ImagePlaceholder.d.ts.map +1 -1
  65. package/dist/image/ui/ImageRenderer.d.ts +8 -7
  66. package/dist/image/ui/ImageRenderer.d.ts.map +1 -1
  67. package/dist/image/ui/ImageSelectionFields.d.ts +8 -0
  68. package/dist/image/ui/ImageSelectionFields.d.ts.map +1 -0
  69. package/dist/image/ui/ImageSelectionModal.d.ts +4 -0
  70. package/dist/image/ui/ImageSelectionModal.d.ts.map +1 -0
  71. package/dist/image/ui/ImageSelectionPanel.d.ts +4 -0
  72. package/dist/image/ui/ImageSelectionPanel.d.ts.map +1 -0
  73. package/dist/image/ui/ImageView.d.ts +8 -35
  74. package/dist/image/ui/ImageView.d.ts.map +1 -1
  75. package/dist/list/index.js +2 -2
  76. package/dist/misc/index.js +1 -1
  77. package/dist/modal/index.js +1 -1
  78. package/dist/multi-select/index.js +1 -1
  79. package/dist/notifications/index.js +1 -1
  80. package/dist/preset-range-date-input/index.js +1 -1
  81. package/dist/simple-table/index.js +1 -1
  82. package/dist/table/index.js +1 -1
  83. package/dist/tabs/index.js +1 -1
  84. package/dist/text-editor/index.js +2 -2
  85. package/dist/toolbar/index.js +2 -2
  86. package/dist/tree-table/index.js +1 -1
  87. package/package.json +1 -1
  88. package/storybook-static/assets/{Badge-BJuMBcdz.js → Badge-DhbMuuXm.js} +1 -1
  89. package/storybook-static/assets/{Badge.stories-IgBcw1Cf.js → Badge.stories-Cn2OwyNl.js} +1 -1
  90. package/storybook-static/assets/{Button-B_GEc_r4.js → Button-BCO6drLh.js} +1 -1
  91. package/storybook-static/assets/{Button-DRBTSyRM.js → Button-CK0YS5UI.js} +1 -1
  92. package/storybook-static/assets/{Button.stories-Di4OQvY8.js → Button.stories-PvBecpMR.js} +1 -1
  93. package/storybook-static/assets/{CheckBox-WHmt7FbU.js → CheckBox-CH7PEkzn.js} +1 -1
  94. package/storybook-static/assets/{CheckBox-57qzcUkX.js → CheckBox-DgMj1d8n.js} +1 -1
  95. package/storybook-static/assets/{CheckBox.stories-BItLovUs.js → CheckBox.stories-D6ItCkPg.js} +1 -1
  96. package/storybook-static/assets/{Color-KMSTOMOX-CWP56kfm.js → Color-KMSTOMOX-GfidB0cg.js} +1 -1
  97. package/storybook-static/assets/{ContextMenu-DKl_ZfMI.js → ContextMenu-D3lrcJcF.js} +1 -1
  98. package/storybook-static/assets/{ContextMenu.stories-D-Xnld63.js → ContextMenu.stories-eH4W7mHM.js} +1 -1
  99. package/storybook-static/assets/{DateInput-BSyYH-et.js → DateInput-B1DsTxcV.js} +1 -1
  100. package/storybook-static/assets/{DateInput-B2X74zQf.js → DateInput-BlmssZge.js} +1 -1
  101. package/storybook-static/assets/{DateInput.stories-Dwk-9ZjA.js → DateInput.stories-CXftqoBw.js} +1 -1
  102. package/storybook-static/assets/{DateRangePresetSelect-CPeX_HRn.js → DateRangePresetSelect-CL0hlHRZ.js} +1 -1
  103. package/storybook-static/assets/{DateRangePresetSelect-DTSWmoT_.js → DateRangePresetSelect-DIrJMADf.js} +1 -1
  104. package/storybook-static/assets/{DateRangePresetSelect.stories-CGNvBg03.js → DateRangePresetSelect.stories-DcSm9soa.js} +1 -1
  105. package/storybook-static/assets/{Detail-BQwyVo2M.js → Detail-CoabkYcs.js} +1 -1
  106. package/storybook-static/assets/{Detail.stories-x4juDK19.js → Detail.stories-DQYXxRp4.js} +1 -1
  107. package/storybook-static/assets/{Dialog-CH9J4tmL.js → Dialog-BMqJ2cWE.js} +1 -1
  108. package/storybook-static/assets/{Dialog.stories-Cp3J86ce.js → Dialog.stories-UMGlcMlF.js} +1 -1
  109. package/storybook-static/assets/{Disclosure-B7i9P4YG.js → Disclosure-KB4xjsXl.js} +1 -1
  110. package/storybook-static/assets/{Disclosure.stories-DzZ5RLXm.js → Disclosure.stories-BebcX5Iz.js} +1 -1
  111. package/storybook-static/assets/{DocsRenderer-JROSPFPF-D61SC7UY.js → DocsRenderer-JROSPFPF-DuKHOivk.js} +2 -2
  112. package/storybook-static/assets/{DropZone-MiBUScxG.js → DropZone-nfS8G3Hn.js} +1 -1
  113. package/storybook-static/assets/{DropZone.stories-C2qhbfNj.js → DropZone.stories-CfXfUPEJ.js} +1 -1
  114. package/storybook-static/assets/{DropdownMenu-X7PLdfVp.js → DropdownMenu-DnrqkJwd.js} +1 -1
  115. package/storybook-static/assets/{ExpandableActionPanel.stories-Ca2AoCI0.js → ExpandableActionPanel.stories-BoiZuwQW.js} +1 -1
  116. package/storybook-static/assets/{Flex-BaD8FRom.js → Flex-CTKFA_mG.js} +1 -1
  117. package/storybook-static/assets/Flex-Cmb3839O.js +3 -0
  118. package/storybook-static/assets/{Flex.stories-F8YaKEO0.js → Flex.stories-CP95d38j.js} +1 -1
  119. package/storybook-static/assets/{Grid-BewDzBtv.js → Grid-DNKooHvc.js} +3 -3
  120. package/storybook-static/assets/{Grid-ZTR_R-m1.js → Grid-Xy7dV3bL.js} +1 -1
  121. package/storybook-static/assets/{Grid.stories-Cu78z_oE.js → Grid.stories-CzW_QizU.js} +1 -1
  122. package/storybook-static/assets/ImageCropper.stories-BTXQ94Gl.js +115 -0
  123. package/storybook-static/assets/ImageRenderer-BoaYYmBZ.js +2 -0
  124. package/storybook-static/assets/ImageRenderer.stories-BbzcY9qz.js +22 -0
  125. package/storybook-static/assets/ImageView.stories-BxeA_KDn.js +9 -0
  126. package/storybook-static/assets/{Input-D6z--4tm.js → Input-23s-lKOn.js} +1 -1
  127. package/storybook-static/assets/{Input-DjRjmBbJ.js → Input-E_LkqP6a.js} +1 -1
  128. package/storybook-static/assets/{Input.stories-CBkJ60Z3.js → Input.stories-uG22uEFU.js} +1 -1
  129. package/storybook-static/assets/{InputDateTime-B2V4I801.js → InputDateTime-zIw8NrCi.js} +1 -1
  130. package/storybook-static/assets/{InputDateTime.stories-gepL7zcB.js → InputDateTime.stories-CRyGwLn7.js} +1 -1
  131. package/storybook-static/assets/{InputFile-B_rtgdVs.js → InputFile-Dt4Qf9UO.js} +1 -1
  132. package/storybook-static/assets/{InputFile.stories-CVD-PTav.js → InputFile.stories-CVHdaQXL.js} +1 -1
  133. package/storybook-static/assets/{InputFiles-CFlxBgsw.js → InputFiles-BqrOxvD8.js} +1 -1
  134. package/storybook-static/assets/{InputFiles-Cy_fvMYT.js → InputFiles-Bwk_tH4A.js} +1 -1
  135. package/storybook-static/assets/{InputFiles.stories-DIbO_ACP.js → InputFiles.stories-eNwGWGc6.js} +1 -1
  136. package/storybook-static/assets/{InputImage-BWbT8pGH.js → InputImage-DpX3d6wQ.js} +1 -1
  137. package/storybook-static/assets/{InputImage.stories-SyFATair.js → InputImage.stories-DBYvsQrj.js} +1 -1
  138. package/storybook-static/assets/{LayoutPicker-0dJNS0bb.js → LayoutPicker-CfSu2g4Z.js} +1 -1
  139. package/storybook-static/assets/{LayoutPicker.stories-BUohHOWt.js → LayoutPicker.stories-D1lUyF06.js} +1 -1
  140. package/storybook-static/assets/{Listbox-Cn1Z-r2n.js → Listbox-uDkRdf67.js} +1 -1
  141. package/storybook-static/assets/{Listbox.stories-c1NSeGUa.js → Listbox.stories-6yyYujhd.js} +1 -1
  142. package/storybook-static/assets/{Modal-Db2Ne_PP.js → Modal-J42YPjEH.js} +1 -1
  143. package/storybook-static/assets/{Modal.stories-CZum1nVD.js → Modal.stories-Nmp6akCZ.js} +1 -1
  144. package/storybook-static/assets/{MultiSelect-D-r3_Bry.js → MultiSelect-BJGmqmIo.js} +1 -1
  145. package/storybook-static/assets/{MultiSelect-CkHso-Za.js → MultiSelect-UF351F4G.js} +1 -1
  146. package/storybook-static/assets/{MultiSelect.stories-CjNtbPvc.js → MultiSelect.stories-DkzP-YMA.js} +1 -1
  147. package/storybook-static/assets/{NotificationsHost-DcsexLl8.js → NotificationsHost-C7ZbgRdj.js} +1 -1
  148. package/storybook-static/assets/{NotificationsHost.stories-DxB9wp4P.js → NotificationsHost.stories-DtE5nY4I.js} +1 -1
  149. package/storybook-static/assets/{ODataMultiSelect-BB6pa_2a.js → ODataMultiSelect-A28BQBXe.js} +1 -1
  150. package/storybook-static/assets/{ODataMultiSelect.stories-D4108lSt.js → ODataMultiSelect.stories-CleaUAky.js} +1 -1
  151. package/storybook-static/assets/{ODataSelect-BcrPaLAR.js → ODataSelect-CgPTwZze.js} +1 -1
  152. package/storybook-static/assets/{ODataSelect-BppTAIqx.js → ODataSelect-CidLsWhU.js} +1 -1
  153. package/storybook-static/assets/{ODataSelect.stories-DteYVpiQ.js → ODataSelect.stories-CnjZKsYR.js} +1 -1
  154. package/storybook-static/assets/{ODataTreeMultiSelect-CVjcPuI1.js → ODataTreeMultiSelect-BcXe8UV0.js} +1 -1
  155. package/storybook-static/assets/{ODataTreeMultiSelect.stories-C6xU81uc.js → ODataTreeMultiSelect.stories-Cy6URpNZ.js} +1 -1
  156. package/storybook-static/assets/{ODataTreeSelect-BRHxD-vG.js → ODataTreeSelect-B79mkiqm.js} +1 -1
  157. package/storybook-static/assets/{ODataTreeSelect.stories-CyqwAaqI.js → ODataTreeSelect.stories-BmS9Kslk.js} +1 -1
  158. package/storybook-static/assets/{PeriodSelect-oi5rAN2N.js → PeriodSelect-Dvd_n0px.js} +1 -1
  159. package/storybook-static/assets/{PeriodSelect.stories-C7UftRku.js → PeriodSelect.stories-DeB7vL4v.js} +1 -1
  160. package/storybook-static/assets/{Popover-DFJPXALP.js → Popover-CF6lPz2I.js} +1 -1
  161. package/storybook-static/assets/{Popover.stories-DTNaGax4.js → Popover.stories-CxldfZVc.js} +1 -1
  162. package/storybook-static/assets/{PresetRangeDateInput-Cm4EbMNS.js → PresetRangeDateInput-CMkWDbAV.js} +1 -1
  163. package/storybook-static/assets/{PresetRangeDateInput.stories-Y5uojvsz.js → PresetRangeDateInput.stories-CNYGpwHh.js} +1 -1
  164. package/storybook-static/assets/{RadioButton-B1xWc03x.js → RadioButton-BhV-iR7A.js} +1 -1
  165. package/storybook-static/assets/{RadioButton.stories-CFZrSdeX.js → RadioButton.stories-BBGp713e.js} +1 -1
  166. package/storybook-static/assets/{RadioGroup-dt4vRt66.js → RadioGroup-CFQmZbmE.js} +1 -1
  167. package/storybook-static/assets/{RadioGroup-CRnLGdRq.js → RadioGroup-_xQT2nsR.js} +1 -1
  168. package/storybook-static/assets/{RadioGroup.stories-Cq8jrT3o.js → RadioGroup.stories-B20ktIVa.js} +1 -1
  169. package/storybook-static/assets/{Select-CWfg857u.js → Select-CXqDj36V.js} +1 -1
  170. package/storybook-static/assets/{Select-COzu9R1S.js → Select-jIsVhwD3.js} +1 -1
  171. package/storybook-static/assets/{Select.stories-ajlw6UD7.js → Select.stories-C0VB6D4d.js} +1 -1
  172. package/storybook-static/assets/{SelectOptionContent-5fpSAPpp.js → SelectOptionContent-COxwEiax.js} +1 -1
  173. package/storybook-static/assets/{SerializableSelect-D7k-0rpL.js → SerializableSelect-BPHsbeTD.js} +1 -1
  174. package/storybook-static/assets/{SerializableSelect-CtF_5hDV.js → SerializableSelect-J1rOw5PY.js} +1 -1
  175. package/storybook-static/assets/{SerializableSelect.stories-DXink3F3.js → SerializableSelect.stories-DsPARybj.js} +1 -1
  176. package/storybook-static/assets/{SingleDateTimeInput-CiZs4GCq.js → SingleDateTimeInput-BpQ4pLpY.js} +1 -1
  177. package/storybook-static/assets/{SingleDateTimeInput.stories-5QJlrw4f.js → SingleDateTimeInput.stories-iX__aO9q.js} +1 -1
  178. package/storybook-static/assets/{Slider-CxK-n_Qh.js → Slider-DBT0NGzG.js} +1 -1
  179. package/storybook-static/assets/{Slider.stories-B0tho-fR.js → Slider.stories-B2eK8XJA.js} +1 -1
  180. package/storybook-static/assets/{SliderInput-ZN9vpT2S.js → SliderInput-ChSw_jKg.js} +1 -1
  181. package/storybook-static/assets/{SliderInput.stories-B9oU6kyp.js → SliderInput.stories-Ydlqkpul.js} +1 -1
  182. package/storybook-static/assets/{Sortable-Cyr7iTZO.js → Sortable-BNdP7m0c.js} +1 -1
  183. package/storybook-static/assets/{Sortable.stories-BhF3AZgC.js → Sortable.stories-DN3EmT5j.js} +1 -1
  184. package/storybook-static/assets/{Splitter-peLMiwre.js → Splitter-CcmZ1RhL.js} +1 -1
  185. package/storybook-static/assets/{Splitter.stories-nr3eJ5GM.js → Splitter.stories-8_bdaQBx.js} +1 -1
  186. package/storybook-static/assets/{StateSelect-B_fxrXNN.js → StateSelect-b7_i5AYO.js} +1 -1
  187. package/storybook-static/assets/{StateSelect.stories-CDdWdRLe.js → StateSelect.stories-8HzaiOPq.js} +1 -1
  188. package/storybook-static/assets/{Switch-DM50QWxA.js → Switch-B6iIA_Sa.js} +1 -1
  189. package/storybook-static/assets/{Switch.stories-D5LjDVPS.js → Switch.stories-C0C1FC4S.js} +1 -1
  190. package/storybook-static/assets/{Table-5aluIGdo.js → Table-ClcldA-z.js} +1 -1
  191. package/storybook-static/assets/{Table.stories-DGKBAzL2.js → Table.stories-BiJfbbFS.js} +1 -1
  192. package/storybook-static/assets/{Tabs-CO7DsnUr.js → Tabs-SS9HB-vC.js} +1 -1
  193. package/storybook-static/assets/{Tabs.stories-DTgCMxUb.js → Tabs.stories-BRcexZE0.js} +1 -1
  194. package/storybook-static/assets/{Textarea-DSvLZptc.js → Textarea-DMbVI72I.js} +1 -1
  195. package/storybook-static/assets/{Textarea.stories-kqd0YbmQ.js → Textarea.stories-DSgmFgdA.js} +1 -1
  196. package/storybook-static/assets/{TimePanel-DDaX01do.js → TimePanel-AqEGPwAi.js} +1 -1
  197. package/storybook-static/assets/{TimePanel.stories-CerMQLRf.js → TimePanel.stories-C7GxLG8Y.js} +1 -1
  198. package/storybook-static/assets/{Toggle-t1lVxQz6.js → Toggle-BGonS5_k.js} +1 -1
  199. package/storybook-static/assets/{Toggle.stories-CeJwV-Ek.js → Toggle.stories-fg1rL2w5.js} +1 -1
  200. package/storybook-static/assets/{TreeMultiSelect-Cqt4O9BU.js → TreeMultiSelect-cfKLgsPQ.js} +1 -1
  201. package/storybook-static/assets/{TreeMultiSelect-D6Au72K2.js → TreeMultiSelect-m1Jc0UmH.js} +1 -1
  202. package/storybook-static/assets/{TreeMultiSelect.stories-C_BIcIv6.js → TreeMultiSelect.stories-CcoijQYD.js} +1 -1
  203. package/storybook-static/assets/{TreePickerBase-DLVYUhCD.js → TreePickerBase-D8LeBNby.js} +1 -1
  204. package/storybook-static/assets/{TreeSelect-CIWXiLSp.js → TreeSelect-CLrdAJA-.js} +1 -1
  205. package/storybook-static/assets/{TreeSelect-CgDLk4ka.js → TreeSelect-CYJ5zvKm.js} +1 -1
  206. package/storybook-static/assets/{TreeSelect.stories-DJJQpAG-.js → TreeSelect.stories-C_uly8NB.js} +1 -1
  207. package/storybook-static/assets/{TreeTable-6VwdbiOA.js → TreeTable-CPTxegC1.js} +1 -1
  208. package/storybook-static/assets/{TreeTable.stories-CexcAFDG.js → TreeTable.stories-BjUwwZjp.js} +1 -1
  209. package/storybook-static/assets/{WithTooltip-7X4HQR7L-CceOi7V4.js → WithTooltip-7X4HQR7L-CUFIZPaf.js} +1 -1
  210. package/storybook-static/assets/{base-table-C0Zyxki6.js → base-table-cOtSkLXv.js} +1 -1
  211. package/storybook-static/assets/{blocks-CcO3Y_Rh.js → blocks-Ca82jrBU.js} +6 -6
  212. package/storybook-static/assets/{button-0yIdCp_-.js → button-BFuY_BqY.js} +1 -1
  213. package/storybook-static/assets/{check-box-vfk8jzFK.js → check-box-CmlDA0Xq.js} +1 -1
  214. package/storybook-static/assets/{chunk-3LY4VQVK-CZm0s4iL.js → chunk-3LY4VQVK-CDA9ib8M.js} +1 -1
  215. package/storybook-static/assets/{chunk-LITCR56V-C1XleE0V.js → chunk-LITCR56V-Mcli8zWg.js} +1 -1
  216. package/storybook-static/assets/{contextMenu-DJTYsh3u.js → contextMenu-BJxw-pJj.js} +1 -1
  217. package/storybook-static/assets/{error-7f4bI5b8.js → error-BwxipWa_.js} +1 -1
  218. package/storybook-static/assets/flex-BPTt9N_D.js +1 -0
  219. package/storybook-static/assets/{floating-ui.react-C-t718F2.js → floating-ui.react-CA8LXveu.js} +1 -1
  220. package/storybook-static/assets/formatter-L2YTDE3Q-CiF3j9Xe.js +1 -0
  221. package/storybook-static/assets/{formatters-c68ZHiVV.js → formatters-BSZSiQe7.js} +1 -1
  222. package/storybook-static/assets/grid-C5nOHfpH.js +1 -0
  223. package/storybook-static/assets/{hooks-Cia2yw95.js → hooks-rW6LwSJF.js} +1 -1
  224. package/storybook-static/assets/{iframe-B1ZJmGrq.js → iframe-DBBiRbws.js} +4 -4
  225. package/storybook-static/assets/{input-Bfb8MLis.js → input-DQGrA_Iz.js} +1 -1
  226. package/storybook-static/assets/{lucide-react-Cw6QPvVA.js → lucide-react-DbhedXaa.js} +1 -1
  227. package/storybook-static/assets/{mdx-react-shim-BGEl8pi6.js → mdx-react-shim-B-pYVQSG.js} +1 -1
  228. package/storybook-static/assets/{media-DsA0K_ZS.js → media-D2fdlN5C.js} +1 -1
  229. package/storybook-static/assets/{misc-zL4hFipW.js → misc-B5Fq527b.js} +1 -1
  230. package/storybook-static/assets/{notifications-BYXcjAgk.js → notifications-CdinTHBe.js} +1 -1
  231. package/storybook-static/assets/{odata-CZ14RE2x.js → odata-CpEOYNKi.js} +1 -1
  232. package/storybook-static/assets/odata-service-C0Syx7b6.js +1 -0
  233. package/storybook-static/assets/{odataStoryFixtures-Cv8XAuzz.js → odataStoryFixtures-dUEdLQNZ.js} +1 -1
  234. package/storybook-static/assets/{picker-DBhG__oJ.js → picker-Cuzrli2L.js} +1 -1
  235. package/storybook-static/assets/{popover-CahYWIfo.js → popover-BiSsB8FW.js} +1 -1
  236. package/storybook-static/assets/{preset-select-C5XCvtZE.js → preset-select-VPhuOafv.js} +1 -1
  237. package/storybook-static/assets/{react-18-BpKMg-Cr.js → react-18-Dj98SmrN.js} +1 -1
  238. package/storybook-static/assets/{react-DzMAKl9o.js → react-BuNie9Jj.js} +1 -1
  239. package/storybook-static/assets/{react-dom-BfFG7H_X.js → react-dom-H_XMZTBP.js} +1 -1
  240. package/storybook-static/assets/select-C0acjPk-.js +1 -0
  241. package/storybook-static/assets/{slider-CWiv9HFe.js → slider-DJkr9biy.js} +1 -1
  242. package/storybook-static/assets/{sortable-D_PcZ-1o.js → sortable-Wp4NkSxC.js} +1 -1
  243. package/storybook-static/assets/{syntaxhighlighter-RTCFPKCB-DatthS1s.js → syntaxhighlighter-RTCFPKCB-Bmk5Bc5f.js} +1 -1
  244. package/storybook-static/assets/{text-6oBGbhcX.js → text-TQB-LeS7.js} +1 -1
  245. package/storybook-static/assets/{theming-c9hibVvV.js → theming-BSLvozk8.js} +1 -1
  246. package/storybook-static/assets/ui-DaejdOMA.js +1 -0
  247. package/storybook-static/assets/{useODataSelectBase-BP43aYQp.js → useODataSelectBase-DTU8LMxW.js} +1 -1
  248. package/storybook-static/assets/{useODataTreeData-D-13yhFk.js → useODataTreeData-BIA97pbg.js} +1 -1
  249. package/storybook-static/assets/{utils-B7W0zPTP.js → utils-CJ9XKy2b.js} +1 -1
  250. package/storybook-static/iframe.html +1 -1
  251. package/storybook-static/index.json +1 -1
  252. package/storybook-static/project.json +1 -1
  253. package/dist/chunks/flex-CPO6xlPR.js.map +0 -1
  254. package/dist/chunks/grid-ByIIytjh.js.map +0 -1
  255. package/dist/image/ui/ImageSelection.d.ts +0 -40
  256. package/dist/image/ui/ImageSelection.d.ts.map +0 -1
  257. package/storybook-static/assets/Flex-CML6WrKV.js +0 -3
  258. package/storybook-static/assets/flex-fN9xAXRx.js +0 -1
  259. package/storybook-static/assets/formatter-L2YTDE3Q-BYPWeXB6.js +0 -1
  260. package/storybook-static/assets/grid-DnGlfdqF.js +0 -1
  261. package/storybook-static/assets/odata-service-FtP1kYQx.js +0 -1
  262. package/storybook-static/assets/select-C1fXLf5x.js +0 -1
  263. package/storybook-static/assets/ui-Cq8WdcMq.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/image/ui/ImageCropper.tsx","../../src/image/ui/ImagePlaceholder.tsx","../../src/image/ui/ImageRenderer.tsx","../../src/image/ui/ImageSelection.tsx","../../src/image/ui/ImageView.tsx"],"sourcesContent":["import { useCallback, useState } from \"react\";\n\nimport Cropper from \"react-easy-crop\";\n\nexport type CroppedAreaPixels = {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n};\n\nexport function ImageCropper({\n\timage,\n\taspect = 1200 / 630,\n\twidth,\n\tonCropComplete\n}: {\n\timage: string;\n\taspect?: number;\n\twidth?: number;\n\tonCropComplete?: (croppedAreaPixels: CroppedAreaPixels) => void;\n}) {\n\tconst [crop, setCrop] = useState({ x: 0, y: 0 });\n\tconst [zoom, setZoom] = useState(1);\n\n\tconst handleCropComplete = useCallback(\n\t\t(_croppedArea: unknown, croppedAreaPixels: CroppedAreaPixels) => {\n\t\t\tonCropComplete?.(croppedAreaPixels);\n\t\t},\n\t\t[onCropComplete]\n\t);\n\n\treturn (\n\t\t<div style={{ position: \"relative\", width: width ?? \"100%\", aspectRatio: aspect }}>\n\t\t\t<Cropper\n\t\t\t\timage={image}\n\t\t\t\tcrop={crop}\n\t\t\t\tzoom={zoom}\n\t\t\t\taspect={aspect}\n\t\t\t\tonCropChange={setCrop}\n\t\t\t\tonZoomChange={setZoom}\n\t\t\t\tonCropComplete={handleCropComplete}\n\t\t\t\tzoomSpeed={0.1}\n\t\t\t\tobjectFit=\"contain\"\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","interface ImagePlaceholderProps {\n\twidth?: number | string;\n\theight?: number | string;\n\taspectRatio?: string | \"unset\";\n\tclassName?: string;\n}\n\nexport function ImagePlaceholder({ width = \"100%\", height = \"100%\", aspectRatio = \"16 / 9\", className }: ImagePlaceholderProps) {\n\treturn (\n\t\t<div style={{ width, height, aspectRatio }} className={className}>\n\t\t\t<svg\n\t\t\t\twidth={width}\n\t\t\t\theight={height}\n\t\t\t\tviewBox=\"0 0 200 200\"\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\trole=\"img\"\n\t\t\t\tfill=\"none\"\n\t\t\t\trx=\"10\"\n\t\t\t\try=\"10\"\n\t\t\t\tstyle={{ display: \"block\" }}\n\t\t\t\taria-label=\"Изображение недоступно\">\n\t\t\t\t{/* <rect width=\"200\" height=\"200\" fill=\"var(--surface-2)\" rx=\"10\" ry=\"10\" /> */}\n\t\t\t\t<g fill=\"var(--surface-0)\">\n\t\t\t\t\t<rect x=\"40\" y=\"50\" width=\"120\" height=\"100\" rx=\"10\" />\n\n\t\t\t\t\t<circle cx=\"60\" cy=\"70\" r=\"8\" fill=\"var(--surface-2)\" />\n\n\t\t\t\t\t<path d=\"M50 130 L75 100 L100 130 Z\" fill=\"var(--surface-2)\" />\n\t\t\t\t\t<path d=\"M90 130 L120 90 L150 130 Z\" fill=\"var(--surface-2)\" />\n\n\t\t\t\t\t<line x1=\"160\" y1=\"40\" x2=\"40\" y2=\"160\" stroke=\"var(--surface-0)\" strokeWidth=\"15\" strokeLinecap=\"round\" />\n\t\t\t\t\t<line x1=\"160\" y1=\"40\" x2=\"40\" y2=\"160\" stroke=\"var(--surface-2)\" strokeWidth=\"5\" strokeLinecap=\"round\" />\n\t\t\t\t</g>\n\t\t\t</svg>\n\t\t</div>\n\t);\n}\n","import { type CSSProperties, type ImgHTMLAttributes, type ReactNode, useEffect, useRef, useState } from \"react\";\n\nimport { ImagePlaceholder } from \"./ImagePlaceholder\";\n\nexport type ImageSource = {\n\tsrcSet: string;\n\ttype?: string;\n\tsizes?: string;\n};\n\nexport interface ImageRendererProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, \"src\"> {\n\tsrc: string;\n\tsources?: readonly ImageSource[];\n\talt?: string;\n\trole?: string;\n\tariaLabel?: string;\n\tcaption?: string;\n\tfallback?: ReactNode;\n\tuseFigure?: boolean;\n\taspectRatio?: string | \"unset\";\n\twrapperStyle?: CSSProperties;\n}\n\n/**\n * Базовый рендер изображения: lazy-появление, placeholder, обработка ошибки и figure/caption.\n * Компонент не знает, как устроено хранилище и какие форматы/размеры доступны.\n */\nexport function ImageRenderer({\n\tsrc,\n\tsources,\n\talt,\n\trole,\n\tariaLabel,\n\tcaption,\n\tfallback,\n\tuseFigure = false,\n\twidth = \"100%\",\n\theight = \"100%\",\n\taspectRatio = \"16 / 9\",\n\tstyle,\n\twrapperStyle,\n\t...imgProps\n}: ImageRendererProps) {\n\tconst wrapperRef = useRef<HTMLDivElement | null>(null);\n\tconst [containerWidth, setContainerWidth] = useState(0);\n\tconst [isVisible, setIsVisible] = useState(false);\n\tconst [hasLoaded, setHasLoaded] = useState(false);\n\tconst [hasError, setHasError] = useState(false);\n\n\tuseEffect(() => {\n\t\tconst observer = new IntersectionObserver(\n\t\t\t([entry]) => {\n\t\t\t\tif (entry.isIntersecting) {\n\t\t\t\t\tconst parentWidth = Math.round(entry.boundingClientRect.width);\n\n\t\t\t\t\tsetContainerWidth(parentWidth);\n\t\t\t\t\tsetIsVisible(true);\n\t\t\t\t\tobserver.disconnect();\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ rootMargin: \"100px\", threshold: 0.01 }\n\t\t);\n\n\t\tif (wrapperRef.current) {\n\t\t\tobserver.observe(wrapperRef.current);\n\t\t}\n\n\t\treturn () => observer.disconnect();\n\t}, []);\n\n\tconst sizesAttr = containerWidth ? `${containerWidth}px` : \"100vw\";\n\tconst defaultFallback = <ImagePlaceholder width={width} height={height} aspectRatio={aspectRatio} />;\n\n\tconst content = (\n\t\t<>\n\t\t\t{!hasLoaded && !hasError && (fallback || defaultFallback)}\n\t\t\t{isVisible && !hasError && (\n\t\t\t\t<picture>\n\t\t\t\t\t{sources?.map((source) => (\n\t\t\t\t\t\t<source\n\t\t\t\t\t\t\tkey={`${source.type ?? \"source\"}-${source.srcSet}`}\n\t\t\t\t\t\t\tsrcSet={source.srcSet}\n\t\t\t\t\t\t\ttype={source.type}\n\t\t\t\t\t\t\tsizes={source.sizes ?? sizesAttr}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc={src}\n\t\t\t\t\t\talt={alt}\n\t\t\t\t\t\trole={role}\n\t\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\t\tonLoad={() => setHasLoaded(true)}\n\t\t\t\t\t\tonError={() => setHasError(true)}\n\t\t\t\t\t\tstyle={!hasLoaded ? { display: \"none\" } : { width: \"100%\", height: \"100%\", objectFit: \"cover\", ...style }}\n\t\t\t\t\t\taria-busy={!hasLoaded}\n\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\theight=\"100%\"\n\t\t\t\t\t\t{...imgProps}\n\t\t\t\t\t/>\n\t\t\t\t</picture>\n\t\t\t)}\n\t\t\t{hasError && defaultFallback}\n\t\t</>\n\t);\n\n\tconst wrapped = (\n\t\t<div ref={wrapperRef} style={{ width, height, aspectRatio, ...wrapperStyle }}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\treturn useFigure ? (\n\t\t<figure className=\"relative\">\n\t\t\t{wrapped}\n\t\t\t{caption && (\n\t\t\t\t<figcaption\n\t\t\t\t\tstyle={{ bottom: 2, right: 2, maxWidth: \"calc(100% - 4px)\" }}\n\t\t\t\t\tclassName=\"absolute paddingInlineMd textRight radiusSm fontSizeSm\">\n\t\t\t\t\t{caption}\n\t\t\t\t</figcaption>\n\t\t\t)}\n\t\t</figure>\n\t) : (\n\t\twrapped\n\t);\n}\n","import { CSSProperties, ReactNode, useCallback, useMemo, useState } from \"react\";\n\nimport { ReadFileResult } from \"@ryuzaki13/react-foundation-lib/file\";\nimport Cropper from \"react-easy-crop\";\n\nimport { Button } from \"../../button\";\nimport { GridContainer } from \"../../grid\";\nimport { InputText } from \"../../input\";\nimport { InputFiles } from \"../../input-files\";\nimport { Modal, ModalContent, ModalFooter } from \"../../modal\";\n\nimport { CroppedAreaPixels } from \"./ImageCropper\";\n\ntype SelectedImageFile = Extract<ReadFileResult, { mode: \"data-url\" }>;\n\n/**\n * Данные одного выбранного изображения, которые нужны вызывающему коду:\n * исходный файл, пользовательское описание и выбранная область обрезки.\n */\nexport type SelectedImageData = {\n\tfile: SelectedImageFile;\n\talt: string;\n\tcrop?: CroppedAreaPixels;\n};\n\ninterface ImageSelectionPanelProps {\n\taspect?: number;\n\tdisabled?: boolean;\n\tvalue?: SelectedImageData[];\n\tdefaultValue?: SelectedImageData[];\n\tonChange?: (data: SelectedImageData[]) => void;\n\tonApply?: (data: SelectedImageData[]) => void;\n\trenderActions?: (data: ImageSelectionActionsData) => ReactNode;\n}\n\ninterface ImageSelectionModalProps extends ImageSelectionPanelProps {\n\tisOpen?: boolean;\n\tonClose?: () => void;\n\ttitle?: string;\n}\n\ninterface ImageSelectionActionsData {\n\tvalue: SelectedImageData[];\n\tactiveIndex: number;\n\thasSelected: boolean;\n\tcanApply: boolean;\n\tapply: () => void;\n}\n\ninterface ImageSelectionState extends ImageSelectionActionsData {\n\tfiles: SelectedImageFile[];\n\tactiveImage?: SelectedImageData;\n\tactiveCropperState: ImageCropperState;\n\tsetFiles: (files: SelectedImageFile[]) => void;\n\tsetActiveIndex: (index: number) => void;\n\tsetActiveAlt: (alt: string) => void;\n\tsetActiveCrop: (crop: CroppedAreaPixels) => void;\n\tsetActiveCropperCrop: (crop: CropperPoint) => void;\n\tsetActiveCropperZoom: (zoom: number) => void;\n}\n\ntype ImageSize = {\n\twidth: number;\n\theight: number;\n};\n\ntype CropperPoint = {\n\tx: number;\n\ty: number;\n};\n\ntype ImageCropperState = {\n\tcrop: CropperPoint;\n\tzoom: number;\n};\n\nfunction getImageKey(image: SelectedImageData, index: number) {\n\treturn `${image.file.meta.name}-${image.file.meta.size}-${image.file.meta.lastModified}-${index}`;\n}\n\n/**\n * Хранит черновик выбора изображений локально даже в controlled-режиме.\n * Это позволяет не дергать внешний onChange на каждый onCropComplete,\n * а отправлять готовый массив только при явном применении.\n */\nfunction useImageSelectionState({\n\tvalue,\n\tdefaultValue,\n\tdisabled,\n\tonChange,\n\tonApply\n}: Pick<ImageSelectionPanelProps, \"value\" | \"defaultValue\" | \"disabled\" | \"onChange\" | \"onApply\">): ImageSelectionState {\n\tconst isControlled = value !== undefined;\n\tconst [draftValue, setDraftValue] = useState<SelectedImageData[]>(value ?? defaultValue ?? []);\n\tconst [controlledValueSnapshot, setControlledValueSnapshot] = useState(value);\n\tconst [requestedActiveIndex, setActiveIndex] = useState(0);\n\tconst [cropperStateByImage, setCropperStateByImage] = useState<Record<string, ImageCropperState>>({});\n\n\tif (isControlled && value !== controlledValueSnapshot) {\n\t\tsetControlledValueSnapshot(value);\n\t\tsetDraftValue(value ?? []);\n\t}\n\n\tconst updateDraftValue = useCallback((updater: (currentValue: SelectedImageData[]) => SelectedImageData[]) => {\n\t\tsetDraftValue((currentValue) => updater(currentValue));\n\t}, []);\n\n\tconst files = useMemo(() => draftValue.map((image) => image.file), [draftValue]);\n\tconst activeIndex = draftValue.length === 0 ? 0 : Math.min(requestedActiveIndex, draftValue.length - 1);\n\tconst activeImage = draftValue[activeIndex];\n\tconst activeImageKey = activeImage ? getImageKey(activeImage, activeIndex) : undefined;\n\tconst activeCropperState = activeImageKey\n\t\t? (cropperStateByImage[activeImageKey] ?? { crop: { x: 0, y: 0 }, zoom: 1 })\n\t\t: { crop: { x: 0, y: 0 }, zoom: 1 };\n\tconst hasSelected = draftValue.length > 0;\n\tconst canApply = !disabled && hasSelected && draftValue.every((image) => image.alt.trim() && image.crop);\n\n\tconst setFiles = useCallback(\n\t\t(nextFiles: SelectedImageFile[]) => {\n\t\t\tupdateDraftValue((currentValue) =>\n\t\t\t\tnextFiles.map((file) => {\n\t\t\t\t\t// Сохраняем alt и crop при переключении, удалении и добавлении файлов.\n\t\t\t\t\tconst existingImage = currentValue.find((image) => image.file.file === file.file);\n\n\t\t\t\t\tif (existingImage) {\n\t\t\t\t\t\treturn { ...existingImage, file };\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { file, alt: \"\" };\n\t\t\t\t})\n\t\t\t);\n\t\t},\n\t\t[updateDraftValue]\n\t);\n\n\tconst setActiveAlt = useCallback(\n\t\t(alt: string) => {\n\t\t\tupdateDraftValue((currentValue) => currentValue.map((image, index) => (index === activeIndex ? { ...image, alt } : image)));\n\t\t},\n\t\t[activeIndex, updateDraftValue]\n\t);\n\n\tconst setActiveCrop = useCallback(\n\t\t(crop: CroppedAreaPixels) => {\n\t\t\tupdateDraftValue((currentValue) => currentValue.map((image, index) => (index === activeIndex ? { ...image, crop } : image)));\n\t\t},\n\t\t[activeIndex, updateDraftValue]\n\t);\n\n\tconst setActiveCropperCrop = useCallback(\n\t\t(crop: CropperPoint) => {\n\t\t\tif (!activeImageKey) return;\n\n\t\t\tsetCropperStateByImage((currentState) => ({\n\t\t\t\t...currentState,\n\t\t\t\t[activeImageKey]: {\n\t\t\t\t\tcrop,\n\t\t\t\t\tzoom: currentState[activeImageKey]?.zoom ?? 1\n\t\t\t\t}\n\t\t\t}));\n\t\t},\n\t\t[activeImageKey]\n\t);\n\n\tconst setActiveCropperZoom = useCallback(\n\t\t(zoom: number) => {\n\t\t\tif (!activeImageKey) return;\n\n\t\t\tsetCropperStateByImage((currentState) => ({\n\t\t\t\t...currentState,\n\t\t\t\t[activeImageKey]: {\n\t\t\t\t\tcrop: currentState[activeImageKey]?.crop ?? { x: 0, y: 0 },\n\t\t\t\t\tzoom\n\t\t\t\t}\n\t\t\t}));\n\t\t},\n\t\t[activeImageKey]\n\t);\n\n\tconst apply = useCallback(() => {\n\t\tonChange?.(draftValue);\n\t\tonApply?.(draftValue);\n\t}, [draftValue, onApply, onChange]);\n\n\treturn {\n\t\tvalue: draftValue,\n\t\tfiles,\n\t\tactiveIndex,\n\t\tactiveImage,\n\t\tactiveCropperState,\n\t\thasSelected,\n\t\tcanApply,\n\t\tapply,\n\t\tsetFiles,\n\t\tsetActiveIndex,\n\t\tsetActiveAlt,\n\t\tsetActiveCrop,\n\t\tsetActiveCropperCrop,\n\t\tsetActiveCropperZoom\n\t};\n}\n\nfunction resolveImageUploadMaxBytes(): number | undefined {\n\tif (typeof __IMAGE_UPLOAD_MAX_BYTES__ !== \"number\") return undefined;\n\treturn __IMAGE_UPLOAD_MAX_BYTES__;\n}\n\nfunction getPreviewImageStyle(image: SelectedImageData, size: ImageSize | undefined, aspect: number): CSSProperties {\n\tif (!image.crop || !size) {\n\t\treturn {\n\t\t\twidth: \"100%\",\n\t\t\taspectRatio: aspect,\n\t\t\tobjectFit: \"cover\",\n\t\t\tdisplay: \"block\"\n\t\t};\n\t}\n\n\tconst crop = image.crop;\n\n\t// Миниатюра масштабирует исходник так, чтобы видимой оставалась только выбранная область crop.\n\treturn {\n\t\tposition: \"absolute\",\n\t\tleft: `${-(crop.x / crop.width) * 100}%`,\n\t\ttop: `${-(crop.y / crop.height) * 100}%`,\n\t\twidth: `${(size.width / crop.width) * 100}%`,\n\t\theight: `${(size.height / crop.height) * 100}%`,\n\t\tmaxWidth: \"none\"\n\t};\n}\n\nfunction ImageSelectionFields({ aspect = 16 / 9, disabled, state }: { aspect?: number; disabled?: boolean; state: ImageSelectionState }) {\n\tconst area = state.activeImage?.crop;\n\tconst [imageSizes, setImageSizes] = useState<Record<string, ImageSize>>({});\n\n\treturn (\n\t\t<GridContainer gap=\"md\">\n\t\t\t<InputFiles\n\t\t\t\tlabel=\"Файл изображения\"\n\t\t\t\tallowedMime={[\"image/jpeg\", \"image/png\", \"image/webp\", \"image/avif\"]}\n\t\t\t\tvalue={state.files}\n\t\t\t\tonChange={state.setFiles}\n\t\t\t\tmaxBytes={resolveImageUploadMaxBytes()}\n\t\t\t\tonReadError={(e) => console.log(\"e\", e)}\n\t\t\t/>\n\n\t\t\t{state.hasSelected && state.activeImage && (\n\t\t\t\t<div>\n\t\t\t\t\t<GridContainer templateColumns=\"repeat(auto-fill, minmax(10em, 1fr))\" gap=\"xs\">\n\t\t\t\t\t\t{state.value.map((image, index) => {\n\t\t\t\t\t\t\tconst imageKey = getImageKey(image, index);\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tkey={imageKey}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\tonClick={() => state.setActiveIndex(index)}\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\t\t\t\t\tborder: index === state.activeIndex ? \"2px solid var(--border-accent)\" : \"2px solid transparent\",\n\t\t\t\t\t\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\t\t\t\t\t\tcursor: disabled ? \"default\" : \"pointer\"\n\t\t\t\t\t\t\t\t\t}}>\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\t\t\t\t\t\t\tdisplay: \"block\",\n\t\t\t\t\t\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\t\t\t\t\t\taspectRatio: aspect,\n\t\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\"\n\t\t\t\t\t\t\t\t\t\t}}>\n\t\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\t\tsrc={image.file.dataUrl}\n\t\t\t\t\t\t\t\t\t\t\tstyle={getPreviewImageStyle(image, imageSizes[imageKey], aspect)}\n\t\t\t\t\t\t\t\t\t\t\tonLoad={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\tconst target = event.currentTarget;\n\n\t\t\t\t\t\t\t\t\t\t\t\tsetImageSizes((currentSizes) => ({\n\t\t\t\t\t\t\t\t\t\t\t\t\t...currentSizes,\n\t\t\t\t\t\t\t\t\t\t\t\t\t[imageKey]: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth: target.naturalWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\theight: target.naturalHeight\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</GridContainer>\n\t\t\t\t\t<div>\n\t\t\t\t\t\tВыберите область изображения{\" \"}\n\t\t\t\t\t\t{area &&\n\t\t\t\t\t\t\t(area.width < 1200 ? (\n\t\t\t\t\t\t\t\t<code className=\"statusError\">\n\t\t\t\t\t\t\t\t\t{area.width}x{area.height} - низкое качество изображения!\n\t\t\t\t\t\t\t\t</code>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<code className=\"statusSuccess\">\n\t\t\t\t\t\t\t\t\t{area.width}x{area.height}\n\t\t\t\t\t\t\t\t</code>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div style={{ position: \"relative\", width: \"100%\", aspectRatio: aspect }}>\n\t\t\t\t\t\t<Cropper\n\t\t\t\t\t\t\tkey={getImageKey(state.activeImage, state.activeIndex)}\n\t\t\t\t\t\t\timage={state.activeImage.file.dataUrl}\n\t\t\t\t\t\t\tcrop={state.activeCropperState.crop}\n\t\t\t\t\t\t\tzoom={state.activeCropperState.zoom}\n\t\t\t\t\t\t\taspect={aspect}\n\t\t\t\t\t\t\tonCropChange={state.setActiveCropperCrop}\n\t\t\t\t\t\t\tonZoomChange={state.setActiveCropperZoom}\n\t\t\t\t\t\t\tonCropComplete={(_croppedArea, croppedAreaPixels) => state.setActiveCrop(croppedAreaPixels)}\n\t\t\t\t\t\t\tzoomSpeed={0.1}\n\t\t\t\t\t\t\tobjectFit=\"contain\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t<InputText\n\t\t\t\trequired\n\t\t\t\tdisabled={!state.hasSelected || disabled}\n\t\t\t\tlabel=\"Краткое описание изображения\"\n\t\t\t\tplaceholder=\"\"\n\t\t\t\tvalue={state.activeImage?.alt ?? \"\"}\n\t\t\t\tonChange={state.setActiveAlt}\n\t\t\t/>\n\t\t</GridContainer>\n\t);\n}\n\nexport function ImageSelectionPanel({ aspect = 16 / 9, disabled, renderActions, ...props }: ImageSelectionPanelProps) {\n\tconst state = useImageSelectionState({ ...props, disabled });\n\tconst actionsData = {\n\t\tvalue: state.value,\n\t\tactiveIndex: state.activeIndex,\n\t\thasSelected: state.hasSelected,\n\t\tcanApply: state.canApply,\n\t\tapply: state.apply\n\t};\n\tconst hasApplyHandler = props.onChange !== undefined || props.onApply !== undefined;\n\n\treturn (\n\t\t<>\n\t\t\t<ImageSelectionFields aspect={aspect} disabled={disabled} state={state} />\n\t\t\t{renderActions\n\t\t\t\t? renderActions(actionsData)\n\t\t\t\t: hasApplyHandler && (\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<Button disabled={!state.canApply} tone=\"success\" onClick={state.apply}>\n\t\t\t\t\t\t\t\tПрименить\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t</>\n\t);\n}\n\nexport function ImageSelectionModal({\n\taspect = 16 / 9,\n\tdisabled,\n\tisOpen = true,\n\tonClose = () => {},\n\ttitle = \"Загрузка нового изображения\",\n\t...props\n}: ImageSelectionModalProps) {\n\tconst state = useImageSelectionState({ ...props, disabled });\n\tconst hasApplyHandler = props.onChange !== undefined || props.onApply !== undefined;\n\n\tif (!hasApplyHandler) {\n\t\treturn (\n\t\t\t<Modal isOpen={isOpen} onClose={onClose} title={title} size=\"xl\">\n\t\t\t\t<ModalContent scrollable>\n\t\t\t\t\t<ImageSelectionFields aspect={aspect} disabled={disabled} state={state} />\n\t\t\t\t</ModalContent>\n\t\t\t</Modal>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={onClose} title={title} size=\"xl\">\n\t\t\t<ModalContent scrollable>\n\t\t\t\t<ImageSelectionFields aspect={aspect} disabled={disabled} state={state} />\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button disabled={!state.canApply} tone=\"success\" onClick={state.apply}>\n\t\t\t\t\tПрименить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { type ImgHTMLAttributes, type ReactNode } from \"react\";\n\nimport { ImageRenderer, type ImageSource } from \"./ImageRenderer\";\n\nexport type ImageFormat = \"avif\" | \"webp\" | \"jpeg\" | \"jpg\" | \"png\";\n\nconst DEFAULT_SET_WIDTHS = [2880, 1920, 1280, 640, 320] as const;\nconst DEFAULT_SET_FORMATS = [\"avif\", \"webp\"] as const satisfies readonly ImageFormat[];\n\nexport type StoredImageData = {\n\tfilename: string;\n\tpath: string;\n\twidth?: number;\n\theight?: number;\n\talt?: string;\n\thasSet?: boolean;\n};\n\ninterface ImageViewProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, \"src\" | \"alt\"> {\n\t/** Запись из таблицы Image. Предпочтительный способ передать изображение из БД. */\n\timage?: StoredImageData;\n\t/** Базовое имя файла из БД. Для новых изображений это md5 без расширения. */\n\tsrc?: string;\n\t/** Путь из БД относительно публичного корня, например `images/articles`. */\n\tpath?: string;\n\talt?: string;\n\trole?: string;\n\tariaLabel?: string;\n\tcaption?: string;\n\tfallback?: ReactNode;\n\tuseFigure?: boolean;\n\taspectRatio?: string | \"unset\";\n\t/** Форматы, которые реально лежат в хранилище для текущего изображения. */\n\tformats?: readonly ImageFormat[];\n\t/** Формат для img.src. Должен существовать в хранилище. */\n\tfallbackFormat?: ImageFormat;\n\t/** Набор размеров для файлов вида base@width.format. */\n\tvariantWidths?: readonly number[];\n\t/** Признак наличия responsive-набора. Если false, @size srcSet не строится. */\n\thasSet?: boolean;\n}\n\nfunction getImageMime(format: ImageFormat): string {\n\tif (format === \"jpg\" || format === \"jpeg\") {\n\t\treturn \"image/jpeg\";\n\t}\n\n\treturn `image/${format}`;\n}\n\nfunction normalizeImagePath(path?: string): string {\n\tif (!path) return \"\";\n\n\treturn path.replace(/^\\/+|\\/+$/g, \"\");\n}\n\nfunction buildImageBasePath(path: string | undefined, filename: string): string {\n\tconst normalizedPath = normalizeImagePath(path);\n\n\treturn normalizedPath ? `/${normalizedPath}/${filename}` : `/${filename}`;\n}\n\nfunction buildImageSources({\n\tbasePath,\n\tformats,\n\tvariantWidths,\n\thasSet\n}: {\n\tbasePath: string;\n\tformats: readonly ImageFormat[];\n\tvariantWidths: readonly number[];\n\thasSet: boolean;\n}): ImageSource[] {\n\tif (!hasSet) {\n\t\treturn formats.map((format) => ({\n\t\t\tsrcSet: `${basePath}.${format}`,\n\t\t\ttype: getImageMime(format)\n\t\t}));\n\t}\n\n\treturn formats.map((format) => ({\n\t\tsrcSet: variantWidths.map((width) => `${basePath}@${width}.${format} ${width}w`).join(\", \"),\n\t\ttype: getImageMime(format)\n\t}));\n}\n\n/**\n * Адаптер для изображений из таблицы Image.\n * Компонент строит пути только из данных БД: path + filename + формат/размер.\n */\nexport function ImageView({\n\timage,\n\tsrc,\n\tpath,\n\talt,\n\tformats = DEFAULT_SET_FORMATS,\n\tfallbackFormat,\n\tvariantWidths = DEFAULT_SET_WIDTHS,\n\thasSet,\n\taspectRatio,\n\t...props\n}: ImageViewProps) {\n\tconst filename = image?.filename ?? src;\n\n\tif (!filename) {\n\t\treturn <ImageRenderer src=\"\" alt={alt ?? image?.alt} {...props} />;\n\t}\n\n\tconst resolvedPath = image?.path ?? path;\n\tconst resolvedHasSet = hasSet ?? image?.hasSet ?? true;\n\tconst resolvedFormats = formats.length > 0 ? formats : DEFAULT_SET_FORMATS;\n\tconst resolvedFallbackFormat = fallbackFormat ?? resolvedFormats[resolvedFormats.length - 1] ?? \"webp\";\n\tconst basePath = buildImageBasePath(resolvedPath, filename);\n\tconst resolvedAspectRatio = aspectRatio ?? (image?.width && image.height ? `${image.width} / ${image.height}` : undefined);\n\tconst sources = buildImageSources({\n\t\tbasePath,\n\t\tformats: resolvedFormats,\n\t\tvariantWidths,\n\t\thasSet: resolvedHasSet\n\t});\n\n\treturn (\n\t\t<ImageRenderer\n\t\t\tsrc={`${basePath}.${resolvedFallbackFormat}`}\n\t\t\tsources={sources}\n\t\t\talt={alt ?? image?.alt}\n\t\t\taspectRatio={resolvedAspectRatio}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/image/lib/buildImageSrcSet.ts","../../src/image/lib/buildImageSources.ts","../../src/image/ui/ImageCropper.tsx","../../src/image/ui/ImagePlaceholder.tsx","../../src/image/ui/ImageRenderer.tsx","../../src/image/lib/getImageSelectionKey.ts","../../src/image/model/useImageSelectionState.ts","../../src/image/lib/getImageCropPreviewStyle.ts","../../src/image/ui/ImageSelectionFields.tsx","../../src/image/ui/ImageSelectionModal.tsx","../../src/image/ui/ImageSelectionPanel.tsx","../../src/image/ui/ImageView.tsx"],"sourcesContent":["import { type ImageCandidate } from \"../model/imageTypes\";\n\n/** Собирает валидный srcset из уже разрешённых вызывающим кодом URL вариантов. */\nexport function buildImageSrcSet(candidates: readonly ImageCandidate[]): string {\n\treturn candidates\n\t\t.map((candidate) => (\"width\" in candidate ? `${candidate.src} ${candidate.width}w` : `${candidate.src} ${candidate.density}x`))\n\t\t.join(\", \");\n}\n","import { type ImageSource, type ResponsiveImageSource } from \"../model/imageTypes\";\n\nimport { buildImageSrcSet } from \"./buildImageSrcSet\";\n\n/** Преобразует декларативные наборы кандидатов в готовые source-дескрипторы. */\nexport function buildImageSources(sources: readonly ResponsiveImageSource[] | undefined, defaultSizes?: string): ImageSource[] {\n\treturn (sources ?? [])\n\t\t.map((source) => ({\n\t\t\tsrcSet: buildImageSrcSet(source.candidates),\n\t\t\ttype: source.type,\n\t\t\tsizes: source.sizes ?? defaultSizes\n\t\t}))\n\t\t.filter((source) => source.srcSet.length > 0);\n}\n","import { useCallback, useState } from \"react\";\n\nimport Cropper from \"react-easy-crop\";\n\nimport { type ImageCropArea, type ImageCropperProps, type ImageCropPoint } from \"../model/imageCropTypes\";\n\nconst DEFAULT_CROP: ImageCropPoint = { x: 0, y: 0 };\n\n/**\n * Управляемая или автономная область обрезки изображения.\n * Числовой aspect задаётся вызывающим кодом и не связан с назначением изображения.\n */\nexport function ImageCropper({\n\timage,\n\taspect = 16 / 9,\n\twidth = \"100%\",\n\tclassName,\n\tstyle,\n\tcrop,\n\tdefaultCrop = DEFAULT_CROP,\n\tzoom,\n\tdefaultZoom = 1,\n\tminZoom = 1,\n\tmaxZoom = 3,\n\tzoomSpeed = 0.1,\n\tobjectFit = \"contain\",\n\tdisabled = false,\n\tonCropChange,\n\tonZoomChange,\n\tonCropComplete\n}: ImageCropperProps) {\n\tconst [uncontrolledCrop, setUncontrolledCrop] = useState(defaultCrop);\n\tconst [uncontrolledZoom, setUncontrolledZoom] = useState(defaultZoom);\n\tconst resolvedCrop = crop ?? uncontrolledCrop;\n\tconst resolvedZoom = zoom ?? uncontrolledZoom;\n\n\tconst handleCropChange = useCallback(\n\t\t(nextCrop: ImageCropPoint) => {\n\t\t\tif (disabled) return;\n\n\t\t\tif (crop === undefined) {\n\t\t\t\tsetUncontrolledCrop(nextCrop);\n\t\t\t}\n\n\t\t\tonCropChange?.(nextCrop);\n\t\t},\n\t\t[crop, disabled, onCropChange]\n\t);\n\n\tconst handleZoomChange = useCallback(\n\t\t(nextZoom: number) => {\n\t\t\tif (disabled) return;\n\n\t\t\tif (zoom === undefined) {\n\t\t\t\tsetUncontrolledZoom(nextZoom);\n\t\t\t}\n\n\t\t\tonZoomChange?.(nextZoom);\n\t\t},\n\t\t[disabled, onZoomChange, zoom]\n\t);\n\n\tconst handleCropComplete = useCallback(\n\t\t(croppedAreaPercentages: ImageCropArea, croppedAreaPixels: ImageCropArea) => {\n\t\t\tif (disabled) return;\n\n\t\t\tonCropComplete?.(croppedAreaPixels, croppedAreaPercentages);\n\t\t},\n\t\t[disabled, onCropComplete]\n\t);\n\n\treturn (\n\t\t<div\n\t\t\tclassName={className}\n\t\t\tstyle={{ position: \"relative\", width, aspectRatio: aspect, pointerEvents: disabled ? \"none\" : undefined, ...style }}>\n\t\t\t<Cropper\n\t\t\t\timage={image}\n\t\t\t\tcrop={resolvedCrop}\n\t\t\t\tzoom={resolvedZoom}\n\t\t\t\taspect={aspect}\n\t\t\t\tminZoom={minZoom}\n\t\t\t\tmaxZoom={maxZoom}\n\t\t\t\tzoomSpeed={zoomSpeed}\n\t\t\t\tobjectFit={objectFit}\n\t\t\t\tonCropChange={handleCropChange}\n\t\t\t\tonZoomChange={handleZoomChange}\n\t\t\t\tonCropComplete={handleCropComplete}\n\t\t\t\tcropperProps={{ \"aria-disabled\": disabled || undefined }}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","export interface ImagePlaceholderProps {\n\twidth?: number | string;\n\theight?: number | string;\n\taspectRatio?: string | \"unset\";\n\tclassName?: string;\n}\n\nexport function ImagePlaceholder({ width = \"100%\", height = \"100%\", aspectRatio = \"16 / 9\", className }: ImagePlaceholderProps) {\n\treturn (\n\t\t<div style={{ width, height, aspectRatio }} className={className}>\n\t\t\t<svg\n\t\t\t\twidth={width}\n\t\t\t\theight={height}\n\t\t\t\tviewBox=\"0 0 200 200\"\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\trole=\"img\"\n\t\t\t\tfill=\"none\"\n\t\t\t\trx=\"10\"\n\t\t\t\try=\"10\"\n\t\t\t\tstyle={{ display: \"block\" }}\n\t\t\t\taria-label=\"Изображение недоступно\">\n\t\t\t\t{/* <rect width=\"200\" height=\"200\" fill=\"var(--surface-2)\" rx=\"10\" ry=\"10\" /> */}\n\t\t\t\t<g fill=\"var(--surface-0)\">\n\t\t\t\t\t<rect x=\"40\" y=\"50\" width=\"120\" height=\"100\" rx=\"10\" />\n\n\t\t\t\t\t<circle cx=\"60\" cy=\"70\" r=\"8\" fill=\"var(--surface-2)\" />\n\n\t\t\t\t\t<path d=\"M50 130 L75 100 L100 130 Z\" fill=\"var(--surface-2)\" />\n\t\t\t\t\t<path d=\"M90 130 L120 90 L150 130 Z\" fill=\"var(--surface-2)\" />\n\n\t\t\t\t\t<line x1=\"160\" y1=\"40\" x2=\"40\" y2=\"160\" stroke=\"var(--surface-0)\" strokeWidth=\"15\" strokeLinecap=\"round\" />\n\t\t\t\t\t<line x1=\"160\" y1=\"40\" x2=\"40\" y2=\"160\" stroke=\"var(--surface-2)\" strokeWidth=\"5\" strokeLinecap=\"round\" />\n\t\t\t\t</g>\n\t\t\t</svg>\n\t\t</div>\n\t);\n}\n","import { type CSSProperties, type ImgHTMLAttributes, type ReactNode, useEffect, useRef, useState } from \"react\";\n\nimport { type ImageLayout, type ImageSource } from \"../model/imageTypes\";\n\nimport { ImagePlaceholder } from \"./ImagePlaceholder\";\n\nexport interface ImageRendererProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, \"src\" | \"width\" | \"height\"> {\n\tsrc: string;\n\tsources?: readonly ImageSource[];\n\tlayout?: ImageLayout;\n\talt?: string;\n\trole?: string;\n\tariaLabel?: string;\n\tcaption?: string;\n\tfallback?: ReactNode;\n\tuseFigure?: boolean;\n\taspectRatio?: string | \"unset\";\n\twidth?: CSSProperties[\"width\"];\n\theight?: CSSProperties[\"height\"];\n\tintrinsicWidth?: number;\n\tintrinsicHeight?: number;\n\twrapperStyle?: CSSProperties;\n}\n\n/**\n * Базовый рендер изображения: lazy-появление, placeholder, обработка ошибки и figure/caption.\n * Компонент не знает, как устроено хранилище и какие форматы/размеры доступны.\n */\nexport function ImageRenderer({\n\tsrc,\n\tsources,\n\talt,\n\trole,\n\tariaLabel,\n\tcaption,\n\tfallback,\n\tuseFigure = false,\n\tlayout = \"cover\",\n\twidth = \"100%\",\n\theight = \"100%\",\n\taspectRatio,\n\tintrinsicWidth,\n\tintrinsicHeight,\n\tonLoad,\n\tonError,\n\tstyle,\n\twrapperStyle,\n\t...imgProps\n}: ImageRendererProps) {\n\tconst wrapperRef = useRef<HTMLDivElement | null>(null);\n\tconst [containerWidth, setContainerWidth] = useState(0);\n\tconst [isVisible, setIsVisible] = useState(false);\n\tconst [hasLoaded, setHasLoaded] = useState(false);\n\tconst [hasError, setHasError] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (typeof IntersectionObserver === \"undefined\") {\n\t\t\t// Отложенный fallback сохраняет одинаковый первый render на сервере и в браузере без IntersectionObserver.\n\t\t\tconst timeoutId = window.setTimeout(() => setIsVisible(true), 0);\n\n\t\t\treturn () => window.clearTimeout(timeoutId);\n\t\t}\n\n\t\tconst observer = new IntersectionObserver(\n\t\t\t([entry]) => {\n\t\t\t\tif (entry.isIntersecting) {\n\t\t\t\t\tconst parentWidth = Math.round(entry.boundingClientRect.width);\n\n\t\t\t\t\tsetContainerWidth(parentWidth);\n\t\t\t\t\tsetIsVisible(true);\n\t\t\t\t\tobserver.disconnect();\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ rootMargin: \"100px\", threshold: 0.01 }\n\t\t);\n\n\t\tif (wrapperRef.current) {\n\t\t\tobserver.observe(wrapperRef.current);\n\t\t}\n\n\t\treturn () => observer.disconnect();\n\t}, []);\n\n\tconst isIntrinsic = layout === \"intrinsic\";\n\tconst resolvedHeight = isIntrinsic ? \"auto\" : height;\n\tconst intrinsicAspectRatio = intrinsicWidth && intrinsicHeight ? `${intrinsicWidth} / ${intrinsicHeight}` : undefined;\n\tconst resolvedAspectRatio = isIntrinsic ? (intrinsicAspectRatio ?? aspectRatio ?? \"auto\") : (aspectRatio ?? \"16 / 9\");\n\tconst placeholderHeight = isIntrinsic && resolvedAspectRatio !== \"auto\" && resolvedAspectRatio !== \"unset\" ? \"100%\" : resolvedHeight;\n\tconst sizesAttr = containerWidth ? `${containerWidth}px` : \"100vw\";\n\tconst defaultFallback = <ImagePlaceholder width={width} height={placeholderHeight} aspectRatio={resolvedAspectRatio} />;\n\tconst loadedImageStyle: CSSProperties = isIntrinsic\n\t\t? {\n\t\t\t\t...style,\n\t\t\t\tdisplay: \"block\",\n\t\t\t\twidth: \"100%\",\n\t\t\t\theight: \"auto\",\n\t\t\t\tobjectFit: undefined\n\t\t\t}\n\t\t: {\n\t\t\t\tdisplay: \"block\",\n\t\t\t\twidth: \"100%\",\n\t\t\t\theight: \"100%\",\n\t\t\t\tobjectFit: layout,\n\t\t\t\t...style\n\t\t\t};\n\n\tconst content = (\n\t\t<>\n\t\t\t{!hasLoaded && !hasError && (fallback || defaultFallback)}\n\t\t\t{isVisible && !hasError && (\n\t\t\t\t<picture>\n\t\t\t\t\t{sources?.map((source) => (\n\t\t\t\t\t\t<source\n\t\t\t\t\t\t\tkey={`${source.type ?? \"source\"}-${source.srcSet}`}\n\t\t\t\t\t\t\tsrcSet={source.srcSet}\n\t\t\t\t\t\t\ttype={source.type}\n\t\t\t\t\t\t\tsizes={source.sizes ?? sizesAttr}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc={src}\n\t\t\t\t\t\talt={alt}\n\t\t\t\t\t\trole={role}\n\t\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\t\tonLoad={(event) => {\n\t\t\t\t\t\t\tsetHasLoaded(true);\n\t\t\t\t\t\t\tonLoad?.(event);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonError={(event) => {\n\t\t\t\t\t\t\tsetHasError(true);\n\t\t\t\t\t\t\tonError?.(event);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tstyle={!hasLoaded ? { display: \"none\" } : loadedImageStyle}\n\t\t\t\t\t\taria-busy={!hasLoaded}\n\t\t\t\t\t\twidth={intrinsicWidth}\n\t\t\t\t\t\theight={intrinsicHeight}\n\t\t\t\t\t\t{...imgProps}\n\t\t\t\t\t/>\n\t\t\t\t</picture>\n\t\t\t)}\n\t\t\t{hasError && defaultFallback}\n\t\t</>\n\t);\n\n\tconst wrapped = (\n\t\t<div ref={wrapperRef} style={{ width, height: resolvedHeight, aspectRatio: resolvedAspectRatio, ...wrapperStyle }}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\treturn useFigure ? (\n\t\t<figure className=\"relative\">\n\t\t\t{wrapped}\n\t\t\t{caption && (\n\t\t\t\t<figcaption\n\t\t\t\t\tstyle={{ bottom: 2, right: 2, maxWidth: \"calc(100% - 4px)\" }}\n\t\t\t\t\tclassName=\"absolute paddingInlineMd textRight radiusSm fontSizeSm\">\n\t\t\t\t\t{caption}\n\t\t\t\t</figcaption>\n\t\t\t)}\n\t\t</figure>\n\t) : (\n\t\twrapped\n\t);\n}\n","import { type SelectedImageData } from \"../model/imageSelectionTypes\";\n\n/** Возвращает устойчивый ключ файла внутри текущего набора выбранных изображений. */\nexport function getImageSelectionKey(image: SelectedImageData, index: number): string {\n\treturn `${image.file.meta.name}-${image.file.meta.size}-${image.file.meta.lastModified}-${index}`;\n}\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport { getImageSelectionKey } from \"../lib/getImageSelectionKey\";\n\nimport { type ImageCropArea, type ImageCropPoint } from \"./imageCropTypes\";\nimport {\n\ttype ImageCropperState,\n\ttype ImageSelectionPanelProps,\n\ttype ImageSelectionState,\n\ttype SelectedImageData,\n\ttype SelectedImageFile\n} from \"./imageSelectionTypes\";\n\nconst INITIAL_CROPPER_STATE: ImageCropperState = { crop: { x: 0, y: 0 }, zoom: 1 };\n\n/**\n * Управляет набором изображений в conventional controlled/uncontrolled-режиме.\n * В controlled-режиме каждое изменение сразу передаётся через onChange, а источник истины остаётся у вызывающего кода.\n */\nexport function useImageSelectionState({\n\tvalue,\n\tdefaultValue,\n\tdisabled,\n\tonChange,\n\tonApply\n}: Pick<ImageSelectionPanelProps, \"value\" | \"defaultValue\" | \"disabled\" | \"onChange\" | \"onApply\">): ImageSelectionState {\n\tconst [uncontrolledValue, setUncontrolledValue] = useState<SelectedImageData[]>(defaultValue ?? []);\n\tconst [requestedActiveIndex, setActiveIndex] = useState(0);\n\tconst [cropperStateByImage, setCropperStateByImage] = useState<Record<string, ImageCropperState>>({});\n\tconst resolvedValue = value ?? uncontrolledValue;\n\n\tconst updateValue = useCallback(\n\t\t(updater: (currentValue: SelectedImageData[]) => SelectedImageData[]) => {\n\t\t\tconst nextValue = updater(resolvedValue);\n\n\t\t\tif (value === undefined) {\n\t\t\t\tsetUncontrolledValue(nextValue);\n\t\t\t}\n\n\t\t\tonChange?.(nextValue);\n\t\t},\n\t\t[onChange, resolvedValue, value]\n\t);\n\n\tconst files = useMemo(() => resolvedValue.map((image) => image.file), [resolvedValue]);\n\tconst activeIndex = resolvedValue.length === 0 ? 0 : Math.min(requestedActiveIndex, resolvedValue.length - 1);\n\tconst activeImage = resolvedValue[activeIndex];\n\tconst activeImageKey = activeImage ? getImageSelectionKey(activeImage, activeIndex) : undefined;\n\tconst activeCropperState = activeImageKey ? (cropperStateByImage[activeImageKey] ?? INITIAL_CROPPER_STATE) : INITIAL_CROPPER_STATE;\n\tconst hasSelected = resolvedValue.length > 0;\n\tconst canApply = !disabled && hasSelected && resolvedValue.every((image) => image.alt.trim() && image.crop);\n\n\tconst setFiles = useCallback(\n\t\t(nextFiles: SelectedImageFile[]) => {\n\t\t\tupdateValue((currentValue) =>\n\t\t\t\tnextFiles.map((file) => {\n\t\t\t\t\t// Сохраняем описание и crop для файлов, которые остались в выборе.\n\t\t\t\t\tconst existingImage = currentValue.find((image) => image.file.file === file.file);\n\n\t\t\t\t\treturn existingImage ? { ...existingImage, file } : { file, alt: \"\" };\n\t\t\t\t})\n\t\t\t);\n\t\t},\n\t\t[updateValue]\n\t);\n\n\tconst setActiveAlt = useCallback(\n\t\t(alt: string) => {\n\t\t\tupdateValue((currentValue) => currentValue.map((image, index) => (index === activeIndex ? { ...image, alt } : image)));\n\t\t},\n\t\t[activeIndex, updateValue]\n\t);\n\n\tconst setActiveCrop = useCallback(\n\t\t(crop: ImageCropArea) => {\n\t\t\tupdateValue((currentValue) => currentValue.map((image, index) => (index === activeIndex ? { ...image, crop } : image)));\n\t\t},\n\t\t[activeIndex, updateValue]\n\t);\n\n\tconst setActiveCropperCrop = useCallback(\n\t\t(crop: ImageCropPoint) => {\n\t\t\tif (!activeImageKey) return;\n\n\t\t\tsetCropperStateByImage((currentState) => ({\n\t\t\t\t...currentState,\n\t\t\t\t[activeImageKey]: {\n\t\t\t\t\tcrop,\n\t\t\t\t\tzoom: currentState[activeImageKey]?.zoom ?? 1\n\t\t\t\t}\n\t\t\t}));\n\t\t},\n\t\t[activeImageKey]\n\t);\n\n\tconst setActiveCropperZoom = useCallback(\n\t\t(zoom: number) => {\n\t\t\tif (!activeImageKey) return;\n\n\t\t\tsetCropperStateByImage((currentState) => ({\n\t\t\t\t...currentState,\n\t\t\t\t[activeImageKey]: {\n\t\t\t\t\tcrop: currentState[activeImageKey]?.crop ?? { x: 0, y: 0 },\n\t\t\t\t\tzoom\n\t\t\t\t}\n\t\t\t}));\n\t\t},\n\t\t[activeImageKey]\n\t);\n\n\tconst apply = useCallback(() => {\n\t\tonApply?.(resolvedValue);\n\t}, [onApply, resolvedValue]);\n\n\treturn {\n\t\tvalue: resolvedValue,\n\t\tfiles,\n\t\tactiveIndex,\n\t\tactiveImage,\n\t\tactiveCropperState,\n\t\thasSelected,\n\t\tcanApply,\n\t\tapply,\n\t\tsetFiles,\n\t\tsetActiveIndex,\n\t\tsetActiveAlt,\n\t\tsetActiveCrop,\n\t\tsetActiveCropperCrop,\n\t\tsetActiveCropperZoom\n\t};\n}\n","import { type CSSProperties } from \"react\";\n\nimport { type SelectedImageData } from \"../model/imageSelectionTypes\";\n\nexport type ImageNaturalSize = {\n\twidth: number;\n\theight: number;\n};\n\n/** Масштабирует preview так, чтобы контейнер показывал только выбранную область crop. */\nexport function getImageCropPreviewStyle(image: SelectedImageData, size: ImageNaturalSize | undefined, aspect: number): CSSProperties {\n\tif (!image.crop || !size) {\n\t\treturn {\n\t\t\twidth: \"100%\",\n\t\t\taspectRatio: aspect,\n\t\t\tobjectFit: \"cover\",\n\t\t\tdisplay: \"block\"\n\t\t};\n\t}\n\n\tconst crop = image.crop;\n\n\treturn {\n\t\tposition: \"absolute\",\n\t\tleft: `${-(crop.x / crop.width) * 100}%`,\n\t\ttop: `${-(crop.y / crop.height) * 100}%`,\n\t\twidth: `${(size.width / crop.width) * 100}%`,\n\t\theight: `${(size.height / crop.height) * 100}%`,\n\t\tmaxWidth: \"none\"\n\t};\n}\n","import { useState } from \"react\";\n\nimport { GridContainer } from \"../../grid\";\nimport { InputText } from \"../../input\";\nimport { InputFiles } from \"../../input-files\";\nimport { getImageCropPreviewStyle, type ImageNaturalSize } from \"../lib/getImageCropPreviewStyle\";\nimport { getImageSelectionKey } from \"../lib/getImageSelectionKey\";\nimport { type ImageSelectionPanelProps, type ImageSelectionState } from \"../model/imageSelectionTypes\";\n\nimport { ImageCropper } from \"./ImageCropper\";\n\nconst DEFAULT_ALLOWED_IMAGE_MIME = [\"image/jpeg\", \"image/png\", \"image/webp\", \"image/avif\"] as const;\n\ninterface ImageSelectionFieldsProps extends Pick<\n\tImageSelectionPanelProps,\n\t\"aspect\" | \"disabled\" | \"allowedMime\" | \"maxBytes\" | \"minimumCropWidth\" | \"onReadError\"\n> {\n\tstate: ImageSelectionState;\n}\n\n/** Поля выбора файлов, crop и альтернативного текста для активного изображения. */\nexport function ImageSelectionFields({\n\taspect = 16 / 9,\n\tdisabled,\n\tallowedMime = DEFAULT_ALLOWED_IMAGE_MIME,\n\tmaxBytes,\n\tminimumCropWidth,\n\tonReadError,\n\tstate\n}: ImageSelectionFieldsProps) {\n\tconst area = state.activeImage?.crop;\n\tconst [imageSizes, setImageSizes] = useState<Record<string, ImageNaturalSize>>({});\n\n\treturn (\n\t\t<GridContainer gap=\"md\">\n\t\t\t<InputFiles\n\t\t\t\tlabel=\"Файл изображения\"\n\t\t\t\tallowedMime={allowedMime}\n\t\t\t\tvalue={state.files}\n\t\t\t\tonChange={state.setFiles}\n\t\t\t\tmaxBytes={maxBytes}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tonReadError={onReadError}\n\t\t\t/>\n\n\t\t\t{state.hasSelected && state.activeImage && (\n\t\t\t\t<div>\n\t\t\t\t\t<GridContainer templateColumns=\"repeat(auto-fill, minmax(10em, 1fr))\" gap=\"xs\">\n\t\t\t\t\t\t{state.value.map((image, index) => {\n\t\t\t\t\t\t\tconst imageKey = getImageSelectionKey(image, index);\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tkey={imageKey}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\tonClick={() => state.setActiveIndex(index)}\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\t\t\t\t\tborder: index === state.activeIndex ? \"2px solid var(--border-accent)\" : \"2px solid transparent\",\n\t\t\t\t\t\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\t\t\t\t\t\tcursor: disabled ? \"default\" : \"pointer\"\n\t\t\t\t\t\t\t\t\t}}>\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\t\t\t\t\t\t\tdisplay: \"block\",\n\t\t\t\t\t\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\t\t\t\t\t\taspectRatio: aspect,\n\t\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\"\n\t\t\t\t\t\t\t\t\t\t}}>\n\t\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\t\tsrc={image.file.dataUrl}\n\t\t\t\t\t\t\t\t\t\t\talt={image.alt || `Предпросмотр изображения ${index + 1}`}\n\t\t\t\t\t\t\t\t\t\t\tstyle={getImageCropPreviewStyle(image, imageSizes[imageKey], aspect)}\n\t\t\t\t\t\t\t\t\t\t\tonLoad={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\tconst target = event.currentTarget;\n\n\t\t\t\t\t\t\t\t\t\t\t\tsetImageSizes((currentSizes) => ({\n\t\t\t\t\t\t\t\t\t\t\t\t\t...currentSizes,\n\t\t\t\t\t\t\t\t\t\t\t\t\t[imageKey]: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth: target.naturalWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\theight: target.naturalHeight\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</GridContainer>\n\n\t\t\t\t\t<div>\n\t\t\t\t\t\tВыберите область изображения{\" \"}\n\t\t\t\t\t\t{area && (\n\t\t\t\t\t\t\t<code className={minimumCropWidth && area.width < minimumCropWidth ? \"statusError\" : \"statusSuccess\"}>\n\t\t\t\t\t\t\t\t{area.width}x{area.height}\n\t\t\t\t\t\t\t\t{minimumCropWidth && area.width < minimumCropWidth ? \" — недостаточная ширина\" : \"\"}\n\t\t\t\t\t\t\t</code>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<ImageCropper\n\t\t\t\t\t\tkey={getImageSelectionKey(state.activeImage, state.activeIndex)}\n\t\t\t\t\t\timage={state.activeImage.file.dataUrl}\n\t\t\t\t\t\tcrop={state.activeCropperState.crop}\n\t\t\t\t\t\tzoom={state.activeCropperState.zoom}\n\t\t\t\t\t\taspect={aspect}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tonCropChange={state.setActiveCropperCrop}\n\t\t\t\t\t\tonZoomChange={state.setActiveCropperZoom}\n\t\t\t\t\t\tonCropComplete={state.setActiveCrop}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t<InputText\n\t\t\t\trequired\n\t\t\t\tdisabled={!state.hasSelected || disabled}\n\t\t\t\tlabel=\"Краткое описание изображения\"\n\t\t\t\tplaceholder=\"\"\n\t\t\t\tvalue={state.activeImage?.alt ?? \"\"}\n\t\t\t\tonChange={state.setActiveAlt}\n\t\t\t/>\n\t\t</GridContainer>\n\t);\n}\n","import { Button } from \"../../button\";\nimport { Modal, ModalContent, ModalFooter } from \"../../modal\";\nimport { type ImageSelectionModalProps } from \"../model/imageSelectionTypes\";\nimport { useImageSelectionState } from \"../model/useImageSelectionState\";\n\nimport { ImageSelectionFields } from \"./ImageSelectionFields\";\n\n/** Модальная форма выбора изображений с необязательным этапом подтверждения. */\nexport function ImageSelectionModal({\n\tdisabled,\n\tisOpen = true,\n\tonClose = () => {},\n\ttitle = \"Загрузка нового изображения\",\n\t...props\n}: ImageSelectionModalProps) {\n\tconst state = useImageSelectionState({ ...props, disabled });\n\n\tif (!props.onApply) {\n\t\treturn (\n\t\t\t<Modal isOpen={isOpen} onClose={onClose} title={title} size=\"xl\">\n\t\t\t\t<ModalContent scrollable>\n\t\t\t\t\t<ImageSelectionFields {...props} disabled={disabled} state={state} />\n\t\t\t\t</ModalContent>\n\t\t\t</Modal>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={onClose} title={title} size=\"xl\">\n\t\t\t<ModalContent scrollable>\n\t\t\t\t<ImageSelectionFields {...props} disabled={disabled} state={state} />\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button disabled={!state.canApply} tone=\"success\" onClick={state.apply}>\n\t\t\t\t\tПрименить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { Button } from \"../../button\";\nimport { type ImageSelectionActionsData, type ImageSelectionPanelProps } from \"../model/imageSelectionTypes\";\nimport { useImageSelectionState } from \"../model/useImageSelectionState\";\n\nimport { ImageSelectionFields } from \"./ImageSelectionFields\";\n\n/** Встраиваемая форма выбора и обрезки одного или нескольких изображений. */\nexport function ImageSelectionPanel({ disabled, renderActions, ...props }: ImageSelectionPanelProps) {\n\tconst state = useImageSelectionState({ ...props, disabled });\n\tconst actionsData: ImageSelectionActionsData = {\n\t\tvalue: state.value,\n\t\tactiveIndex: state.activeIndex,\n\t\thasSelected: state.hasSelected,\n\t\tcanApply: state.canApply,\n\t\tapply: state.apply\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<ImageSelectionFields {...props} disabled={disabled} state={state} />\n\t\t\t{renderActions\n\t\t\t\t? renderActions(actionsData)\n\t\t\t\t: props.onApply && (\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<Button disabled={!state.canApply} tone=\"success\" onClick={state.apply}>\n\t\t\t\t\t\t\t\tПрименить\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t</>\n\t);\n}\n","import { type ImgHTMLAttributes } from \"react\";\n\nimport { buildImageSources } from \"../lib/buildImageSources\";\nimport { buildImageSrcSet } from \"../lib/buildImageSrcSet\";\nimport { type ResponsiveImageData } from \"../model/imageTypes\";\n\nimport { ImageRenderer, type ImageRendererProps } from \"./ImageRenderer\";\n\nexport interface ImageViewProps\n\textends\n\t\tOmit<ImageRendererProps, \"src\" | \"sources\" | \"alt\" | \"intrinsicWidth\" | \"intrinsicHeight\" | \"srcSet\" | \"sizes\">,\n\t\tPick<ImgHTMLAttributes<HTMLImageElement>, \"sizes\"> {\n\timage: ResponsiveImageData;\n\talt?: string;\n}\n\n/**\n * Собирает picture/srcset из готовых URL и делегирует отображение ImageRenderer.\n * Компонент не формирует имена файлов и не знает о форматах или размерах хранилища.\n */\nexport function ImageView({ image, alt, sizes, aspectRatio, ...props }: ImageViewProps) {\n\tconst sources = buildImageSources(image.sources, sizes);\n\tconst srcSet = image.candidates ? buildImageSrcSet(image.candidates) : undefined;\n\tconst resolvedAspectRatio =\n\t\taspectRatio ?? (image.intrinsicWidth && image.intrinsicHeight ? `${image.intrinsicWidth} / ${image.intrinsicHeight}` : undefined);\n\n\treturn (\n\t\t<ImageRenderer\n\t\t\t{...props}\n\t\t\tsrc={image.src}\n\t\t\tsrcSet={srcSet || undefined}\n\t\t\tsources={sources}\n\t\t\tsizes={sizes}\n\t\t\talt={alt ?? image.alt}\n\t\t\tintrinsicWidth={image.intrinsicWidth}\n\t\t\tintrinsicHeight={image.intrinsicHeight}\n\t\t\taspectRatio={resolvedAspectRatio}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type ImageSource, type ResponsiveImageSource } from "../model/imageTypes";
2
+ /** Преобразует декларативные наборы кандидатов в готовые source-дескрипторы. */
3
+ export declare function buildImageSources(sources: readonly ResponsiveImageSource[] | undefined, defaultSizes?: string): ImageSource[];
4
+ //# sourceMappingURL=buildImageSources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildImageSources.d.ts","sourceRoot":"","sources":["../../../src/image/lib/buildImageSources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAInF,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,GAAG,SAAS,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAQ7H"}
@@ -0,0 +1,4 @@
1
+ import { type ImageCandidate } from "../model/imageTypes";
2
+ /** Собирает валидный srcset из уже разрешённых вызывающим кодом URL вариантов. */
3
+ export declare function buildImageSrcSet(candidates: readonly ImageCandidate[]): string;
4
+ //# sourceMappingURL=buildImageSrcSet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildImageSrcSet.d.ts","sourceRoot":"","sources":["../../../src/image/lib/buildImageSrcSet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAI9E"}
@@ -0,0 +1,9 @@
1
+ import { type CSSProperties } from "react";
2
+ import { type SelectedImageData } from "../model/imageSelectionTypes";
3
+ export type ImageNaturalSize = {
4
+ width: number;
5
+ height: number;
6
+ };
7
+ /** Масштабирует preview так, чтобы контейнер показывал только выбранную область crop. */
8
+ export declare function getImageCropPreviewStyle(image: SelectedImageData, size: ImageNaturalSize | undefined, aspect: number): CSSProperties;
9
+ //# sourceMappingURL=getImageCropPreviewStyle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getImageCropPreviewStyle.d.ts","sourceRoot":"","sources":["../../../src/image/lib/getImageCropPreviewStyle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,yFAAyF;AACzF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,gBAAgB,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAoBpI"}
@@ -0,0 +1,4 @@
1
+ import { type SelectedImageData } from "../model/imageSelectionTypes";
2
+ /** Возвращает устойчивый ключ файла внутри текущего набора выбранных изображений. */
3
+ export declare function getImageSelectionKey(image: SelectedImageData, index: number): string;
4
+ //# sourceMappingURL=getImageSelectionKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getImageSelectionKey.d.ts","sourceRoot":"","sources":["../../../src/image/lib/getImageSelectionKey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpF"}
@@ -0,0 +1,35 @@
1
+ import { type CSSProperties } from "react";
2
+ /** Координаты смещения изображения внутри cropper. */
3
+ export type ImageCropPoint = {
4
+ x: number;
5
+ y: number;
6
+ };
7
+ /** Прямоугольная область обрезки в пикселях или процентах. */
8
+ export type ImageCropArea = {
9
+ x: number;
10
+ y: number;
11
+ width: number;
12
+ height: number;
13
+ };
14
+ /** Способ начального вписывания исходника в область cropper. */
15
+ export type ImageCropperObjectFit = "contain" | "cover" | "horizontal-cover" | "vertical-cover";
16
+ export interface ImageCropperProps {
17
+ image: string;
18
+ aspect?: number;
19
+ width?: CSSProperties["width"];
20
+ className?: string;
21
+ style?: CSSProperties;
22
+ crop?: ImageCropPoint;
23
+ defaultCrop?: ImageCropPoint;
24
+ zoom?: number;
25
+ defaultZoom?: number;
26
+ minZoom?: number;
27
+ maxZoom?: number;
28
+ zoomSpeed?: number;
29
+ objectFit?: ImageCropperObjectFit;
30
+ disabled?: boolean;
31
+ onCropChange?: (crop: ImageCropPoint) => void;
32
+ onZoomChange?: (zoom: number) => void;
33
+ onCropComplete?: (croppedAreaPixels: ImageCropArea, croppedAreaPercentages: ImageCropArea) => void;
34
+ }
35
+ //# sourceMappingURL=imageCropTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageCropTypes.d.ts","sourceRoot":"","sources":["../../../src/image/model/imageCropTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,sDAAsD;AACtD,MAAM,MAAM,cAAc,GAAG;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACV,CAAC;AAEF,8DAA8D;AAC9D,MAAM,MAAM,aAAa,GAAG;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,gEAAgE;AAChE,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,OAAO,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;AAEhG,MAAM,WAAW,iBAAiB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,WAAW,CAAC,EAAE,cAAc,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,cAAc,CAAC,EAAE,CAAC,iBAAiB,EAAE,aAAa,EAAE,sBAAsB,EAAE,aAAa,KAAK,IAAI,CAAC;CACnG"}
@@ -0,0 +1,53 @@
1
+ import { type ReactNode } from "react";
2
+ import { type ReadFileError, type ReadFileResult } from "@ryuzaki13/react-foundation-lib/file";
3
+ import { type ImageCropArea, type ImageCropPoint } from "./imageCropTypes";
4
+ export type SelectedImageFile = Extract<ReadFileResult, {
5
+ mode: "data-url";
6
+ }>;
7
+ /** Данные исходного файла и подтверждённые пользователем параметры изображения. */
8
+ export type SelectedImageData = {
9
+ file: SelectedImageFile;
10
+ alt: string;
11
+ crop?: ImageCropArea;
12
+ };
13
+ export interface ImageSelectionActionsData {
14
+ value: SelectedImageData[];
15
+ activeIndex: number;
16
+ hasSelected: boolean;
17
+ canApply: boolean;
18
+ apply: () => void;
19
+ }
20
+ export interface ImageSelectionPanelProps {
21
+ aspect?: number;
22
+ disabled?: boolean;
23
+ value?: SelectedImageData[];
24
+ defaultValue?: SelectedImageData[];
25
+ allowedMime?: readonly string[];
26
+ maxBytes?: number;
27
+ minimumCropWidth?: number;
28
+ onReadError?: (error: ReadFileError) => void;
29
+ onChange?: (data: SelectedImageData[]) => void;
30
+ onApply?: (data: SelectedImageData[]) => void;
31
+ renderActions?: (data: ImageSelectionActionsData) => ReactNode;
32
+ }
33
+ export interface ImageSelectionModalProps extends ImageSelectionPanelProps {
34
+ isOpen?: boolean;
35
+ onClose?: () => void;
36
+ title?: string;
37
+ }
38
+ export type ImageCropperState = {
39
+ crop: ImageCropPoint;
40
+ zoom: number;
41
+ };
42
+ export interface ImageSelectionState extends ImageSelectionActionsData {
43
+ files: SelectedImageFile[];
44
+ activeImage?: SelectedImageData;
45
+ activeCropperState: ImageCropperState;
46
+ setFiles: (files: SelectedImageFile[]) => void;
47
+ setActiveIndex: (index: number) => void;
48
+ setActiveAlt: (alt: string) => void;
49
+ setActiveCrop: (crop: ImageCropArea) => void;
50
+ setActiveCropperCrop: (crop: ImageCropPoint) => void;
51
+ setActiveCropperZoom: (zoom: number) => void;
52
+ }
53
+ //# sourceMappingURL=imageSelectionTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageSelectionTypes.d.ts","sourceRoot":"","sources":["../../../src/image/model/imageSelectionTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAE/F,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE3E,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AAE9E,mFAAmF;AACnF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,iBAAiB,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,aAAa,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACzC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC5B,YAAY,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IAC/C,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IAC9C,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,SAAS,CAAC;CAC/D;AAED,MAAM,WAAW,wBAAyB,SAAQ,wBAAwB;IACzE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,WAAW,mBAAoB,SAAQ,yBAAyB;IACrE,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,aAAa,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,oBAAoB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACrD,oBAAoB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C"}
@@ -0,0 +1,41 @@
1
+ /** Режим размещения изображения внутри доступной области. */
2
+ export type ImageLayout = "cover" | "contain" | "intrinsic";
3
+ /** Готовый source-дескриптор для прямого отображения через picture. */
4
+ export type ImageSource = {
5
+ srcSet: string;
6
+ type?: string;
7
+ sizes?: string;
8
+ };
9
+ /** Кандидат responsive-изображения с дескриптором физической ширины. */
10
+ export type ImageWidthCandidate = {
11
+ src: string;
12
+ width: number;
13
+ density?: never;
14
+ };
15
+ /** Кандидат responsive-изображения с дескриптором плотности пикселей. */
16
+ export type ImageDensityCandidate = {
17
+ src: string;
18
+ density: number;
19
+ width?: never;
20
+ };
21
+ /** Готовый URL варианта изображения и его стандартный srcset-дескриптор. */
22
+ export type ImageCandidate = ImageWidthCandidate | ImageDensityCandidate;
23
+ /** Набор кандидатов одного формата для элемента picture/source. */
24
+ export type ResponsiveImageSource = {
25
+ candidates: readonly ImageCandidate[];
26
+ type?: string;
27
+ sizes?: string;
28
+ };
29
+ /**
30
+ * Независимый от хранилища контракт изображения.
31
+ * Все URL и варианты подготавливает вызывающий слой, знакомый со схемой хранения.
32
+ */
33
+ export type ResponsiveImageData = {
34
+ src: string;
35
+ alt?: string;
36
+ intrinsicWidth?: number;
37
+ intrinsicHeight?: number;
38
+ candidates?: readonly ImageCandidate[];
39
+ sources?: readonly ResponsiveImageSource[];
40
+ };
41
+ //# sourceMappingURL=imageTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageTypes.d.ts","sourceRoot":"","sources":["../../../src/image/model/imageTypes.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;AAE5D,uEAAuE;AACvE,MAAM,MAAM,WAAW,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wEAAwE;AACxE,MAAM,MAAM,mBAAmB,GAAG;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,KAAK,CAAC;CAChB,CAAC;AAEF,yEAAyE;AACzE,MAAM,MAAM,qBAAqB,GAAG;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;CACd,CAAC;AAEF,4EAA4E;AAC5E,MAAM,MAAM,cAAc,GAAG,mBAAmB,GAAG,qBAAqB,CAAC;AAEzE,mEAAmE;AACnE,MAAM,MAAM,qBAAqB,GAAG;IACnC,UAAU,EAAE,SAAS,cAAc,EAAE,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IACvC,OAAO,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC3C,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type ImageSelectionPanelProps, type ImageSelectionState } from "./imageSelectionTypes";
2
+ /**
3
+ * Управляет набором изображений в conventional controlled/uncontrolled-режиме.
4
+ * В controlled-режиме каждое изменение сразу передаётся через onChange, а источник истины остаётся у вызывающего кода.
5
+ */
6
+ export declare function useImageSelectionState({ value, defaultValue, disabled, onChange, onApply }: Pick<ImageSelectionPanelProps, "value" | "defaultValue" | "disabled" | "onChange" | "onApply">): ImageSelectionState;
7
+ //# sourceMappingURL=useImageSelectionState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useImageSelectionState.d.ts","sourceRoot":"","sources":["../../../src/image/model/useImageSelectionState.ts"],"names":[],"mappings":"AAKA,OAAO,EAEN,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EAGxB,MAAM,uBAAuB,CAAC;AAI/B;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EACtC,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,EAAE,IAAI,CAAC,wBAAwB,EAAE,OAAO,GAAG,cAAc,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC,GAAG,mBAAmB,CAyGtH"}
@@ -1,13 +1,7 @@
1
- export type CroppedAreaPixels = {
2
- x: number;
3
- y: number;
4
- width: number;
5
- height: number;
6
- };
7
- export declare function ImageCropper({ image, aspect, width, onCropComplete }: {
8
- image: string;
9
- aspect?: number;
10
- width?: number;
11
- onCropComplete?: (croppedAreaPixels: CroppedAreaPixels) => void;
12
- }): import("react").JSX.Element;
1
+ import { type ImageCropperProps } from "../model/imageCropTypes";
2
+ /**
3
+ * Управляемая или автономная область обрезки изображения.
4
+ * Числовой aspect задаётся вызывающим кодом и не связан с назначением изображения.
5
+ */
6
+ export declare function ImageCropper({ image, aspect, width, className, style, crop, defaultCrop, zoom, defaultZoom, minZoom, maxZoom, zoomSpeed, objectFit, disabled, onCropChange, onZoomChange, onCropComplete }: ImageCropperProps): import("react").JSX.Element;
13
7
  //# sourceMappingURL=ImageCropper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImageCropper.d.ts","sourceRoot":"","sources":["../../../src/image/ui/ImageCropper.tsx"],"names":[],"mappings":"AAIA,MAAM,MAAM,iBAAiB,GAAG;IAC/B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,YAAY,CAAC,EAC5B,KAAK,EACL,MAAmB,EACnB,KAAK,EACL,cAAc,EACd,EAAE;IACF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAChE,+BA0BA"}
1
+ {"version":3,"file":"ImageCropper.d.ts","sourceRoot":"","sources":["../../../src/image/ui/ImageCropper.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAsB,KAAK,iBAAiB,EAAuB,MAAM,yBAAyB,CAAC;AAI1G;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC5B,KAAK,EACL,MAAe,EACf,KAAc,EACd,SAAS,EACT,KAAK,EACL,IAAI,EACJ,WAA0B,EAC1B,IAAI,EACJ,WAAe,EACf,OAAW,EACX,OAAW,EACX,SAAe,EACf,SAAqB,EACrB,QAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,EAAE,iBAAiB,+BA6DnB"}
@@ -1,9 +1,8 @@
1
- interface ImagePlaceholderProps {
1
+ export interface ImagePlaceholderProps {
2
2
  width?: number | string;
3
3
  height?: number | string;
4
4
  aspectRatio?: string | "unset";
5
5
  className?: string;
6
6
  }
7
7
  export declare function ImagePlaceholder({ width, height, aspectRatio, className }: ImagePlaceholderProps): import("react").JSX.Element;
8
- export {};
9
8
  //# sourceMappingURL=ImagePlaceholder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImagePlaceholder.d.ts","sourceRoot":"","sources":["../../../src/image/ui/ImagePlaceholder.tsx"],"names":[],"mappings":"AAAA,UAAU,qBAAqB;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,KAAc,EAAE,MAAe,EAAE,WAAsB,EAAE,SAAS,EAAE,EAAE,qBAAqB,+BA6B7H"}
1
+ {"version":3,"file":"ImagePlaceholder.d.ts","sourceRoot":"","sources":["../../../src/image/ui/ImagePlaceholder.tsx"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,KAAc,EAAE,MAAe,EAAE,WAAsB,EAAE,SAAS,EAAE,EAAE,qBAAqB,+BA6B7H"}
@@ -1,12 +1,9 @@
1
1
  import { type CSSProperties, type ImgHTMLAttributes, type ReactNode } from "react";
2
- export type ImageSource = {
3
- srcSet: string;
4
- type?: string;
5
- sizes?: string;
6
- };
7
- export interface ImageRendererProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, "src"> {
2
+ import { type ImageLayout, type ImageSource } from "../model/imageTypes";
3
+ export interface ImageRendererProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, "src" | "width" | "height"> {
8
4
  src: string;
9
5
  sources?: readonly ImageSource[];
6
+ layout?: ImageLayout;
10
7
  alt?: string;
11
8
  role?: string;
12
9
  ariaLabel?: string;
@@ -14,11 +11,15 @@ export interface ImageRendererProps extends Omit<ImgHTMLAttributes<HTMLImageElem
14
11
  fallback?: ReactNode;
15
12
  useFigure?: boolean;
16
13
  aspectRatio?: string | "unset";
14
+ width?: CSSProperties["width"];
15
+ height?: CSSProperties["height"];
16
+ intrinsicWidth?: number;
17
+ intrinsicHeight?: number;
17
18
  wrapperStyle?: CSSProperties;
18
19
  }
19
20
  /**
20
21
  * Базовый рендер изображения: lazy-появление, placeholder, обработка ошибки и figure/caption.
21
22
  * Компонент не знает, как устроено хранилище и какие форматы/размеры доступны.
22
23
  */
23
- export declare function ImageRenderer({ src, sources, alt, role, ariaLabel, caption, fallback, useFigure, width, height, aspectRatio, style, wrapperStyle, ...imgProps }: ImageRendererProps): import("react").JSX.Element;
24
+ export declare function ImageRenderer({ src, sources, alt, role, ariaLabel, caption, fallback, useFigure, layout, width, height, aspectRatio, intrinsicWidth, intrinsicHeight, onLoad, onError, style, wrapperStyle, ...imgProps }: ImageRendererProps): import("react").JSX.Element;
24
25
  //# sourceMappingURL=ImageRenderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImageRenderer.d.ts","sourceRoot":"","sources":["../../../src/image/ui/ImageRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAA+B,MAAM,OAAO,CAAC;AAIhH,MAAM,MAAM,WAAW,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,EAAE,KAAK,CAAC;IAC3F,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,YAAY,CAAC,EAAE,aAAa,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC7B,GAAG,EACH,OAAO,EACP,GAAG,EACH,IAAI,EACJ,SAAS,EACT,OAAO,EACP,QAAQ,EACR,SAAiB,EACjB,KAAc,EACd,MAAe,EACf,WAAsB,EACtB,KAAK,EACL,YAAY,EACZ,GAAG,QAAQ,EACX,EAAE,kBAAkB,+BAmFpB"}
1
+ {"version":3,"file":"ImageRenderer.d.ts","sourceRoot":"","sources":["../../../src/image/ui/ImageRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAA+B,MAAM,OAAO,CAAC;AAEhH,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIzE,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IAChH,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,aAAa,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC7B,GAAG,EACH,OAAO,EACP,GAAG,EACH,IAAI,EACJ,SAAS,EACT,OAAO,EACP,QAAQ,EACR,SAAiB,EACjB,MAAgB,EAChB,KAAc,EACd,MAAe,EACf,WAAW,EACX,cAAc,EACd,eAAe,EACf,MAAM,EACN,OAAO,EACP,KAAK,EACL,YAAY,EACZ,GAAG,QAAQ,EACX,EAAE,kBAAkB,+BAoHpB"}
@@ -0,0 +1,8 @@
1
+ import { type ImageSelectionPanelProps, type ImageSelectionState } from "../model/imageSelectionTypes";
2
+ interface ImageSelectionFieldsProps extends Pick<ImageSelectionPanelProps, "aspect" | "disabled" | "allowedMime" | "maxBytes" | "minimumCropWidth" | "onReadError"> {
3
+ state: ImageSelectionState;
4
+ }
5
+ /** Поля выбора файлов, crop и альтернативного текста для активного изображения. */
6
+ export declare function ImageSelectionFields({ aspect, disabled, allowedMime, maxBytes, minimumCropWidth, onReadError, state }: ImageSelectionFieldsProps): import("react").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=ImageSelectionFields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageSelectionFields.d.ts","sourceRoot":"","sources":["../../../src/image/ui/ImageSelectionFields.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,wBAAwB,EAAE,KAAK,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAMvG,UAAU,yBAA0B,SAAQ,IAAI,CAC/C,wBAAwB,EACxB,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,UAAU,GAAG,kBAAkB,GAAG,aAAa,CACvF;IACA,KAAK,EAAE,mBAAmB,CAAC;CAC3B;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,EACpC,MAAe,EACf,QAAQ,EACR,WAAwC,EACxC,QAAQ,EACR,gBAAgB,EAChB,WAAW,EACX,KAAK,EACL,EAAE,yBAAyB,+BAkG3B"}
@@ -0,0 +1,4 @@
1
+ import { type ImageSelectionModalProps } from "../model/imageSelectionTypes";
2
+ /** Модальная форма выбора изображений с необязательным этапом подтверждения. */
3
+ export declare function ImageSelectionModal({ disabled, isOpen, onClose, title, ...props }: ImageSelectionModalProps): import("react").JSX.Element;
4
+ //# sourceMappingURL=ImageSelectionModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageSelectionModal.d.ts","sourceRoot":"","sources":["../../../src/image/ui/ImageSelectionModal.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAK7E,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,EACnC,QAAQ,EACR,MAAa,EACb,OAAkB,EAClB,KAAqC,EACrC,GAAG,KAAK,EACR,EAAE,wBAAwB,+BAyB1B"}
@@ -0,0 +1,4 @@
1
+ import { type ImageSelectionPanelProps } from "../model/imageSelectionTypes";
2
+ /** Встраиваемая форма выбора и обрезки одного или нескольких изображений. */
3
+ export declare function ImageSelectionPanel({ disabled, renderActions, ...props }: ImageSelectionPanelProps): import("react").JSX.Element;
4
+ //# sourceMappingURL=ImageSelectionPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageSelectionPanel.d.ts","sourceRoot":"","sources":["../../../src/image/ui/ImageSelectionPanel.tsx"],"names":[],"mappings":"AACA,OAAO,EAAkC,KAAK,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAK7G,6EAA6E;AAC7E,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,KAAK,EAAE,EAAE,wBAAwB,+BAwBlG"}
@@ -1,40 +1,13 @@
1
- import { type ImgHTMLAttributes, type ReactNode } from "react";
2
- export type ImageFormat = "avif" | "webp" | "jpeg" | "jpg" | "png";
3
- export type StoredImageData = {
4
- filename: string;
5
- path: string;
6
- width?: number;
7
- height?: number;
1
+ import { type ImgHTMLAttributes } from "react";
2
+ import { type ResponsiveImageData } from "../model/imageTypes";
3
+ import { type ImageRendererProps } from "./ImageRenderer";
4
+ export interface ImageViewProps extends Omit<ImageRendererProps, "src" | "sources" | "alt" | "intrinsicWidth" | "intrinsicHeight" | "srcSet" | "sizes">, Pick<ImgHTMLAttributes<HTMLImageElement>, "sizes"> {
5
+ image: ResponsiveImageData;
8
6
  alt?: string;
9
- hasSet?: boolean;
10
- };
11
- interface ImageViewProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, "src" | "alt"> {
12
- /** Запись из таблицы Image. Предпочтительный способ передать изображение из БД. */
13
- image?: StoredImageData;
14
- /** Базовое имя файла из БД. Для новых изображений это md5 без расширения. */
15
- src?: string;
16
- /** Путь из БД относительно публичного корня, например `images/articles`. */
17
- path?: string;
18
- alt?: string;
19
- role?: string;
20
- ariaLabel?: string;
21
- caption?: string;
22
- fallback?: ReactNode;
23
- useFigure?: boolean;
24
- aspectRatio?: string | "unset";
25
- /** Форматы, которые реально лежат в хранилище для текущего изображения. */
26
- formats?: readonly ImageFormat[];
27
- /** Формат для img.src. Должен существовать в хранилище. */
28
- fallbackFormat?: ImageFormat;
29
- /** Набор размеров для файлов вида base@width.format. */
30
- variantWidths?: readonly number[];
31
- /** Признак наличия responsive-набора. Если false, @size srcSet не строится. */
32
- hasSet?: boolean;
33
7
  }
34
8
  /**
35
- * Адаптер для изображений из таблицы Image.
36
- * Компонент строит пути только из данных БД: path + filename + формат/размер.
9
+ * Собирает picture/srcset из готовых URL и делегирует отображение ImageRenderer.
10
+ * Компонент не формирует имена файлов и не знает о форматах или размерах хранилища.
37
11
  */
38
- export declare function ImageView({ image, src, path, alt, formats, fallbackFormat, variantWidths, hasSet, aspectRatio, ...props }: ImageViewProps): import("react").JSX.Element;
39
- export {};
12
+ export declare function ImageView({ image, alt, sizes, aspectRatio, ...props }: ImageViewProps): import("react").JSX.Element;
40
13
  //# sourceMappingURL=ImageView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImageView.d.ts","sourceRoot":"","sources":["../../../src/image/ui/ImageView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAI/D,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;AAKnE,MAAM,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,UAAU,cAAe,SAAQ,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACxF,mFAAmF;IACnF,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACjC,2DAA2D;IAC3D,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,wDAAwD;IACxD,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,+EAA+E;IAC/E,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AA8CD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EACzB,KAAK,EACL,GAAG,EACH,IAAI,EACJ,GAAG,EACH,OAA6B,EAC7B,cAAc,EACd,aAAkC,EAClC,MAAM,EACN,WAAW,EACX,GAAG,KAAK,EACR,EAAE,cAAc,+BA6BhB"}
1
+ {"version":3,"file":"ImageView.d.ts","sourceRoot":"","sources":["../../../src/image/ui/ImageView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAI/C,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEzE,MAAM,WAAW,cAChB,SACC,IAAI,CAAC,kBAAkB,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,QAAQ,GAAG,OAAO,CAAC,EAC/G,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACnD,KAAK,EAAE,mBAAmB,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,+BAmBrF"}
@@ -1,5 +1,5 @@
1
- import { t as e } from "../chunks/grid-ByIIytjh.js";
2
- import { c as t, h as n } from "../chunks/misc-1PxS8OWD.js";
1
+ import { t as e } from "../chunks/grid-dI94AAbi.js";
2
+ import { c as t, h as n } from "../chunks/misc-ClXJygTj.js";
3
3
  import r, { Children as i, useMemo as a, useRef as o } from "react";
4
4
  import { cn as s } from "@ryuzaki13/react-foundation-lib/utils";
5
5
  import { jsx as c } from "react/jsx-runtime";
@@ -1,2 +1,2 @@
1
- import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g, v as _, y as v } from "../chunks/misc-1PxS8OWD.js";
1
+ import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g, v as _, y as v } from "../chunks/misc-ClXJygTj.js";
2
2
  export { v as AnimatedLogo, _ as CopyTextWrapper, u as ErrorIcon, e as IconWrapper, p as InformationIcon, l as LazyDynamicComponent, i as LazyValue, o as LoadingMessage, a as Message, r as NoData, g as Notice, c as OneStepScroller, s as RenderStateIcon, n as Scrollable, f as SkeletonLine, t as StateIcon, h as StateWrapper, d as SuccessIcon, m as WarningIcon };
@@ -1,2 +1,2 @@
1
- import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "../chunks/modal-4vYSSbAa.js";
1
+ import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "../chunks/modal-QGp5CjB9.js";
2
2
  export { n as Modal, i as ModalContent, t as ModalFooter, r as ModalManagerContext, o as ModalManagerProvider, e as ModalToolbar, a as useModalManager };
@@ -1,2 +1,2 @@
1
- import { a as e, i as t, n, o as r, r as i, t as a } from "../chunks/multi-select-r0ekR6Bh.js";
1
+ import { a as e, i as t, n, o as r, r as i, t as a } from "../chunks/multi-select-DkfdFYm4.js";
2
2
  export { e as MultiSelect, r as MultiSelectToken, n as ODataDependentMultiSelect, i as ODataDependentSegmentMultiSelect, t as ODataMultiSelect, a as SerializableMultiSelect };