@mari-ui/components 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accordion.js +4 -4
- package/dist/accordion.js.map +1 -1
- package/dist/alert.js +5 -5
- package/dist/alert.js.map +1 -1
- package/dist/autocomplete.js +8 -8
- package/dist/autocomplete.js.map +1 -1
- package/dist/avatar.js +3 -3
- package/dist/badge.js +3 -3
- package/dist/breadcrumb.js +9 -9
- package/dist/breadcrumb.js.map +1 -1
- package/dist/button.js +4 -4
- package/dist/calendar.js +14 -14
- package/dist/calendar.js.map +1 -1
- package/dist/card.js +4 -4
- package/dist/card.js.map +1 -1
- package/dist/carousel.js +4 -4
- package/dist/carousel.js.map +1 -1
- package/dist/chart.js +5 -5
- package/dist/chart.js.map +1 -1
- package/dist/checkbox.js +4 -4
- package/dist/{chunk-BDV4GOEN.js → chunk-5GILG5AK.js} +1 -1
- package/dist/chunk-5GILG5AK.js.map +1 -0
- package/dist/{chunk-IP2J3BWY.js → chunk-6AMBZXZJ.js} +1 -1
- package/dist/chunk-6AMBZXZJ.js.map +1 -0
- package/dist/{chunk-XUKVQO6M.js → chunk-6CSUVVFG.js} +1 -1
- package/dist/chunk-6CSUVVFG.js.map +1 -0
- package/dist/{chunk-ELHESRRH.js → chunk-7FQQRTPX.js} +5 -5
- package/dist/chunk-7FQQRTPX.js.map +1 -0
- package/dist/{chunk-QNOHFHVL.js → chunk-7WB4CDWX.js} +4 -4
- package/dist/chunk-7WB4CDWX.js.map +1 -0
- package/dist/{chunk-47FHUOLT.js → chunk-BLFY5UAL.js} +1 -1
- package/dist/chunk-BLFY5UAL.js.map +1 -0
- package/dist/{chunk-CYLXW66E.js → chunk-C3QWJFSE.js} +2 -2
- package/dist/chunk-C3QWJFSE.js.map +1 -0
- package/dist/{chunk-QDFDMWXD.js → chunk-CNWRDTEW.js} +7 -7
- package/dist/chunk-CNWRDTEW.js.map +1 -0
- package/dist/{chunk-2IEXY3OZ.js → chunk-CVKAGR3D.js} +4 -4
- package/dist/{chunk-LZHERDNB.js → chunk-CXIWRNSP.js} +5 -5
- package/dist/chunk-CXIWRNSP.js.map +1 -0
- package/dist/{chunk-FNJHS5KQ.js → chunk-E5JTEQ4V.js} +6 -6
- package/dist/chunk-E5JTEQ4V.js.map +1 -0
- package/dist/{chunk-IO4346TF.js → chunk-FC7T3INX.js} +8 -8
- package/dist/chunk-FC7T3INX.js.map +1 -0
- package/dist/{chunk-KCYM2JXP.js → chunk-FWSMUUZ5.js} +5 -5
- package/dist/chunk-FWSMUUZ5.js.map +1 -0
- package/dist/{chunk-3ABWBQCS.js → chunk-GTNCXOUL.js} +2 -2
- package/dist/chunk-GTNCXOUL.js.map +1 -0
- package/dist/{chunk-ZLPAXPDI.js → chunk-GVJ4M63W.js} +3 -3
- package/dist/{chunk-ZLPAXPDI.js.map → chunk-GVJ4M63W.js.map} +1 -1
- package/dist/{chunk-LBXIPDAB.js → chunk-JXD5DW6E.js} +3 -3
- package/dist/chunk-JXD5DW6E.js.map +1 -0
- package/dist/{chunk-P7Z5BREP.js → chunk-L6DBWUAB.js} +6 -6
- package/dist/chunk-L6DBWUAB.js.map +1 -0
- package/dist/{chunk-YZ7MDC6B.js → chunk-LNL4TCGL.js} +2 -2
- package/dist/chunk-LNL4TCGL.js.map +1 -0
- package/dist/{chunk-TCYDVNSU.js → chunk-MT4VH7QV.js} +1 -1
- package/dist/chunk-MT4VH7QV.js.map +1 -0
- package/dist/{chunk-DKENCYHA.js → chunk-MXGY2ENX.js} +1 -1
- package/dist/chunk-MXGY2ENX.js.map +1 -0
- package/dist/{chunk-DUCIAQGR.js → chunk-NENNFQEY.js} +3 -3
- package/dist/chunk-NENNFQEY.js.map +1 -0
- package/dist/{chunk-LBQMEHK6.js → chunk-NPFMPRII.js} +1 -1
- package/dist/chunk-NPFMPRII.js.map +1 -0
- package/dist/{chunk-NS7FKOFI.js → chunk-NYXU5EFE.js} +1 -1
- package/dist/chunk-NYXU5EFE.js.map +1 -0
- package/dist/{chunk-S66GKX2W.js → chunk-OAWUZIIN.js} +1 -1
- package/dist/chunk-OAWUZIIN.js.map +1 -0
- package/dist/{chunk-JNZODUXP.js → chunk-OYDG6C54.js} +1 -1
- package/dist/chunk-OYDG6C54.js.map +1 -0
- package/dist/{chunk-FFXRFQSU.js → chunk-POBOJBNJ.js} +1 -1
- package/dist/chunk-POBOJBNJ.js.map +1 -0
- package/dist/{chunk-RIBB5OJV.js → chunk-PR2MCHU4.js} +4 -4
- package/dist/chunk-PR2MCHU4.js.map +1 -0
- package/dist/{chunk-LEOIKO7C.js → chunk-RLWP6NJU.js} +4 -4
- package/dist/chunk-RLWP6NJU.js.map +1 -0
- package/dist/{chunk-V7KDUUV6.js → chunk-RMNV2CE2.js} +2 -2
- package/dist/chunk-RMNV2CE2.js.map +1 -0
- package/dist/{chunk-ZXYQ2ZPR.js → chunk-TEMTIMAH.js} +3 -3
- package/dist/chunk-TEMTIMAH.js.map +1 -0
- package/dist/{chunk-NPM7IDYV.js → chunk-TSFAAREV.js} +3 -3
- package/dist/chunk-TSFAAREV.js.map +1 -0
- package/dist/{chunk-54HHEXXD.js → chunk-VKN374SD.js} +1 -1
- package/dist/chunk-VKN374SD.js.map +1 -0
- package/dist/{chunk-ZMA7BT2L.js → chunk-XWBJPA3D.js} +4 -4
- package/dist/{chunk-ZMA7BT2L.js.map → chunk-XWBJPA3D.js.map} +1 -1
- package/dist/{chunk-QZRBO7BE.js → chunk-Z4KFHRDW.js} +9 -9
- package/dist/chunk-Z4KFHRDW.js.map +1 -0
- package/dist/{chunk-TXRQCHOR.js → chunk-ZAR3SCPV.js} +5 -5
- package/dist/chunk-ZAR3SCPV.js.map +1 -0
- package/dist/color-picker.js +19 -19
- package/dist/date-picker.js +10 -10
- package/dist/date-picker.js.map +1 -1
- package/dist/divider.js +2 -2
- package/dist/divider.js.map +1 -1
- package/dist/drawer.js +7 -7
- package/dist/dropdown.js +7 -7
- package/dist/empty.js +5 -5
- package/dist/field.js +2 -2
- package/dist/field.js.map +1 -1
- package/dist/float-button.js +6 -6
- package/dist/float-button.js.map +1 -1
- package/dist/image.js +8 -8
- package/dist/image.js.map +1 -1
- package/dist/input-number.js +6 -6
- package/dist/input.js +8 -8
- package/dist/list.js +12 -12
- package/dist/list.js.map +1 -1
- package/dist/loading.js +1 -1
- package/dist/logo.js.map +1 -1
- package/dist/mari.css +8 -2
- package/dist/masonry.js +5 -5
- package/dist/masonry.js.map +1 -1
- package/dist/menu.js +10 -10
- package/dist/menu.js.map +1 -1
- package/dist/modal.js +8 -8
- package/dist/modal.js.map +1 -1
- package/dist/pagination.js +5 -5
- package/dist/popconfirm.js +13 -13
- package/dist/popconfirm.js.map +1 -1
- package/dist/popover.js +10 -10
- package/dist/progress.js +2 -2
- package/dist/progress.js.map +1 -1
- package/dist/qrcode.js +1 -1
- package/dist/qrcode.js.map +1 -1
- package/dist/radio.js +4 -4
- package/dist/radio.js.map +1 -1
- package/dist/rate.js +2 -2
- package/dist/rate.js.map +1 -1
- package/dist/segmented.js +4 -4
- package/dist/select.js +11 -11
- package/dist/skeleton.js +3 -3
- package/dist/slider.js +8 -8
- package/dist/slider.js.map +1 -1
- package/dist/splitter.js.map +1 -1
- package/dist/statistic.js +7 -7
- package/dist/statistic.js.map +1 -1
- package/dist/steps.js +4 -4
- package/dist/steps.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/switch.js +2 -2
- package/dist/switch.js.map +1 -1
- package/dist/table.js +19 -19
- package/dist/table.js.map +1 -1
- package/dist/tabs.js +2 -2
- package/dist/tabs.js.map +1 -1
- package/dist/tag.js +3 -3
- package/dist/theme-customizer.js +19 -19
- package/dist/theme-customizer.js.map +1 -1
- package/dist/timeline.js +5 -5
- package/dist/timeline.js.map +1 -1
- package/dist/toast.js +7 -7
- package/dist/tooltip.js +4 -4
- package/dist/tour.js +12 -12
- package/dist/tour.js.map +1 -1
- package/dist/transfer.js +11 -11
- package/dist/transfer.js.map +1 -1
- package/dist/tree-select.js +12 -12
- package/dist/tree-select.js.map +1 -1
- package/dist/tree.js +5 -5
- package/dist/types/accordion/Accordion.d.ts +1 -3
- package/dist/types/accordion/Accordion.d.ts.map +1 -1
- package/dist/types/alert/Alert.d.ts +0 -1
- package/dist/types/alert/Alert.d.ts.map +1 -1
- package/dist/types/autocomplete/AutoComplete.d.ts +2 -2
- package/dist/types/autocomplete/utils.d.ts +0 -8
- package/dist/types/autocomplete/utils.d.ts.map +1 -1
- package/dist/types/avatar/utils.d.ts +1 -1
- package/dist/types/badge/Badge.d.ts +0 -3
- package/dist/types/badge/Badge.d.ts.map +1 -1
- package/dist/types/breadcrumb/Breadcrumb.d.ts +1 -12
- package/dist/types/breadcrumb/Breadcrumb.d.ts.map +1 -1
- package/dist/types/breadcrumb/utils.d.ts +0 -7
- package/dist/types/breadcrumb/utils.d.ts.map +1 -1
- package/dist/types/button/types.d.ts +1 -9
- package/dist/types/button/types.d.ts.map +1 -1
- package/dist/types/calendar/Calendar.d.ts +3 -4
- package/dist/types/calendar/Calendar.d.ts.map +1 -1
- package/dist/types/calendar/_components/CalendarPanel.d.ts +1 -2
- package/dist/types/calendar/_components/CalendarPanel.d.ts.map +1 -1
- package/dist/types/calendar/_components/DayGrid.d.ts +1 -1
- package/dist/types/calendar/types.d.ts +1 -1
- package/dist/types/calendar/types.d.ts.map +1 -1
- package/dist/types/card/Card.d.ts +3 -4
- package/dist/types/card/Card.d.ts.map +1 -1
- package/dist/types/card/types.d.ts +1 -1
- package/dist/types/carousel/types.d.ts +4 -10
- package/dist/types/carousel/types.d.ts.map +1 -1
- package/dist/types/carousel/utils.d.ts +0 -11
- package/dist/types/carousel/utils.d.ts.map +1 -1
- package/dist/types/chart/_shared/paths.d.ts +1 -1
- package/dist/types/chart/_shared/scale.d.ts +1 -2
- package/dist/types/chart/_shared/scale.d.ts.map +1 -1
- package/dist/types/chart/bar-chart/BarChart.d.ts +1 -1
- package/dist/types/chart/gauge/Gauge.d.ts +1 -1
- package/dist/types/chart/line-chart/LineChart.d.ts +2 -2
- package/dist/types/chart/pie-chart/PieChart.d.ts +1 -1
- package/dist/types/chart/sparkline/Sparkline.d.ts +1 -1
- package/dist/types/checkbox/utils.d.ts.map +1 -1
- package/dist/types/color-picker/ColorPicker.d.ts +0 -6
- package/dist/types/color-picker/ColorPicker.d.ts.map +1 -1
- package/dist/types/color-picker/_components/ColorPresets.d.ts +1 -1
- package/dist/types/color-picker/_components/ColorPresets.d.ts.map +1 -1
- package/dist/types/color-picker/utils.d.ts +1 -1
- package/dist/types/date-picker/DatePicker.d.ts +0 -6
- package/dist/types/date-picker/DatePicker.d.ts.map +1 -1
- package/dist/types/date-picker/TimePicker.d.ts +1 -1
- package/dist/types/date-picker/_components/TimePanel.d.ts.map +1 -1
- package/dist/types/date-picker/utils.d.ts +1 -1
- package/dist/types/date-picker/utils.d.ts.map +1 -1
- package/dist/types/divider/Divider.d.ts +1 -1
- package/dist/types/divider/types.d.ts +2 -4
- package/dist/types/divider/types.d.ts.map +1 -1
- package/dist/types/drawer/Drawer.d.ts +5 -6
- package/dist/types/drawer/Drawer.d.ts.map +1 -1
- package/dist/types/dropdown/_components/DropdownContent.d.ts +1 -1
- package/dist/types/dropdown/_components/DropdownItem.d.ts +0 -5
- package/dist/types/dropdown/_components/DropdownItem.d.ts.map +1 -1
- package/dist/types/dropdown/types.d.ts +1 -1
- package/dist/types/dropdown/useDropdown.d.ts +0 -16
- package/dist/types/dropdown/useDropdown.d.ts.map +1 -1
- package/dist/types/dropdown/utils.d.ts +1 -1
- package/dist/types/empty/Empty.d.ts +1 -6
- package/dist/types/empty/Empty.d.ts.map +1 -1
- package/dist/types/field/Field.d.ts +1 -5
- package/dist/types/field/Field.d.ts.map +1 -1
- package/dist/types/float-button/BackTop.d.ts +1 -1
- package/dist/types/float-button/FloatButton.d.ts +0 -5
- package/dist/types/float-button/FloatButton.d.ts.map +1 -1
- package/dist/types/float-button/FloatButtonGroup.d.ts +1 -1
- package/dist/types/float-button/utils.d.ts +1 -1
- package/dist/types/foundations/usePersonaTheme.d.ts +1 -1
- package/dist/types/image/Image.d.ts +0 -6
- package/dist/types/image/Image.d.ts.map +1 -1
- package/dist/types/image/ImageGallery.d.ts +1 -1
- package/dist/types/image/ImageViewer.d.ts +1 -1
- package/dist/types/image/galleryUtils.d.ts +1 -1
- package/dist/types/input/SearchInput.d.ts +1 -6
- package/dist/types/input/SearchInput.d.ts.map +1 -1
- package/dist/types/input/Textarea.d.ts +2 -6
- package/dist/types/input/Textarea.d.ts.map +1 -1
- package/dist/types/input/mention/types.d.ts +1 -2
- package/dist/types/input/mention/types.d.ts.map +1 -1
- package/dist/types/input/types.d.ts +3 -15
- package/dist/types/input/types.d.ts.map +1 -1
- package/dist/types/input/utils.d.ts +1 -26
- package/dist/types/input/utils.d.ts.map +1 -1
- package/dist/types/input-number/InputNumber.d.ts +0 -2
- package/dist/types/input-number/InputNumber.d.ts.map +1 -1
- package/dist/types/input-number/utils.d.ts +1 -1
- package/dist/types/lib/ContentSkeleton.d.ts +1 -1
- package/dist/types/lib/FloatingArrow.d.ts +0 -10
- package/dist/types/lib/FloatingArrow.d.ts.map +1 -1
- package/dist/types/lib/SkeletonDemo.d.ts +1 -1
- package/dist/types/lib/SkeletonSlot.d.ts +1 -1
- package/dist/types/lib/colorClasses.d.ts +1 -7
- package/dist/types/lib/colorClasses.d.ts.map +1 -1
- package/dist/types/lib/date/index.d.ts +1 -1
- package/dist/types/lib/elevationClass.d.ts +0 -8
- package/dist/types/lib/elevationClass.d.ts.map +1 -1
- package/dist/types/lib/fieldContext.d.ts +1 -1
- package/dist/types/lib/floating.d.ts +2 -7
- package/dist/types/lib/floating.d.ts.map +1 -1
- package/dist/types/lib/infiniteScroll.d.ts +1 -1
- package/dist/types/lib/linkBehavior.d.ts +1 -1
- package/dist/types/lib/overlay.d.ts +0 -7
- package/dist/types/lib/overlay.d.ts.map +1 -1
- package/dist/types/lib/sizeClasses.d.ts +2 -2
- package/dist/types/lib/skeleton.d.ts +1 -1
- package/dist/types/lib/storyMeta.d.ts +7 -28
- package/dist/types/lib/storyMeta.d.ts.map +1 -1
- package/dist/types/lib/storybookArgTypes.d.ts +1 -1
- package/dist/types/lib/useFloatingPosition.d.ts +1 -1
- package/dist/types/list/List.d.ts +0 -4
- package/dist/types/list/List.d.ts.map +1 -1
- package/dist/types/loading/Loading.d.ts.map +1 -1
- package/dist/types/loading/types.d.ts +2 -5
- package/dist/types/loading/types.d.ts.map +1 -1
- package/dist/types/loading/utils.d.ts +0 -5
- package/dist/types/loading/utils.d.ts.map +1 -1
- package/dist/types/masonry/Masonry.d.ts +0 -4
- package/dist/types/masonry/Masonry.d.ts.map +1 -1
- package/dist/types/menu/_shared/MenuLink.d.ts +0 -4
- package/dist/types/menu/_shared/MenuLink.d.ts.map +1 -1
- package/dist/types/menu/_shared/MobileNav.d.ts +0 -6
- package/dist/types/menu/_shared/MobileNav.d.ts.map +1 -1
- package/dist/types/menu/_shared/NavBar.d.ts +0 -8
- package/dist/types/menu/_shared/NavBar.d.ts.map +1 -1
- package/dist/types/menu/basic-menu/BasicMenu.d.ts +2 -16
- package/dist/types/menu/basic-menu/BasicMenu.d.ts.map +1 -1
- package/dist/types/menu/mega-menu/MegaMenu.d.ts +0 -8
- package/dist/types/menu/mega-menu/MegaMenu.d.ts.map +1 -1
- package/dist/types/menu/mega-menu/_components/MegaMenuItem.d.ts +0 -12
- package/dist/types/menu/mega-menu/_components/MegaMenuItem.d.ts.map +1 -1
- package/dist/types/menu/sidebar/Sidebar.d.ts +1 -16
- package/dist/types/menu/sidebar/Sidebar.d.ts.map +1 -1
- package/dist/types/menu/sidebar/_components/SidebarButton.d.ts +0 -6
- package/dist/types/menu/sidebar/_components/SidebarButton.d.ts.map +1 -1
- package/dist/types/menu/sidebar/_components/SidebarItem.d.ts +0 -10
- package/dist/types/menu/sidebar/_components/SidebarItem.d.ts.map +1 -1
- package/dist/types/menu/sidebar/_components/SidebarMenu.d.ts +0 -4
- package/dist/types/menu/sidebar/_components/SidebarMenu.d.ts.map +1 -1
- package/dist/types/menu/types.d.ts +2 -11
- package/dist/types/menu/types.d.ts.map +1 -1
- package/dist/types/menu/utils.d.ts +0 -22
- package/dist/types/menu/utils.d.ts.map +1 -1
- package/dist/types/modal/Modal.d.ts +1 -12
- package/dist/types/modal/Modal.d.ts.map +1 -1
- package/dist/types/modal/types.d.ts +3 -4
- package/dist/types/modal/types.d.ts.map +1 -1
- package/dist/types/modal/utils.d.ts +1 -5
- package/dist/types/modal/utils.d.ts.map +1 -1
- package/dist/types/pagination/Pagination.d.ts +2 -11
- package/dist/types/pagination/Pagination.d.ts.map +1 -1
- package/dist/types/pagination/types.d.ts +1 -1
- package/dist/types/pagination/types.d.ts.map +1 -1
- package/dist/types/pagination/utils.d.ts +5 -12
- package/dist/types/pagination/utils.d.ts.map +1 -1
- package/dist/types/popconfirm/Popconfirm.d.ts +0 -4
- package/dist/types/popconfirm/Popconfirm.d.ts.map +1 -1
- package/dist/types/popover/Popover.d.ts +0 -5
- package/dist/types/popover/Popover.d.ts.map +1 -1
- package/dist/types/progress/Progress.d.ts +0 -3
- package/dist/types/progress/Progress.d.ts.map +1 -1
- package/dist/types/qrcode/QRCode.d.ts +0 -6
- package/dist/types/qrcode/QRCode.d.ts.map +1 -1
- package/dist/types/radio/utils.d.ts +1 -1
- package/dist/types/segmented/Segmented.d.ts +0 -4
- package/dist/types/segmented/Segmented.d.ts.map +1 -1
- package/dist/types/select/Select.d.ts +0 -5
- package/dist/types/select/Select.d.ts.map +1 -1
- package/dist/types/select/_components/SelectPanel.d.ts +2 -3
- package/dist/types/select/_components/SelectPanel.d.ts.map +1 -1
- package/dist/types/select/types.d.ts +1 -1
- package/dist/types/select/types.d.ts.map +1 -1
- package/dist/types/skeleton/utils.d.ts.map +1 -1
- package/dist/types/slider/Slider.d.ts.map +1 -1
- package/dist/types/slider/utils.d.ts +0 -1
- package/dist/types/slider/utils.d.ts.map +1 -1
- package/dist/types/splitter/Splitter.d.ts +4 -4
- package/dist/types/statistic/Statistic.d.ts +1 -1
- package/dist/types/statistic/utils.d.ts +2 -4
- package/dist/types/statistic/utils.d.ts.map +1 -1
- package/dist/types/steps/Steps.d.ts.map +1 -1
- package/dist/types/steps/_components/StepsContent.d.ts +1 -10
- package/dist/types/steps/_components/StepsContent.d.ts.map +1 -1
- package/dist/types/steps/types.d.ts +1 -1
- package/dist/types/steps/types.d.ts.map +1 -1
- package/dist/types/steps/utils.d.ts +0 -9
- package/dist/types/steps/utils.d.ts.map +1 -1
- package/dist/types/switch/Switch.d.ts +1 -9
- package/dist/types/switch/Switch.d.ts.map +1 -1
- package/dist/types/switch/utils.d.ts.map +1 -1
- package/dist/types/table/Table.d.ts +7 -11
- package/dist/types/table/Table.d.ts.map +1 -1
- package/dist/types/table/_components/TableBody.d.ts.map +1 -1
- package/dist/types/table/_components/TableEditDrawer.d.ts +0 -8
- package/dist/types/table/_components/TableEditDrawer.d.ts.map +1 -1
- package/dist/types/table/_components/TableHeader.d.ts +0 -7
- package/dist/types/table/_components/TableHeader.d.ts.map +1 -1
- package/dist/types/table/_components/TableInfoValue.d.ts +0 -10
- package/dist/types/table/_components/TableInfoValue.d.ts.map +1 -1
- package/dist/types/table/_components/TablePagination.d.ts +0 -12
- package/dist/types/table/_components/TablePagination.d.ts.map +1 -1
- package/dist/types/table/_components/TableRowActions.d.ts +0 -6
- package/dist/types/table/_components/TableRowActions.d.ts.map +1 -1
- package/dist/types/table/types.d.ts +2 -18
- package/dist/types/table/types.d.ts.map +1 -1
- package/dist/types/table/utils.d.ts +1 -7
- package/dist/types/table/utils.d.ts.map +1 -1
- package/dist/types/tabs/Tabs.d.ts +0 -1
- package/dist/types/tabs/Tabs.d.ts.map +1 -1
- package/dist/types/tabs/_components/TabsContent.d.ts +0 -5
- package/dist/types/tabs/_components/TabsContent.d.ts.map +1 -1
- package/dist/types/tabs/_components/TabsList.d.ts +6 -6
- package/dist/types/tabs/_components/TabsTrigger.d.ts +1 -1
- package/dist/types/tabs/utils.d.ts +0 -5
- package/dist/types/tabs/utils.d.ts.map +1 -1
- package/dist/types/tag/utils.d.ts +0 -8
- package/dist/types/tag/utils.d.ts.map +1 -1
- package/dist/types/theme-customizer/ThemeCustomizer.d.ts +1 -1
- package/dist/types/timeline/Timeline.d.ts +1 -3
- package/dist/types/timeline/Timeline.d.ts.map +1 -1
- package/dist/types/toast/Toast.d.ts +2 -2
- package/dist/types/toast/useToast.d.ts +2 -4
- package/dist/types/toast/useToast.d.ts.map +1 -1
- package/dist/types/toast/utils.d.ts +0 -1
- package/dist/types/toast/utils.d.ts.map +1 -1
- package/dist/types/tooltip/Tooltip.d.ts.map +1 -1
- package/dist/types/tooltip/utils.d.ts +0 -6
- package/dist/types/tooltip/utils.d.ts.map +1 -1
- package/dist/types/tour/Tour.d.ts +0 -6
- package/dist/types/tour/Tour.d.ts.map +1 -1
- package/dist/types/tour/utils.d.ts +1 -1
- package/dist/types/tour/utils.d.ts.map +1 -1
- package/dist/types/transfer/Transfer.d.ts +0 -5
- package/dist/types/transfer/Transfer.d.ts.map +1 -1
- package/dist/types/transfer/utils.d.ts +1 -3
- package/dist/types/transfer/utils.d.ts.map +1 -1
- package/dist/types/tree/Tree.d.ts +0 -6
- package/dist/types/tree/Tree.d.ts.map +1 -1
- package/dist/types/tree/utils.d.ts +1 -1
- package/dist/types/tree-select/TreeSelect.d.ts +0 -6
- package/dist/types/tree-select/TreeSelect.d.ts.map +1 -1
- package/dist/types/tree-select/_components/TreeSelectPanel.d.ts +1 -1
- package/dist/types/tree-select/utils.d.ts +1 -1
- package/dist/types/typography/utils.d.ts.map +1 -1
- package/dist/types/upload/_components/List.d.ts +0 -7
- package/dist/types/upload/_components/List.d.ts.map +1 -1
- package/dist/types/upload/_components/ReviewList.d.ts +0 -8
- package/dist/types/upload/_components/ReviewList.d.ts.map +1 -1
- package/dist/types/upload/_components/UploadDragDropButton.d.ts +0 -8
- package/dist/types/upload/_components/UploadDragDropButton.d.ts.map +1 -1
- package/dist/types/upload/_components/UploadReviewButton.d.ts +0 -5
- package/dist/types/upload/_components/UploadReviewButton.d.ts.map +1 -1
- package/dist/types/upload/types.d.ts +5 -8
- package/dist/types/upload/types.d.ts.map +1 -1
- package/dist/types/upload/useUpload.d.ts +0 -10
- package/dist/types/upload/useUpload.d.ts.map +1 -1
- package/dist/types/upload/utils.d.ts +0 -4
- package/dist/types/upload/utils.d.ts.map +1 -1
- package/dist/typewriter.js +1 -1
- package/dist/typography.js +2 -2
- package/dist/typography.js.map +1 -1
- package/dist/upload.js +8 -8
- package/dist/upload.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-3ABWBQCS.js.map +0 -1
- package/dist/chunk-47FHUOLT.js.map +0 -1
- package/dist/chunk-54HHEXXD.js.map +0 -1
- package/dist/chunk-BDV4GOEN.js.map +0 -1
- package/dist/chunk-CYLXW66E.js.map +0 -1
- package/dist/chunk-DKENCYHA.js.map +0 -1
- package/dist/chunk-DUCIAQGR.js.map +0 -1
- package/dist/chunk-ELHESRRH.js.map +0 -1
- package/dist/chunk-FFXRFQSU.js.map +0 -1
- package/dist/chunk-FNJHS5KQ.js.map +0 -1
- package/dist/chunk-IO4346TF.js.map +0 -1
- package/dist/chunk-IP2J3BWY.js.map +0 -1
- package/dist/chunk-JNZODUXP.js.map +0 -1
- package/dist/chunk-KCYM2JXP.js.map +0 -1
- package/dist/chunk-LBQMEHK6.js.map +0 -1
- package/dist/chunk-LBXIPDAB.js.map +0 -1
- package/dist/chunk-LEOIKO7C.js.map +0 -1
- package/dist/chunk-LZHERDNB.js.map +0 -1
- package/dist/chunk-NPM7IDYV.js.map +0 -1
- package/dist/chunk-NS7FKOFI.js.map +0 -1
- package/dist/chunk-P7Z5BREP.js.map +0 -1
- package/dist/chunk-QDFDMWXD.js.map +0 -1
- package/dist/chunk-QNOHFHVL.js.map +0 -1
- package/dist/chunk-QZRBO7BE.js.map +0 -1
- package/dist/chunk-RIBB5OJV.js.map +0 -1
- package/dist/chunk-S66GKX2W.js.map +0 -1
- package/dist/chunk-TCYDVNSU.js.map +0 -1
- package/dist/chunk-TXRQCHOR.js.map +0 -1
- package/dist/chunk-V7KDUUV6.js.map +0 -1
- package/dist/chunk-XUKVQO6M.js.map +0 -1
- package/dist/chunk-YZ7MDC6B.js.map +0 -1
- package/dist/chunk-ZXYQ2ZPR.js.map +0 -1
- /package/dist/{chunk-2IEXY3OZ.js.map → chunk-CVKAGR3D.js.map} +0 -0
package/dist/image.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/image/Image.tsx","../src/image/ImageViewer.tsx","../src/image/utils.ts","../src/image/viewerUtils.ts","../src/image/ImageGallery.tsx","../src/image/galleryUtils.ts"],"sourcesContent":["\"use client\";\n\nimport React, { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { EyeIcon, ImageOffIcon } from \"lucide-react\";\nimport { cn, useControllableState } from \"@mari-ui/core\";\nimport { skeletonBoxProps } from \"../lib/skeleton\";\nimport { ImageViewer } from \"./ImageViewer\";\nimport type { ImageFit, ImageLoader, ImagePreviewConfig, ImageProps } from \"./types\";\nimport { getBoxStyle, imgAttributes, normalizeSource, resolveBlurSource, resolveImage } from \"./utils\";\n\nexport type { ImageProps };\n\nconst FIT_CLASS: Record<ImageFit, string> = {\n cover: \"object-cover\",\n contain: \"object-contain\",\n fill: \"object-fill\",\n none: \"object-none\",\n \"scale-down\": \"object-scale-down\",\n};\n\ntype Status = \"loading\" | \"loaded\" | \"error\";\n\nfunction DefaultFallback() {\n return (\n <span className=\"flex size-full min-h-16 flex-col items-center justify-center gap-1 p-2 text-center text-xs text-mari-muted\">\n <ImageOffIcon aria-hidden className=\"size-6\" />\n Görsel yüklenemedi\n </span>\n );\n}\n\n/** Yüklenirken: bulanık ön izleme → özel içerik → parıltı (öncelik sırasıyla). */\nfunction PlaceholderLayer({ blurSrc, custom, shimmer, fit }: Readonly<{ blurSrc: string | null; custom: React.ReactNode; shimmer: boolean; fit: ImageFit }>) {\n if (blurSrc) {\n return <img src={blurSrc} alt=\"\" aria-hidden draggable={false} className={cn(\"absolute inset-0 size-full scale-110 blur-lg\", FIT_CLASS[fit])} />;\n }\n if (custom) {\n return (\n <span aria-hidden className=\"absolute inset-0 flex items-center justify-center\">\n {custom}\n </span>\n );\n }\n return shimmer ? <span aria-hidden className={cn(\"absolute inset-0\", skeletonBoxProps().className)} /> : null;\n}\n\nfunction placeholderNode(placeholder: ImageProps[\"placeholder\"]): React.ReactNode {\n return placeholder !== undefined && typeof placeholder !== \"boolean\" && typeof placeholder !== \"string\" ? placeholder : null;\n}\n\n/**\n * Faz 16.7 — yapı ant.design Image'dan (progressive loading: önce düşük\n * çözünürlüklü/bulanık ön izleme, asıl görsel yüklenince yumuşak geçiş;\n * `fallback`; `preview`), görünüm token'lardan. Framework'e bağlı değil: düz\n * `<img>` (`loading=\"lazy\"`, `decoding=\"async\"`, `srcSet`/`sizes`); CDN ve\n * boyutlandırma `loader` ile, `next/image`'a gerek yok.\n *\n * Dış kutu yeri önceden ayırır (`aspectRatio` ya da `width`/`height`) →\n * yüklenince sayfa kaymaz. `preview` ile kutu bir düğme olur ve tam ekran\n * `ImageViewer` açılır.\n */\nexport const Image = forwardRef<HTMLImageElement, ImageProps>(function Image(\n {\n src,\n alt,\n width,\n height,\n aspectRatio,\n fit = \"cover\",\n loader,\n widths,\n sizes,\n quality,\n placeholder,\n fallback,\n loading = \"lazy\",\n priority = false,\n preview = false,\n skeleton = false,\n className,\n wrapperClassName,\n style,\n onLoad,\n onError,\n ...imgProps\n },\n ref\n) {\n const source = normalizeSource(src);\n const [status, setStatus] = useState<Status>(\"loading\");\n const imgRef = useRef<HTMLImageElement | null>(null);\n\n const resolved = source ? resolveImage(source, { loader, width, widths, quality }) : null;\n const effectivePlaceholder = placeholder ?? (source?.blurDataURL ? true : undefined);\n const blurSrc = source ? resolveBlurSource(effectivePlaceholder, source, loader) : null;\n const customPlaceholder = placeholderNode(effectivePlaceholder);\n\n // Kaynak değişince baştan.\n const key = resolved ? `${resolved.src}|${resolved.srcSet ?? \"\"}` : \"\";\n useEffect(() => {\n setStatus(\"loading\");\n // SSR'dan gelen ya da önbellekteki görsel hidrasyondan önce yüklenmiş olabilir — `onLoad` hiç gelmez.\n const img = imgRef.current;\n if (img?.complete) setStatus(img.naturalWidth > 0 ? \"loaded\" : \"error\");\n }, [key]);\n\n const boxStyle = getBoxStyle({ width, height, aspectRatio, source });\n const boxClass = cn(\n \"relative isolate inline-block max-w-full overflow-hidden rounded-md align-middle\",\n status !== \"loaded\" && \"bg-mari-surface-alt\",\n wrapperClassName\n );\n\n if (skeleton) {\n const sk = skeletonBoxProps(boxClass);\n // Boyut bilinmiyorsa iskelet görünür kalsın diye makul bir oran.\n const skStyle = Object.keys(boxStyle).length ? boxStyle : { width: \"100%\", aspectRatio: \"4 / 3\" };\n return <span {...sk} className={cn(sk.className, \"block\")} style={{ ...skStyle, ...style }} />;\n }\n\n const setRefs = (el: HTMLImageElement | null) => {\n imgRef.current = el;\n if (typeof ref === \"function\") ref(el);\n else if (ref) ref.current = el;\n };\n\n const loaded = status === \"loaded\";\n const failed = status === \"error\" || !source;\n\n const content = (\n <>\n {!loaded && !failed && (\n <PlaceholderLayer blurSrc={blurSrc} custom={customPlaceholder} shimmer={effectivePlaceholder === true} fit={fit} />\n )}\n {resolved && status !== \"error\" && (\n <img\n {...imgProps}\n ref={setRefs}\n src={resolved.src}\n srcSet={resolved.srcSet}\n {...imgAttributes({ width, height, source, srcSet: resolved.srcSet, sizes, priority, loading, fetchPriority: imgProps.fetchPriority })}\n alt={alt}\n decoding=\"async\"\n onLoad={(event) => {\n setStatus(\"loaded\");\n onLoad?.(event);\n }}\n onError={(event) => {\n setStatus(\"error\");\n onError?.(event);\n }}\n className={cn(\n \"relative block size-full transition-opacity duration-500 motion-reduce:transition-none\",\n FIT_CLASS[fit],\n loaded ? \"opacity-100\" : \"opacity-0\",\n className\n )}\n />\n )}\n {failed && <FallbackLayer key={key} fallback={fallback} alt={alt} className={cn(FIT_CLASS[fit], className)} />}\n </>\n );\n\n if (!preview) {\n return (\n <span className={boxClass} style={{ ...boxStyle, ...style }}>\n {content}\n </span>\n );\n }\n\n return (\n <PreviewFrame\n config={typeof preview === \"object\" ? preview : {}}\n src={src}\n alt={alt}\n loader={loader}\n loaded={loaded}\n disabled={failed}\n thumbnail={() => imgRef.current?.currentSrc || resolved?.src}\n className={boxClass}\n style={{ ...boxStyle, ...style }}\n >\n {content}\n </PreviewFrame>\n );\n});\n\n/** Yüklenemezse: URL yedeği (o da yüklenemezse varsayılan), node ya da varsayılan. */\nfunction FallbackLayer({ fallback, alt, className }: Readonly<{ fallback: ImageProps[\"fallback\"]; alt: string; className?: string }>) {\n const [urlFailed, setUrlFailed] = useState(false);\n if (typeof fallback === \"string\" && !urlFailed) {\n return <img src={fallback} alt={alt} onError={() => setUrlFailed(true)} className={cn(\"block size-full\", className)} />;\n }\n if (typeof fallback !== \"string\" && fallback) return <>{fallback}</>;\n return <DefaultFallback />;\n}\n\n/** `preview`: kutu bir düğme olur, tam ekran görüntüleyiciyi açar; kapanınca odak düğmeye döner. */\nfunction PreviewFrame({\n config,\n src,\n alt,\n loader,\n loaded,\n disabled,\n thumbnail,\n className,\n style,\n children,\n}: Readonly<{\n config: ImagePreviewConfig;\n src: ImageProps[\"src\"];\n alt: string;\n loader?: ImageLoader;\n loaded: boolean;\n disabled: boolean;\n thumbnail: () => string | undefined;\n className: string;\n style: React.CSSProperties;\n children: React.ReactNode;\n}>) {\n const triggerRef = useRef<HTMLButtonElement>(null);\n const [open, setOpen] = useControllableState({ value: config.open, defaultValue: false, onChange: config.onOpenChange });\n const previewSource = config.src ?? src;\n return (\n <>\n <button\n ref={triggerRef}\n type=\"button\"\n aria-haspopup=\"dialog\"\n aria-label={alt ? `${alt} — büyüt` : \"Görseli büyüt\"}\n disabled={disabled}\n onClick={() => setOpen(true)}\n className={cn(\n className,\n \"group cursor-zoom-in focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-mari-ring disabled:cursor-default\"\n )}\n style={style}\n >\n {children}\n {loaded && (\n <span\n aria-hidden\n className=\"absolute inset-0 flex items-center justify-center gap-1.5 bg-mari-scrim text-sm font-medium text-white opacity-0 transition-opacity duration-200 group-hover:opacity-100 group-focus-visible:opacity-100 pointer-coarse:hidden\"\n >\n <EyeIcon className=\"size-4\" />\n Önizle\n </span>\n )}\n </button>\n {previewSource && (\n <ImageViewer\n open={open ?? false}\n onClose={() => setOpen(false)}\n loader={loader}\n getOriginElement={() => triggerRef.current}\n items={[{ key: \"preview\", src: previewSource, alt, caption: config.caption, thumbnail: thumbnail() }]}\n />\n )}\n </>\n );\n}\n","\"use client\";\n\nimport React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { ChevronLeftIcon, ChevronRightIcon, ImageOffIcon, Loader2Icon, XIcon, ZoomInIcon, ZoomOutIcon } from \"lucide-react\";\nimport { cn, useControllableState } from \"@mari-ui/core\";\nimport { Button } from \"../button\";\nimport { useModalBehavior, usePresence } from \"../lib/overlay\";\nimport type { ImageLoader, ImageSource } from \"./types\";\nimport { normalizeSource, resolveImage } from \"./utils\";\nimport {\n IDENTITY,\n MAX_SCALE,\n MIN_SCALE,\n clampPan,\n containSize,\n dismissProgress,\n dragIntent,\n originTransform,\n shouldDismiss,\n swipeOutcome,\n toggleZoom,\n visibleSlides,\n zoomAround,\n type Size,\n type ViewState,\n} from \"./viewerUtils\";\n\nexport interface ImageViewerItem {\n key: React.Key;\n /** Tam çözünürlüklü kaynak (video için video adresi). */\n src: ImageSource;\n alt: string;\n /** Asıl görsel yüklenene kadar altta gösterilen küçük boy; alt şeritte de kullanılır. */\n thumbnail?: string;\n caption?: React.ReactNode;\n /** Varsayılan: `\"image\"`. Videoda yakınlaştırma yoktur, yerel oynatıcı denetimleri kullanılır. */\n type?: \"image\" | \"video\";\n /** Video kapak görseli. */\n poster?: string;\n /** Video altyazı/açıklama izleri (WebVTT). Konuşma içeren videolarda verin. */\n tracks?: { src: string; srcLang: string; label: string; kind?: \"captions\" | \"subtitles\" | \"descriptions\"; default?: boolean }[];\n}\n\nexport interface ImageViewerProps {\n items: ImageViewerItem[];\n open: boolean;\n onClose: () => void;\n index?: number;\n defaultIndex?: number;\n onIndexChange?: (index: number) => void;\n loader?: ImageLoader;\n /**\n * Bir öğenin sayfadaki küçük resmi (genelde tetikleyici düğme): açılış/kapanış\n * o kutudan büyüyerek/küçülerek olur, kapanınca odak ona döner.\n */\n getOriginElement?: (index: number) => HTMLElement | null | undefined;\n /** Alt şerit. Varsayılan: birden fazla öğe varsa. */\n thumbnails?: boolean;\n /** Üst çubuğa ek eylemler (paylaş, sil…). */\n actions?: (item: ImageViewerItem, index: number) => React.ReactNode;\n \"aria-label\"?: string;\n}\n\nconst EXIT_MS = 250;\nconst ENTER_MS = 300;\nconst SETTLE_MS = 250;\nconst SLIDE_GAP = 24;\nconst DOUBLE_TAP_MS = 280;\nconst ZOOM_STEP = 1.5;\nconst EASE = \"cubic-bezier(0.2, 0.8, 0.2, 1)\";\n\ninterface Gesture {\n kind: \"pending\" | \"swipe\" | \"dismiss\" | \"pan\" | \"pinch\";\n startX: number;\n startY: number;\n lastX: number;\n lastY: number;\n lastT: number;\n vx: number;\n vy: number;\n dx: number;\n dy: number;\n startView: ViewState;\n startDist: number;\n startMid: { x: number; y: number };\n pointerType: string;\n}\n\nfunction reducedMotion(): boolean {\n return typeof window !== \"undefined\" && window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches === true;\n}\n\nfunction setStyle(el: HTMLElement | null | undefined, transform: string, ms: number) {\n if (!el) return;\n el.style.transition = ms > 0 ? `transform ${ms}ms ${EASE}, opacity ${ms}ms ${EASE}` : \"none\";\n el.style.transform = transform;\n}\n\nfunction zoomLevelOf(scale: number): \"min\" | \"mid\" | \"max\" {\n if (scale <= MIN_SCALE) return \"min\";\n return scale >= MAX_SCALE ? \"max\" : \"mid\";\n}\n\n/** Başlangıç durumunu uygula ki ardından gelen geçiş ondan başlasın. */\nfunction forceReflow(el: HTMLElement | null | undefined) {\n el?.getBoundingClientRect();\n}\n\nconst viewTransform = (v: ViewState) => `translate3d(${v.x}px, ${v.y}px, 0) scale(${v.scale})`;\n\n/** Küçük resim adresi: verilen `thumbnail` → `loader` küçük boy → kaynağın kendisi. */\nexport function viewerThumbnail(item: ImageViewerItem, loader: ImageLoader | undefined, width = 160): string | undefined {\n if (item.thumbnail) return item.thumbnail;\n if (item.type === \"video\") return item.poster;\n const source = normalizeSource(item.src);\n if (!source) return undefined;\n return loader ? loader({ src: source.src, width }) : source.src;\n}\n\nfunction ViewerSlide({\n item,\n offset,\n loader,\n}: Readonly<{\n item: ImageViewerItem;\n offset: number;\n loader?: ImageLoader;\n}>) {\n const active = offset === 0;\n const source = normalizeSource(item.src);\n const [loaded, setLoaded] = useState(false);\n const [failed, setFailed] = useState(false);\n const thumb = viewerThumbnail(item, loader);\n const resolved = source && item.type !== \"video\" ? resolveImage(source, { loader }) : null;\n\n return (\n <div\n data-viewer-slide=\"\"\n data-viewer-active={active ? \"\" : undefined}\n aria-hidden={active ? undefined : true}\n className=\"absolute inset-0\"\n style={{ transform: `translateX(calc(${offset * 100}% + ${offset * SLIDE_GAP}px))` }}\n >\n <div data-viewer-zoom=\"\" className=\"relative flex size-full items-center justify-center will-change-transform\">\n {item.type === \"video\" ? (\n source && (\n // Altyazılar `tracks` ile tüketiciden gelir (kural eşlenmiş <track>ları göremiyor).\n // eslint-disable-next-line jsx-a11y/media-has-caption\n <video\n src={source.src}\n poster={item.poster}\n controls\n playsInline\n preload=\"metadata\"\n tabIndex={active ? 0 : -1}\n aria-label={item.alt}\n className=\"max-h-full max-w-full\"\n >\n {item.tracks?.map((t) => (\n <track key={t.src} kind={t.kind ?? \"captions\"} src={t.src} srcLang={t.srcLang} label={t.label} default={t.default} />\n ))}\n </video>\n )\n ) : (\n <>\n {thumb && !loaded && !failed && (\n <img src={thumb} alt=\"\" aria-hidden draggable={false} className=\"absolute inset-0 size-full object-contain blur-sm\" />\n )}\n {resolved && !failed && (\n <img\n data-viewer-full=\"\"\n src={resolved.src}\n srcSet={resolved.srcSet}\n sizes=\"100vw\"\n alt={item.alt}\n draggable={false}\n decoding=\"async\"\n onLoad={() => setLoaded(true)}\n onError={() => setFailed(true)}\n className={cn(\n \"absolute inset-0 size-full object-contain transition-opacity duration-300 motion-reduce:transition-none\",\n loaded ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n )}\n {!loaded && !failed && !thumb && <Loader2Icon aria-hidden className=\"size-8 animate-spin text-mari-muted\" />}\n {failed && (\n <div className=\"flex flex-col items-center gap-2 text-sm text-mari-muted\">\n <ImageOffIcon aria-hidden className=\"size-10\" />\n Görsel yüklenemedi\n </div>\n )}\n </>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Faz 16.7 — tam ekran görsel/video görüntüleyici. Yapı iPhone Fotoğraflar'dan:\n * küçük resimden büyüyerek açılış, yana kaydırarak geçiş, aşağı çekerek kapatma,\n * iki parmak / tekerlek / çift dokunuşla yakınlaştırma + kaydırma, dokununca\n * araç çubuklarını gizleme, alt şerit. Görünüm token'lardan (arka plan =\n * `mari-surface`: açık temada beyaz, koyu temada koyu — iPhone gibi).\n * `Image`'ın `preview`'ı ve `ImageGallery` bunu kullanır.\n */\nexport function ImageViewer({\n items,\n open,\n onClose,\n index: indexProp,\n defaultIndex = 0,\n onIndexChange,\n loader,\n getOriginElement,\n thumbnails,\n actions,\n \"aria-label\": ariaLabel = \"Görsel görüntüleyici\",\n}: ImageViewerProps) {\n const [rawIndex, setIndex] = useControllableState({ value: indexProp, defaultValue: defaultIndex, onChange: onIndexChange });\n const count = items.length;\n const index = Math.min(Math.max(rawIndex ?? 0, 0), Math.max(count - 1, 0));\n const item = items[index];\n const present = usePresence(open, EXIT_MS);\n\n const panelRef = useRef<HTMLDivElement>(null);\n const stageRef = useRef<HTMLDivElement>(null);\n const trackRef = useRef<HTMLDivElement>(null);\n const backdropRef = useRef<HTMLDivElement>(null);\n const stripRef = useRef<HTMLDivElement>(null);\n const view = useRef<ViewState>(IDENTITY);\n const pointers = useRef(new Map<number, { x: number; y: number }>());\n const gesture = useRef<Gesture | null>(null);\n const busy = useRef(false);\n const lastTap = useRef<{ t: number; x: number; y: number } | null>(null);\n const tapTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const goTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const indexRef = useRef(index);\n indexRef.current = index;\n // Yalnız eşik geçişlerinde render: hareket başına değil.\n const [zoomLevel, setZoomLevel] = useState<\"min\" | \"mid\" | \"max\">(\"min\");\n const zoomed = zoomLevel !== \"min\";\n const [chrome, setChrome] = useState(true);\n\n useModalBehavior(open, panelRef, onClose, {\n getInitialFocus: (panel) => panel.querySelector<HTMLElement>(\"[data-viewer-close]\"),\n });\n\n const isVideo = item?.type === \"video\";\n const showStrip = (thumbnails ?? count > 1) && count > 1;\n\n const zoomEl = () => trackRef.current?.querySelector<HTMLElement>(\"[data-viewer-active] [data-viewer-zoom]\") ?? null;\n const stageSize = (): Size => ({ width: stageRef.current?.clientWidth ?? 0, height: stageRef.current?.clientHeight ?? 0 });\n const baseSize = (): Size => {\n const imgs = zoomEl()?.querySelectorAll(\"img\");\n const img = Array.from(imgs ?? []).find((el) => el.naturalWidth > 0);\n return img ? containSize({ width: img.naturalWidth, height: img.naturalHeight }, stageSize()) : stageSize();\n };\n const toStagePoint = (clientX: number, clientY: number) => {\n const r = stageRef.current?.getBoundingClientRect();\n if (!r) return { x: 0, y: 0 };\n return { x: clientX - r.left - r.width / 2, y: clientY - r.top - r.height / 2 };\n };\n\n const applyView = useCallback((next: ViewState, ms = 0) => {\n view.current = next;\n setStyle(zoomEl(), viewTransform(next), ms);\n setZoomLevel(zoomLevelOf(next.scale));\n }, []);\n\n const setTrack = (dx: number, ms = 0) => setStyle(trackRef.current, `translate3d(${dx}px, 0, 0)`, ms);\n\n const setDismiss = (dx: number, dy: number, ms = 0) => {\n const p = dismissProgress(dy, stageSize().height);\n setStyle(zoomEl(), `translate3d(${dx}px, ${Math.max(dy, 0)}px, 0) scale(${1 - p * 0.3})`, ms);\n const backdrop = backdropRef.current;\n if (backdrop) {\n backdrop.style.transition = ms > 0 ? `opacity ${ms}ms ${EASE}` : \"none\";\n backdrop.style.opacity = String(1 - p);\n }\n };\n\n const go = useCallback(\n (dir: -1 | 1) => {\n const next = indexRef.current + dir;\n if (busy.current) return;\n if (next < 0 || next >= count) {\n setTrack(0, SETTLE_MS);\n return;\n }\n busy.current = true;\n const width = stageSize().width;\n setTrack(reducedMotion() ? 0 : -dir * (width + SLIDE_GAP), reducedMotion() ? 0 : SETTLE_MS);\n clearTimeout(goTimer.current);\n goTimer.current = setTimeout(() => {\n busy.current = false;\n setIndex(next);\n }, reducedMotion() ? 0 : SETTLE_MS);\n },\n [count, setIndex]\n );\n\n // Öğe değişince: şerit ve yakınlaştırma sıfır, komşu dilimlerdeki eski dönüşümler temizlenir, videolar durur.\n useLayoutEffect(() => {\n if (!present) return;\n setTrack(0);\n trackRef.current?.querySelectorAll<HTMLElement>(\"[data-viewer-zoom]\").forEach((el) => setStyle(el, \"\", 0));\n view.current = IDENTITY;\n setZoomLevel(\"min\");\n trackRef.current?.querySelectorAll(\"video\").forEach((v) => {\n if (!v.paused && !v.closest(\"[data-viewer-active]\")) v.pause();\n });\n }, [index, present]);\n\n // Alt şeritte geçerli öğe ortada.\n useEffect(() => {\n const strip = stripRef.current;\n const btn = strip?.querySelector<HTMLElement>('[aria-current=\"true\"]');\n if (!strip || !btn) return;\n strip.scrollTo?.({ left: btn.offsetLeft - strip.clientWidth / 2 + btn.offsetWidth / 2, behavior: reducedMotion() ? \"auto\" : \"smooth\" });\n }, [index, present, showStrip]);\n\n // Açılış: küçük resimden büyüyerek (FLIP), yoksa solarak.\n useLayoutEffect(() => {\n if (!open) return;\n setChrome(true);\n const zoom = zoomEl();\n const backdrop = backdropRef.current;\n const origin = getOriginElement?.(indexRef.current);\n const originImg = origin?.querySelector(\"img\");\n if (backdrop) {\n backdrop.style.transition = \"none\";\n backdrop.style.opacity = \"0\";\n }\n if (zoom && origin && !reducedMotion()) {\n const from = (originImg ?? origin).getBoundingClientRect();\n const stage = stageRef.current?.getBoundingClientRect();\n const fit =\n originImg && originImg.naturalWidth > 0\n ? containSize({ width: originImg.naturalWidth, height: originImg.naturalHeight }, stageSize())\n : stageSize();\n if (stage) {\n const t = originTransform(from, {\n left: stage.left + (stage.width - fit.width) / 2,\n top: stage.top + (stage.height - fit.height) / 2,\n width: fit.width,\n height: fit.height,\n });\n setStyle(zoom, `translate3d(${t.x}px, ${t.y}px, 0) scale(${t.scale})`, 0);\n }\n } else if (zoom) {\n zoom.style.opacity = \"0\";\n }\n forceReflow(zoom);\n const ms = reducedMotion() ? 0 : ENTER_MS;\n setStyle(zoom, viewTransform(IDENTITY), ms);\n if (zoom) zoom.style.opacity = \"1\";\n if (backdrop) {\n backdrop.style.transition = `opacity ${ms}ms ${EASE}`;\n backdrop.style.opacity = \"1\";\n }\n // Açılışta bir kez; `getOriginElement` her render'da yeni olabilir.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n\n // Kapanış: geçerli öğenin küçük resmine küçülerek; odak ona döner.\n const wasOpen = useRef(open);\n useEffect(() => {\n const closing = wasOpen.current && !open;\n wasOpen.current = open;\n if (!closing) return;\n clearTimeout(tapTimer.current);\n gesture.current = null;\n pointers.current.clear();\n const origin = getOriginElement?.(indexRef.current);\n const zoom = zoomEl();\n const ms = reducedMotion() ? 0 : EXIT_MS;\n const rect = origin?.getBoundingClientRect();\n const onScreen = rect && rect.bottom > 0 && rect.top < window.innerHeight && rect.width > 0;\n const zoomRect = zoom?.getBoundingClientRect();\n if (zoom && rect && onScreen && zoomRect && !reducedMotion()) {\n const base = baseSize();\n const current = view.current.scale > MIN_SCALE ? IDENTITY : view.current;\n const target = {\n left: zoomRect.left + (zoomRect.width - base.width) / 2,\n top: zoomRect.top + (zoomRect.height - base.height) / 2,\n width: base.width,\n height: base.height,\n };\n const t = originTransform(rect, target);\n setStyle(zoom, viewTransform(current), 0);\n forceReflow(zoom);\n setStyle(zoom, `translate3d(${t.x}px, ${t.y}px, 0) scale(${t.scale})`, ms);\n } else if (zoom) {\n zoom.style.transition = `opacity ${ms}ms ${EASE}`;\n zoom.style.opacity = \"0\";\n }\n const backdrop = backdropRef.current;\n if (backdrop) {\n backdrop.style.transition = `opacity ${ms}ms ${EASE}`;\n backdrop.style.opacity = \"0\";\n }\n setChrome(false);\n // Modal davranışı odağı açılıştan önceki öğeye döndürdü; geçerli öğenin küçük resmi daha doğru hedef.\n origin?.focus({ preventScroll: true });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n\n useEffect(\n () => () => {\n clearTimeout(tapTimer.current);\n clearTimeout(goTimer.current);\n },\n []\n );\n\n // Tekerlek / izleme dörtgeni sıkıştırması: imleç çevresinde yakınlaştır.\n useEffect(() => {\n const stage = stageRef.current;\n if (!present || !stage) return;\n const onWheel = (event: WheelEvent) => {\n if (isVideo) return;\n event.preventDefault();\n const factor = Math.exp(-event.deltaY * (event.ctrlKey ? 0.01 : 0.002));\n applyView(zoomAround(view.current, view.current.scale * factor, toStagePoint(event.clientX, event.clientY), baseSize(), stageSize()));\n };\n stage.addEventListener(\"wheel\", onWheel, { passive: false });\n return () => stage.removeEventListener(\"wheel\", onWheel);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [present, isVideo, applyView]);\n\n const handleTap = (event: React.PointerEvent) => {\n const now = event.timeStamp;\n const prev = lastTap.current;\n if (prev && now - prev.t < DOUBLE_TAP_MS && Math.hypot(event.clientX - prev.x, event.clientY - prev.y) < 30) {\n lastTap.current = null;\n clearTimeout(tapTimer.current);\n if (!isVideo) applyView(toggleZoom(view.current, toStagePoint(event.clientX, event.clientY), baseSize(), stageSize()), SETTLE_MS);\n return;\n }\n lastTap.current = { t: now, x: event.clientX, y: event.clientY };\n // Dokunmatikte tek dokunuş araç çubuklarını gizler/gösterir (çift dokunuştan ayırmak için bekler).\n if (event.pointerType !== \"mouse\") {\n clearTimeout(tapTimer.current);\n tapTimer.current = setTimeout(() => setChrome((c) => !c), DOUBLE_TAP_MS);\n }\n };\n\n const startSingle = (x: number, y: number, t: number, pointerType: string): Gesture => ({\n kind: view.current.scale > MIN_SCALE ? \"pan\" : \"pending\",\n startX: x,\n startY: y,\n lastX: x,\n lastY: y,\n lastT: t,\n vx: 0,\n vy: 0,\n dx: 0,\n dy: 0,\n startView: view.current,\n startDist: 0,\n startMid: { x: 0, y: 0 },\n pointerType,\n });\n\n const onPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (busy.current || !open) return;\n if (event.pointerType === \"mouse\" && event.button !== 0) return;\n // Fareyle videonun kendi denetimleri çalışsın.\n if (event.pointerType === \"mouse\" && (event.target as HTMLElement).closest(\"video\")) return;\n pointers.current.set(event.pointerId, { x: event.clientX, y: event.clientY });\n if (pointers.current.size === 2 && !isVideo) {\n const [a, b] = Array.from(pointers.current.values()) as [{ x: number; y: number }, { x: number; y: number }];\n gesture.current = {\n ...startSingle(event.clientX, event.clientY, event.timeStamp, event.pointerType),\n kind: \"pinch\",\n startView: view.current,\n startDist: Math.hypot(a.x - b.x, a.y - b.y) || 1,\n startMid: toStagePoint((a.x + b.x) / 2, (a.y + b.y) / 2),\n };\n setTrack(0, SETTLE_MS);\n return;\n }\n if (pointers.current.size === 1) gesture.current = startSingle(event.clientX, event.clientY, event.timeStamp, event.pointerType);\n };\n\n const movePinch = (g: Gesture) => {\n const pts = Array.from(pointers.current.values());\n if (pts.length < 2) return;\n const [a, b] = pts as [{ x: number; y: number }, { x: number; y: number }];\n const mid = toStagePoint((a.x + b.x) / 2, (a.y + b.y) / 2);\n const scale = g.startView.scale * (Math.hypot(a.x - b.x, a.y - b.y) / g.startDist);\n const z = zoomAround(g.startView, Math.max(scale, MIN_SCALE), g.startMid, baseSize(), stageSize());\n applyView({ scale: z.scale, x: z.x + mid.x - g.startMid.x, y: z.y + mid.y - g.startMid.y });\n };\n\n const trackDrag = (g: Gesture, event: React.PointerEvent) => {\n const dt = event.timeStamp - g.lastT;\n if (dt > 0) {\n g.vx = (event.clientX - g.lastX) / dt;\n g.vy = (event.clientY - g.lastY) / dt;\n }\n g.lastX = event.clientX;\n g.lastY = event.clientY;\n g.lastT = event.timeStamp;\n g.dx = event.clientX - g.startX;\n g.dy = event.clientY - g.startY;\n };\n\n const onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const g = gesture.current;\n if (!g || !pointers.current.has(event.pointerId)) return;\n pointers.current.set(event.pointerId, { x: event.clientX, y: event.clientY });\n if (g.kind === \"pinch\") {\n movePinch(g);\n return;\n }\n trackDrag(g, event);\n\n if (g.kind === \"pending\") {\n const intent = dragIntent(g.dx, g.dy);\n if (!intent) return;\n g.kind = intent;\n try {\n stageRef.current?.setPointerCapture(event.pointerId);\n } catch {\n /* sentetik olaylarda pointer yakalanamayabilir */\n }\n }\n if (g.kind === \"swipe\") {\n const atEdge = (indexRef.current === 0 && g.dx > 0) || (indexRef.current === count - 1 && g.dx < 0);\n setTrack(atEdge ? g.dx * 0.35 : g.dx);\n } else if (g.kind === \"dismiss\") {\n setDismiss(g.dx, g.dy);\n } else if (g.kind === \"pan\") {\n applyView({ scale: g.startView.scale, x: g.startView.x + g.dx, y: g.startView.y + g.dy });\n }\n };\n\n const endPinch = (g: Gesture, timeStamp: number) => {\n const rest = Array.from(pointers.current.values())[0];\n if (rest) {\n // Bir parmak kaldı: kaydırmaya geç.\n gesture.current = { ...startSingle(rest.x, rest.y, timeStamp, g.pointerType), kind: \"pan\" };\n return;\n }\n gesture.current = null;\n const v = view.current;\n applyView(v.scale < 1.05 ? IDENTITY : clampPan(v, baseSize(), stageSize()), SETTLE_MS);\n };\n\n const endSwipe = (g: Gesture, stage: Size) => {\n const dir = swipeOutcome(g.dx, g.vx, stage.width);\n const target = indexRef.current + dir;\n if (dir !== 0 && target >= 0 && target < count) go(dir);\n else setTrack(0, SETTLE_MS);\n };\n\n const endDismiss = (g: Gesture, stage: Size) => {\n if (shouldDismiss(g.dy, g.vy, stage.height)) onClose();\n else setDismiss(0, 0, SETTLE_MS);\n };\n\n const onPointerEnd = (event: React.PointerEvent<HTMLDivElement>) => {\n const g = gesture.current;\n if (!pointers.current.delete(event.pointerId) || !g) return;\n if (g.kind === \"pinch\") {\n endPinch(g, event.timeStamp);\n return;\n }\n if (pointers.current.size > 0) return;\n gesture.current = null;\n const stage = stageSize();\n if (g.kind === \"pending\" && event.type === \"pointerup\") handleTap(event);\n else if (g.kind === \"swipe\") endSwipe(g, stage);\n else if (g.kind === \"dismiss\") endDismiss(g, stage);\n else if (g.kind === \"pan\") applyView(clampPan(view.current, baseSize(), stage), SETTLE_MS);\n };\n\n const zoomBy = (factor: number) => applyView(zoomAround(view.current, view.current.scale * factor, { x: 0, y: 0 }, baseSize(), stageSize()), SETTLE_MS);\n\n const onKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n if (target.closest(\"video, input, textarea, select\")) return;\n const keys: Record<string, () => void> = {\n ArrowLeft: () => go(-1),\n ArrowRight: () => go(1),\n \"+\": () => zoomBy(ZOOM_STEP),\n \"=\": () => zoomBy(ZOOM_STEP),\n \"-\": () => zoomBy(1 / ZOOM_STEP),\n \"0\": () => applyView(IDENTITY, SETTLE_MS),\n };\n const action = keys[event.key];\n if (!action || (isVideo && event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\")) return;\n event.preventDefault();\n action();\n };\n\n const keyHandler = useRef(onKeyDown);\n keyHandler.current = onKeyDown;\n useEffect(() => {\n const panel = panelRef.current;\n if (!present || !panel) return;\n const listener = (event: KeyboardEvent) => keyHandler.current(event);\n panel.addEventListener(\"keydown\", listener);\n return () => panel.removeEventListener(\"keydown\", listener);\n }, [present]);\n\n if (!present || typeof document === \"undefined\" || !item) return null;\n\n const chromeClass = cn(\n \"absolute inset-x-0 z-10 bg-mari-surface/80 backdrop-blur-md transition-opacity duration-200 motion-reduce:transition-none\",\n chrome && open ? \"opacity-100\" : \"pointer-events-none opacity-0\"\n );\n\n return createPortal(\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={ariaLabel}\n tabIndex={-1}\n onFocus={() => setChrome(true)}\n className={cn(\"fixed inset-0 z-mari-modal text-mari-foreground outline-none\", !open && \"pointer-events-none\")}\n >\n <div ref={backdropRef} className=\"absolute inset-0 bg-mari-surface\" />\n\n <div\n ref={stageRef}\n data-viewer-stage=\"\"\n className={cn(\"absolute inset-0 touch-none overflow-hidden select-none\", zoomed ? \"cursor-grab active:cursor-grabbing\" : \"cursor-zoom-in\", isVideo && \"cursor-auto\")}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerEnd}\n onPointerCancel={onPointerEnd}\n >\n <div ref={trackRef} className=\"absolute inset-0\">\n {visibleSlides(index, count).map((i) => (\n <ViewerSlide key={items[i]!.key} item={items[i]!} offset={i - index} loader={loader} />\n ))}\n </div>\n </div>\n\n <div className={cn(chromeClass, \"top-0 flex items-center gap-1 px-2 pt-[max(0.5rem,env(safe-area-inset-top))] pb-2\")}>\n <Button data-viewer-close variant=\"ghost\" color=\"neutral\" shape=\"circle\" icon={<XIcon />} aria-label=\"Kapat\" onClick={onClose} />\n <p className=\"min-w-0 flex-1 truncate text-center text-sm font-medium tabular-nums\">\n {count > 1 ? `${index + 1} / ${count}` : item.alt}\n </p>\n {actions?.(item, index)}\n {!isVideo && (\n <>\n <Button\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n icon={<ZoomOutIcon />}\n aria-label=\"Uzaklaştır\"\n disabled={zoomLevel === \"min\"}\n onClick={() => zoomBy(1 / ZOOM_STEP)}\n className=\"pointer-coarse:hidden\"\n />\n <Button\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n icon={<ZoomInIcon />}\n aria-label=\"Yakınlaştır\"\n disabled={zoomLevel === \"max\"}\n onClick={() => zoomBy(ZOOM_STEP)}\n className=\"pointer-coarse:hidden\"\n />\n </>\n )}\n </div>\n\n {count > 1 && (\n <>\n {index > 0 && (\n <Button\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n size=\"lg\"\n icon={<ChevronLeftIcon />}\n aria-label=\"Önceki\"\n onClick={() => go(-1)}\n className={cn(chromeClass, \"inset-x-auto top-1/2 left-3 hidden -translate-y-1/2 sm:inline-flex pointer-coarse:hidden\")}\n />\n )}\n {index < count - 1 && (\n <Button\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n size=\"lg\"\n icon={<ChevronRightIcon />}\n aria-label=\"Sonraki\"\n onClick={() => go(1)}\n className={cn(chromeClass, \"inset-x-auto top-1/2 right-3 hidden -translate-y-1/2 sm:inline-flex pointer-coarse:hidden\")}\n />\n )}\n </>\n )}\n\n {(item.caption || showStrip) && (\n <div className={cn(chromeClass, \"bottom-0 flex flex-col gap-2 pt-2 pb-[max(0.5rem,env(safe-area-inset-bottom))]\")}>\n {item.caption && <div className=\"px-4 text-center text-sm\">{item.caption}</div>}\n {showStrip && (\n <div ref={stripRef} role=\"group\" aria-label=\"Küçük resimler\" className=\"flex items-center gap-0.5 overflow-x-auto px-[50%] [scrollbar-width:none]\">\n {items.map((it, i) => {\n const current = i === index;\n const src = viewerThumbnail(it, loader, 96);\n return (\n <button\n key={it.key}\n type=\"button\"\n aria-label={it.alt || `Öğe ${i + 1}`}\n aria-current={current ? \"true\" : undefined}\n onClick={() => setIndex(i)}\n className={cn(\n \"relative h-11 shrink-0 overflow-hidden bg-mari-surface-alt transition-[width,margin] duration-200 motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-mari-ring\",\n current ? \"mx-1.5 w-11 rounded-sm\" : \"w-7\"\n )}\n >\n {src && <img src={src} alt=\"\" draggable={false} loading=\"lazy\" className=\"size-full object-cover\" />}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n\n <p className=\"sr-only\" aria-live=\"polite\">\n {count > 1 ? `${item.alt}, ${index + 1} / ${count}` : item.alt}\n </p>\n </div>,\n document.body\n );\n}\n","import type React from \"react\";\nimport type { ImageLoader, ImageSource, ImageStaticSource } from \"./types\";\n\n/** `srcSet` için varsayılan aday genişlikler (yaygın cihaz genişlikleri). */\nexport const DEFAULT_WIDTHS = [384, 640, 828, 1080, 1280, 1920, 2560];\n/** Bulanık ön izleme için `loader`dan istenen küçük boy. */\nexport const BLUR_WIDTH = 24;\n\nexport function normalizeSource(src: ImageSource | null | undefined): ImageStaticSource | null {\n if (src == null) return null;\n if (typeof src === \"string\") return src === \"\" ? null : { src };\n return src.src ? src : null;\n}\n\nexport interface ResolvedImage {\n src: string;\n srcSet?: string;\n}\n\n/**\n * Asıl `<img>` adresleri.\n * - `loader` yoksa: kaynak olduğu gibi, `srcSet` yok.\n * - Sayısal `width` varsa: 1x/2x yoğunluk adayları (sabit boyutlu görsel).\n * - Yoksa: `widths` genişlik adayları (`sizes` ile duyarlı görsel).\n */\nexport function resolveImage(\n source: ImageStaticSource,\n { loader, width, widths = DEFAULT_WIDTHS, quality }: { loader?: ImageLoader; width?: number | string; widths?: number[]; quality?: number }\n): ResolvedImage {\n if (!loader) return { src: source.src };\n const call = (w: number) => loader({ src: source.src, width: w, quality });\n if (typeof width === \"number\") {\n return { src: call(width), srcSet: `${call(width)} 1x, ${call(width * 2)} 2x` };\n }\n const sorted = [...new Set(widths)].sort((a, b) => a - b);\n const largest = sorted[sorted.length - 1] ?? 1080;\n return { src: call(largest), srcSet: sorted.map((w) => `${call(w)} ${w}w`).join(\", \") };\n}\n\n/** `placeholder` → bulanık ön izleme URL'si (yoksa `null`: parıltı ya da özel node). */\nexport function resolveBlurSource(\n placeholder: unknown,\n source: ImageStaticSource,\n loader: ImageLoader | undefined\n): string | null {\n if (typeof placeholder === \"string\") return placeholder;\n if (placeholder !== true) return null;\n if (source.blurDataURL) return source.blurDataURL;\n if (loader) return loader({ src: source.src, width: BLUR_WIDTH, quality: 30 });\n return null;\n}\n\nfunction toCssLength(value: number | string | undefined): string | undefined {\n if (value === undefined) return undefined;\n return typeof value === \"number\" ? `${value}px` : value;\n}\n\nfunction toAspectRatio(value: number | string | undefined): string | undefined {\n if (value === undefined) return undefined;\n return String(value);\n}\n\n/**\n * Dış kutunun boyutu. Öncelik: açık `aspectRatio` → sayısal `width`/`height` oranı\n * → statik kaynağın kendi boyutu. Oran varsa ve yalnız biri verilmişse diğeri\n * orandan gelir; hiç boyut yoksa kutu kabın genişliğini alır.\n */\nexport function getBoxStyle({\n width,\n height,\n aspectRatio,\n source,\n}: {\n width?: number | string;\n height?: number | string;\n aspectRatio?: number | string;\n source?: ImageStaticSource | null;\n}): React.CSSProperties {\n let ratio = toAspectRatio(aspectRatio);\n if (!ratio && typeof width === \"number\" && typeof height === \"number\") ratio = `${width} / ${height}`;\n if (!ratio && width === undefined && height === undefined && source?.width && source.height) {\n ratio = `${source.width} / ${source.height}`;\n }\n const style: React.CSSProperties = {};\n const w = toCssLength(width);\n const h = toCssLength(height);\n if (w) style.width = w;\n if (h && !(ratio && w)) style.height = h;\n if (ratio) {\n style.aspectRatio = ratio;\n if (!w && !h) style.width = \"100%\";\n }\n return style;\n}\n\n/** `<img>`ye gidecek boyut/öncelik öznitelikleri (tarayıcı oranı önceden bilsin, LCP görseli öne alınsın). */\nexport function imgAttributes({\n width,\n height,\n source,\n srcSet,\n sizes,\n priority,\n loading,\n fetchPriority,\n}: {\n width?: number | string;\n height?: number | string;\n source: ImageStaticSource | null;\n srcSet?: string;\n sizes?: string;\n priority: boolean;\n loading: \"lazy\" | \"eager\";\n fetchPriority?: \"high\" | \"low\" | \"auto\";\n}) {\n const fixedWidth = typeof width === \"number\";\n const lazy = loading === \"lazy\" && !priority;\n // `auto`: lazy görselde tarayıcı gerçek kutu genişliğine göre seçer (desteklemeyen 100vw'ye düşer).\n const defaultSizes = lazy ? \"auto, 100vw\" : \"100vw\";\n return {\n width: fixedWidth ? width : source?.width,\n height: typeof height === \"number\" ? height : source?.height,\n sizes: sizes ?? (srcSet && !fixedWidth ? defaultSizes : undefined),\n loading: lazy ? loading : (\"eager\" as const),\n fetchPriority: priority ? (\"high\" as const) : fetchPriority,\n };\n}\n","/**\n * Görüntüleyicinin (ImageViewer) saf jest/geometri mantığı — DOM'suz, ayrıca test edilir.\n * Koordinatlar sahnenin (stage) MERKEZİNE göredir; görsel ölçek 1'de sahneye\n * `contain` ile sığdırılmış boyuttadır (`base`).\n */\n\nexport const MIN_SCALE = 1;\nexport const MAX_SCALE = 4;\n/** Çift dokunuş / çift tıklama yakınlaştırması. */\nexport const DOUBLE_TAP_SCALE = 2.5;\n\nexport interface ViewState {\n scale: number;\n x: number;\n y: number;\n}\n\nexport interface Size {\n width: number;\n height: number;\n}\n\nexport const IDENTITY: ViewState = { scale: 1, x: 0, y: 0 };\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\n/** Görsel sahneden büyükse taşan kadar kaydırılabilir; küçükse ortada kalır. */\nexport function clampPan(view: ViewState, base: Size, stage: Size): ViewState {\n const maxX = Math.max(0, (base.width * view.scale - stage.width) / 2);\n const maxY = Math.max(0, (base.height * view.scale - stage.height) / 2);\n // `|| 0`: -0 yerine 0 (sınır 0 iken Math.max(-0, negatif) = -0).\n return { scale: view.scale, x: clamp(view.x, -maxX, maxX) || 0, y: clamp(view.y, -maxY, maxY) || 0 };\n}\n\n/**\n * `point` (sahne merkezine göre) sabit kalacak şekilde yeni ölçeğe geç —\n * imlecin/parmakların altındaki nokta yerinden oynamaz.\n */\nexport function zoomAround(view: ViewState, nextScale: number, point: { x: number; y: number }, base: Size, stage: Size): ViewState {\n const scale = clamp(nextScale, MIN_SCALE, MAX_SCALE);\n const ratio = scale / view.scale;\n const next = { scale, x: point.x - (point.x - view.x) * ratio, y: point.y - (point.y - view.y) * ratio };\n return scale === MIN_SCALE ? IDENTITY : clampPan(next, base, stage);\n}\n\n/** Çift dokunuş: yakın değilse noktaya yakınlaş, yakınsa sıfırla. */\nexport function toggleZoom(view: ViewState, point: { x: number; y: number }, base: Size, stage: Size): ViewState {\n return view.scale > MIN_SCALE ? IDENTITY : zoomAround(view, DOUBLE_TAP_SCALE, point, base, stage);\n}\n\n/** Sürükleme bırakılınca: -1 önceki, 1 sonraki, 0 yerine dön. Hız px/ms. */\nexport function swipeOutcome(dx: number, velocityX: number, stageWidth: number): -1 | 0 | 1 {\n const far = Math.abs(dx) > stageWidth * 0.25;\n const fast = Math.abs(velocityX) > 0.5 && Math.abs(dx) > 20;\n if (!far && !fast) return 0;\n return dx < 0 ? 1 : -1;\n}\n\n/** Aşağı çekerek kapatma: 0..1 ilerleme (arka plan saydamlaşır, görsel küçülür). */\nexport function dismissProgress(dy: number, stageHeight: number): number {\n return clamp(dy / (stageHeight * 0.5), 0, 1);\n}\n\nexport function shouldDismiss(dy: number, velocityY: number, stageHeight: number): boolean {\n return dy > stageHeight * 0.18 || (velocityY > 0.5 && dy > 30);\n}\n\n/**\n * İlk sürükleme yönü: yatay → kaydırma, aşağı → kapatma, belirsiz → bekle.\n * Yakınken her yön kaydırmadır (pan).\n */\nexport function dragIntent(dx: number, dy: number): \"swipe\" | \"dismiss\" | null {\n if (Math.hypot(dx, dy) < 8) return null;\n if (Math.abs(dx) > Math.abs(dy)) return \"swipe\";\n return dy > 0 ? \"dismiss\" : \"swipe\";\n}\n\nexport interface RectLike {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/**\n * Küçük resimden büyüyerek açılış (FLIP): hedef kutudaki görseli, kaynak\n * kutunun yerine ve boyutuna götüren dönüşüm. Küçük resim kare kırpılmış\n * olabilir — ölçek, kaynağı KAPLAYACAK (cover) şekilde seçilir.\n */\nexport function originTransform(from: RectLike, to: RectLike): { x: number; y: number; scale: number } {\n if (to.width === 0 || to.height === 0) return { x: 0, y: 0, scale: 1 };\n const scale = Math.max(from.width / to.width, from.height / to.height);\n return {\n x: from.left + from.width / 2 - (to.left + to.width / 2),\n y: from.top + from.height / 2 - (to.top + to.height / 2),\n scale,\n };\n}\n\n/** Görüntülenecek komşu dilimler (önceki, şimdiki, sonraki). */\nexport function visibleSlides(index: number, count: number): number[] {\n return [index - 1, index, index + 1].filter((i) => i >= 0 && i < count);\n}\n\n/** Doğal boyuttaki görselin sahneye `contain` ile sığmış boyutu (büyütmeden). */\nexport function containSize(natural: Size, stage: Size, upscale = true): Size {\n if (natural.width === 0 || natural.height === 0) return stage;\n let ratio = Math.min(stage.width / natural.width, stage.height / natural.height);\n if (!upscale) ratio = Math.min(1, ratio);\n return { width: natural.width * ratio, height: natural.height * ratio };\n}\n","\"use client\";\n\nimport React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { CheckIcon, PlayIcon, ZoomInIcon, ZoomOutIcon } from \"lucide-react\";\nimport { cn, useControllableState } from \"@mari-ui/core\";\nimport { Button } from \"../button\";\nimport { Segmented } from \"../segmented\";\nimport { InfiniteScrollFooter, type InfiniteScrollOptions } from \"../lib/infiniteScroll\";\nimport { skeletonBoxProps, type SkeletonableProps } from \"../lib/skeleton\";\nimport { Image } from \"./Image\";\nimport { ImageViewer, type ImageViewerItem, type ImageViewerProps } from \"./ImageViewer\";\nimport type { ImageLoader, ImageSource } from \"./types\";\nimport {\n DRILL_DOWN,\n drillDownTarget,\n MAX_COLUMNS,\n MIN_COLUMNS,\n autoColumns,\n buildLayout,\n clampColumns,\n formatDuration,\n gridKeyIntent,\n groupItems,\n rangeIndexes,\n renderedRows,\n sectionLabel,\n visibleRows,\n type GalleryLayout,\n type GalleryView,\n} from \"./galleryUtils\";\n\nexport type { GalleryView };\n\nexport interface ImageGalleryItem {\n key: React.Key;\n /** Tam çözünürlüklü kaynak (video için video adresi). */\n src: ImageSource;\n alt: string;\n /** Çekim tarihi — bölümler buna göre. Hiçbir öğede yoksa galeri tek düz ızgaradır. */\n date?: Date | null;\n /** Varsayılan: `\"image\"`. */\n type?: \"image\" | \"video\";\n /** Video kapak görseli (ızgarada ve görüntüleyicide) — hazır adres, `loader`dan geçmez. */\n poster?: string;\n /** Video süresi (sn) — küçük resmin köşesinde. */\n duration?: number;\n /** Izgarada `src` yerine gösterilecek küçük kaynak (CDN `loader`ı yoksa önerilir). */\n thumbnail?: ImageSource;\n caption?: React.ReactNode;\n tracks?: Exclude<ImageViewerItem[\"tracks\"], undefined>;\n}\n\nexport interface ImageGalleryProps extends SkeletonableProps {\n items: ImageGalleryItem[];\n /** Bölümleme: `day` / `month` / `year` başlıklı, `all` başlıksız tek ızgara. Varsayılan: `\"day\"`. */\n view?: GalleryView;\n defaultView?: GalleryView;\n onViewChange?: (view: GalleryView) => void;\n /** Araç çubuğundaki görünüm seçenekleri (sırasıyla). Varsayılan: Yıllar, Aylar, Günler, Tümü. */\n views?: GalleryView[];\n /** Sütun sayısı. `\"auto\"`: genişlik ve görünüme göre (gün iri, yıl sık). Varsayılan: `\"auto\"`. */\n columns?: number | \"auto\";\n defaultColumns?: number | \"auto\";\n onColumnsChange?: (columns: number | \"auto\") => void;\n /** Küçük resimler arası boşluk (px, kıl payı). Varsayılan: `2`. */\n gap?: number;\n loader?: ImageLoader;\n /** Araç çubuğu (görünüm, sütun, seçim). Varsayılan: `true`. */\n toolbar?: boolean;\n /** Araç çubuğunun solundaki başlık. */\n title?: React.ReactNode;\n /** Bölüm başlıklarının düzeyi. Varsayılan: `3`. */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** Sona yaklaşınca sonraki sayfayı ister (sanallaştırmayla birlikte çalışır). */\n infinite?: InfiniteScrollOptions;\n /** Araç çubuğunda \"Seç\" düğmesi; dokunmatikte uzun basış da seçim moduna alır. */\n selectable?: boolean;\n selectionMode?: boolean;\n defaultSelectionMode?: boolean;\n onSelectionModeChange?: (active: boolean) => void;\n selectedKeys?: React.Key[];\n defaultSelectedKeys?: React.Key[];\n onSelectionChange?: (keys: React.Key[]) => void;\n /** Seçim modunda araç çubuğuna eklenecek eylemler (paylaş, sil…). */\n selectionActions?: (keys: React.Key[]) => React.ReactNode;\n /** Görüntüleyicinin üst çubuğuna ek eylemler. */\n viewerActions?: Exclude<ImageViewerProps[\"actions\"], undefined>;\n /** Tarih biçimi. Varsayılan: `\"tr-TR\"`. */\n locale?: string;\n /** Öğe yokken. Varsayılan: \"Henüz fotoğraf yok\". */\n emptyText?: React.ReactNode;\n \"aria-label\"?: string;\n className?: string;\n}\n\nconst VIEW_LABEL: Record<GalleryView, string> = { year: \"Yıllar\", month: \"Aylar\", day: \"Günler\", all: \"Tümü\" };\nconst DEFAULT_VIEWS: GalleryView[] = [\"year\", \"month\", \"day\", \"all\"];\nconst TILE_WIDTHS = [96, 160, 256, 384, 640];\nconst HEADER_REM = 2.75;\nconst LONG_PRESS_MS = 500;\nconst SKELETON_ROWS = 4;\n\nconst useIsomorphicLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\nfunction scrollParent(el: HTMLElement): HTMLElement | null {\n for (let p = el.parentElement; p && p !== document.body; p = p.parentElement) {\n if (/(auto|scroll|overlay)/.test(getComputedStyle(p).overflowY)) return p;\n }\n return null;\n}\n\n/** Galerinin görünen dikey aralığı (galeriye göre px): kaydırma atası ve pencere ile kesişim. */\nfunction viewportOf(el: HTMLElement, scroller: HTMLElement | null): [number, number] {\n const rect = el.getBoundingClientRect();\n let top = 0;\n let bottom = window.innerHeight;\n if (scroller) {\n const s = scroller.getBoundingClientRect();\n top = Math.max(top, s.top);\n bottom = Math.min(bottom, s.bottom);\n }\n return [top - rect.top, bottom - rect.top];\n}\n\nfunction remToPx(rem: number): number {\n if (typeof window === \"undefined\") return rem * 16;\n return rem * (parseFloat(getComputedStyle(document.documentElement).fontSize) || 16);\n}\n\n/** Öğenin genişliği (ResizeObserver). `active` değişince (öğe DOM'a girince) yeniden bağlanır. */\nfunction useWidth(ref: React.RefObject<HTMLElement | null>, active: boolean): number {\n const [width, setWidth] = useState(0);\n useIsomorphicLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n setWidth(el.clientWidth);\n if (typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => setWidth(el.clientWidth));\n ro.observe(el);\n return () => ro.disconnect();\n }, [ref, active]);\n return width;\n}\n\n/**\n * Sanal ızgara: görünen aralık (sayfa ya da iç kaydırma alanı) kaydırma\n * olaylarıyla izlenir; yalnız görünen satırlar (+ birkaç yedek) render edilir.\n */\nfunction useVisibleRows(gridRef: React.RefObject<HTMLDivElement | null>, layout: GalleryLayout, active: boolean) {\n const [range, setRange] = useState<[number, number]>([0, 20]);\n const layoutRef = useRef(layout);\n layoutRef.current = layout;\n const viewportHeight = useRef(0);\n const update = useRef<() => void>(() => {});\n\n useIsomorphicLayoutEffect(() => {\n const el = gridRef.current;\n if (!el) return;\n const scroller = scrollParent(el);\n let frame = 0;\n update.current = () => {\n const [top, bottom] = viewportOf(el, scroller);\n viewportHeight.current = bottom - top;\n const next = visibleRows(layoutRef.current.rows, top, bottom);\n setRange((prev) => (prev[0] === next[0] && prev[1] === next[1] ? prev : next));\n };\n const onScroll = () => {\n if (frame) return;\n frame = requestAnimationFrame(() => {\n frame = 0;\n update.current();\n });\n };\n // Yakalama aşaması: hangi ata kaydırırsa kaydırsın haber alınır.\n window.addEventListener(\"scroll\", onScroll, { capture: true, passive: true });\n window.addEventListener(\"resize\", onScroll);\n return () => {\n cancelAnimationFrame(frame);\n update.current = () => {};\n window.removeEventListener(\"scroll\", onScroll, { capture: true });\n window.removeEventListener(\"resize\", onScroll);\n };\n }, [gridRef, active]);\n\n // Yerleşim değişince (genişlik, sütun, görünüm, yeni sayfa) aralığı yeniden hesapla.\n useIsomorphicLayoutEffect(() => update.current(), [layout, active]);\n\n return { range, viewportHeight };\n}\n\nfunction GalleryTile({\n item,\n index,\n active,\n selecting,\n selected,\n loader,\n cell,\n onActivate,\n onLongPress,\n onKeyDown,\n}: Readonly<{\n item: ImageGalleryItem;\n index: number;\n active: boolean;\n selecting: boolean;\n selected: boolean;\n loader?: ImageLoader;\n cell: number;\n onActivate: (index: number, event: React.MouseEvent | React.KeyboardEvent) => void;\n onLongPress: (index: number) => void;\n onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void;\n}>) {\n const press = useRef<{ timer: ReturnType<typeof setTimeout>; x: number; y: number; fired: boolean } | null>(null);\n const isVideo = item.type === \"video\";\n // Kapak görseli görüntüleyicideki gibi hazır bir adres: `loader`dan geçmez.\n const thumb = isVideo ? (item.poster ?? null) : (item.thumbnail ?? item.src);\n const thumbLoader = isVideo ? undefined : loader;\n\n const cancelPress = () => {\n const p = press.current;\n if (!p) return;\n clearTimeout(p.timer);\n // Uzun basış gerçekleştiyse bayrak, ardından gelen tıklamayı yutmak için kalır.\n if (!p.fired) press.current = null;\n };\n useEffect(() => cancelPress, []);\n\n return (\n <div\n role=\"gridcell\"\n tabIndex={active ? 0 : -1}\n data-index={index}\n aria-selected={selecting ? selected : undefined}\n onKeyDown={onKeyDown}\n onClick={(event) => {\n // Uzun basış seçimi zaten yaptı; ardından gelen tıklama geri almasın.\n if (press.current?.fired) {\n press.current = null;\n return;\n }\n onActivate(index, event);\n }}\n onPointerDown={(event) => {\n if (event.pointerType !== \"touch\" || selecting) return;\n cancelPress();\n const { clientX: x, clientY: y } = event;\n const timer = setTimeout(() => {\n if (press.current) press.current.fired = true;\n onLongPress(index);\n }, LONG_PRESS_MS);\n press.current = { timer, x, y, fired: false };\n }}\n onPointerMove={(event) => {\n const p = press.current;\n if (p && !p.fired && Math.hypot(event.clientX - p.x, event.clientY - p.y) > 10) cancelPress();\n }}\n onPointerUp={cancelPress}\n onPointerCancel={cancelPress}\n onContextMenu={(event) => {\n // Uzun basışta tarayıcının \"görseli kaydet\" menüsü açılmasın.\n if (press.current) event.preventDefault();\n }}\n className={cn(\n \"relative block size-full cursor-pointer overflow-hidden bg-mari-surface-alt outline-none select-none [-webkit-touch-callout:none]\",\n // Halka görselin üstünde kalsın: inset gölge içeriğin altında boyanır → ::after katmanı.\n \"scroll-mt-14 after:pointer-events-none after:absolute after:inset-0 after:content-[''] focus-visible:after:ring-2 focus-visible:after:ring-mari-ring focus-visible:after:ring-inset\"\n )}\n >\n <Image\n src={thumb}\n alt={item.alt}\n loader={thumbLoader}\n widths={TILE_WIDTHS}\n sizes={`${Math.max(1, Math.ceil(cell))}px`}\n draggable={false}\n wrapperClassName={cn(\n \"block size-full rounded-none transition-[transform,opacity] duration-150 motion-reduce:transition-none\",\n selected && \"opacity-70\"\n )}\n />\n {isVideo && (\n // Fotoğrafa bağlı, temadan bağımsız (native VIDEO_BADGE_BG ile aynı): açık temanın\n // yarı saydam scrim'i açık karede beyaz metni AA'nın altına düşürüyordu.\n <span className=\"pointer-events-none absolute right-1 bottom-1 inline-flex items-center gap-0.5 rounded-sm bg-black/72 px-1 text-xs font-medium text-white tabular-nums\">\n <PlayIcon aria-hidden className=\"size-3 fill-current\" />\n {item.duration !== undefined ? formatDuration(item.duration) : <span className=\"sr-only\">Video</span>}\n {item.duration !== undefined && <span className=\"sr-only\">, video</span>}\n </span>\n )}\n {selecting && (\n <span\n aria-hidden\n className={cn(\n \"pointer-events-none absolute right-1.5 bottom-1.5 flex size-5 items-center justify-center rounded-full border-2 border-white\",\n selected ? \"bg-mari-primary-solid text-mari-primary-solid-contrast\" : \"bg-mari-scrim\",\n isVideo && \"bottom-6\"\n )}\n >\n {selected && <CheckIcon className=\"size-3\" strokeWidth={3} />}\n </span>\n )}\n </div>\n );\n}\n\n/**\n * Görünüm değişince (yıl → ay → gün) bir öğenin bölüm başlığını araç\n * çubuğunun hemen altına kaydırır. Yeni yerleşim hesaplandıktan sonra çalışır.\n */\nfunction useSectionScroll(\n gridRef: React.RefObject<HTMLDivElement | null>,\n toolbarRef: React.RefObject<HTMLDivElement | null>,\n layout: GalleryLayout,\n width: number\n) {\n const pending = useRef<number | null>(null);\n useIsomorphicLayoutEffect(() => {\n const el = gridRef.current;\n const index = pending.current;\n const row = index === null ? undefined : layout.rowOf[index];\n if (!el || !width || row === undefined) return;\n pending.current = null;\n const header = layout.rows[row - 1];\n const top = header?.kind === \"header\" ? header.top : layout.rows[row]!.top;\n const scroller = scrollParent(el);\n const [viewTop] = viewportOf(el, scroller);\n const delta = top - viewTop - (toolbarRef.current?.offsetHeight ?? 0);\n // jsdom'da `scrollBy` yok.\n (scroller ?? window).scrollBy?.({ top: delta });\n }, [layout, width]);\n return (index: number) => {\n pending.current = index;\n };\n}\n\n/** Seçim modu + seçili anahtarlar (kontrollü/kontrolsüz) ve Shift aralığının çapası. */\nfunction useGallerySelection(\n flat: readonly ImageGalleryItem[],\n opts: {\n value?: React.Key[];\n defaultValue: React.Key[];\n onChange?: (keys: React.Key[]) => void;\n mode?: boolean;\n defaultMode: boolean;\n onModeChange?: (active: boolean) => void;\n }\n) {\n const [selecting = false, setSelecting] = useControllableState({ value: opts.mode, defaultValue: opts.defaultMode, onChange: opts.onModeChange });\n const [keys = [], setKeysState] = useControllableState({ value: opts.value, defaultValue: opts.defaultValue, onChange: opts.onChange });\n // Render beklemeden art arda gelen güncellemeler (hızlı tıklama) birbirini ezmesin.\n const latest = useRef(keys);\n latest.current = keys;\n const setKeys = (next: React.Key[]) => {\n latest.current = next;\n setKeysState(next);\n };\n const set = useMemo(() => new Set(keys), [keys]);\n const anchor = useRef<number | null>(null);\n\n const addRange = (to: number) => {\n if (anchor.current === null) return;\n const added = rangeIndexes(anchor.current, to).map((i) => flat[i]!.key);\n setKeys([...new Set([...latest.current, ...added])]);\n };\n\n const exit = () => {\n setSelecting(false);\n if (keys.length) setKeys([]);\n anchor.current = null;\n };\n\n const selectAll = () => setKeys(flat.map((i) => i.key));\n\n return {\n selecting,\n keys,\n has: (key: React.Key) => set.has(key),\n enter: () => setSelecting(true),\n exit,\n selectAll,\n /** Tıklama/Space: tek öğeyi aç/kapa; Shift ile çapadan buraya kadar ekle. */\n toggle: (index: number, range: boolean) => {\n const key = flat[index]?.key;\n if (key === undefined) return;\n if (range && anchor.current !== null) {\n addRange(index);\n return;\n }\n const current = latest.current;\n setKeys(current.includes(key) ? current.filter((k) => k !== key) : [...current, key]);\n anchor.current = index;\n },\n /** Shift+ok: çapadan hedefe kadar ekle. */\n extendTo: addRange,\n /** Uzun basış: seçim moduna gir, bu öğeyi seç. */\n startWith: (index: number) => {\n setSelecting(true);\n anchor.current = index;\n const key = flat[index]!.key;\n if (!latest.current.includes(key)) setKeys([...latest.current, key]);\n },\n /** Escape çıkar, Ctrl/⌘+A tümünü seçer. İşlendiyse `true`. */\n shortcut: (event: React.KeyboardEvent) => {\n const all = event.key.toLowerCase() === \"a\" && (event.ctrlKey || event.metaKey);\n if (event.key !== \"Escape\" && !all) return false;\n event.preventDefault();\n if (all) selectAll();\n else exit();\n return true;\n },\n };\n}\n\n/**\n * Faz 16.7 — fotoğraf/video galerisi. Yapı iPhone Fotoğraflar'dan: kare\n * küçük resimler kıl payı aralıkla, tarihe göre bölümler ve Yıllar / Aylar /\n * Günler / Tümü görünümleri (üst görünümün başlığına tıklayınca bir alta\n * inilir), sütun sayısı değiştirilebilir, seçim modu (uzun basış, Shift ile\n * aralık), tam ekran `ImageViewer` (video dahil). Binlerce öğe için sanal:\n * yalnız görünen satırlar DOM'da; `infinite` ile sonraki sayfalar istenir.\n *\n * Erişilebilirlik: APG `grid` — tek sekme durağı, ok tuşları / Home / End /\n * PageUp / PageDown ile gezinme (sanallaştırmada da: hedef satır render edilip\n * odaklanır), `aria-rowcount`/`aria-rowindex`; seçim modunda\n * `aria-multiselectable` + `aria-selected`.\n */\nexport function ImageGallery({\n items,\n view: viewProp,\n defaultView = \"day\",\n onViewChange,\n views = DEFAULT_VIEWS,\n columns: columnsProp,\n defaultColumns = \"auto\",\n onColumnsChange,\n gap = 2,\n loader,\n toolbar = true,\n title,\n headingLevel = 3,\n infinite,\n selectable = false,\n selectionMode: selectionModeProp,\n defaultSelectionMode = false,\n onSelectionModeChange,\n selectedKeys: selectedKeysProp,\n defaultSelectedKeys = [],\n onSelectionChange,\n selectionActions,\n viewerActions,\n locale = \"tr-TR\",\n emptyText = \"Henüz fotoğraf yok\",\n skeleton = false,\n \"aria-label\": ariaLabel = \"Fotoğraflar\",\n className,\n}: Readonly<ImageGalleryProps>) {\n const [rawView, setViewState] = useControllableState({ value: viewProp, defaultValue: defaultView, onChange: onViewChange });\n const [columnsSetting = \"auto\", setColumns] = useControllableState<number | \"auto\">({\n value: columnsProp,\n defaultValue: defaultColumns,\n onChange: onColumnsChange,\n });\n const hasDates = useMemo(() => items.some((i) => i.date), [items]);\n const view: GalleryView = hasDates ? (rawView ?? \"day\") : \"all\";\n\n const sections = useMemo(() => groupItems(items, view, (i) => i.date), [items, view]);\n const flat = useMemo(() => sections.flatMap((s) => s.entries.map((e) => e.item)), [sections]);\n const count = flat.length;\n const sel = useGallerySelection(flat, {\n value: selectedKeysProp,\n defaultValue: defaultSelectedKeys,\n onChange: onSelectionChange,\n mode: selectionModeProp,\n defaultMode: defaultSelectionMode,\n onModeChange: onSelectionModeChange,\n });\n\n const gridRef = useRef<HTMLDivElement>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n const gridMounted = !skeleton && count > 0;\n const width = useWidth(gridRef, gridMounted);\n const columns = columnsSetting === \"auto\" ? autoColumns(width, view, gap) : clampColumns(columnsSetting);\n const headerHeight = view === \"all\" ? 0 : remToPx(HEADER_REM);\n const layout = useMemo(() => buildLayout(sections, { width, columns, gap, headerHeight }), [sections, width, columns, gap, headerHeight]);\n const virtual = useVisibleRows(gridRef, layout, gridMounted);\n\n const [rawActive, setActive] = useState(0);\n const activeIndex = Math.min(rawActive, Math.max(count - 1, 0));\n const pendingFocus = useRef(false);\n\n const [viewerOpen, setViewerOpen] = useState(false);\n const [viewerIndex, setViewerIndex] = useState(0);\n\n const setView = (next: GalleryView) => {\n setViewState(next);\n // Kendiliğinden sütun sayısı yeni görünüme göre; tüketici kontrol ediyorsa ona kalır.\n if (columnsProp === undefined) setColumns(\"auto\");\n };\n\n const cellOf = (index: number) => gridRef.current?.querySelector<HTMLElement>(`[data-index=\"${index}\"]`) ?? null;\n\n // Odak taşınacaksa: hedef satır bu render'da DOM'a girdi → odakla (tarayıcı görünüme kaydırır).\n useIsomorphicLayoutEffect(() => {\n if (!pendingFocus.current) return;\n pendingFocus.current = false;\n cellOf(activeIndex)?.focus();\n });\n\n const scrollToItemSection = useSectionScroll(gridRef, toolbarRef, layout, width);\n\n const drillDown = (sectionIndex: number) => {\n const target = drillDownTarget(items, sections, view, sectionIndex, (i) => i.date);\n if (!target) return;\n setView(target.view);\n scrollToItemSection(target.index);\n setActive(target.index);\n };\n\n const openViewer = (index: number) => {\n setViewerIndex(index);\n setViewerOpen(true);\n };\n\n const onActivate = (index: number, event: React.MouseEvent | React.KeyboardEvent) => {\n setActive(index);\n if (sel.selecting) sel.toggle(index, event.shiftKey);\n else openViewer(index);\n };\n\n const onLongPress = (index: number) => {\n if (!selectable) return;\n setActive(index);\n sel.startWith(index);\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget || (sel.selecting && sel.shortcut(event))) return;\n const index = Number(event.currentTarget.dataset.index);\n const pageRows = Math.floor(virtual.viewportHeight.current / (layout.cell + gap)) - 1;\n const intent = gridKeyIntent(layout, index, event.key, event.ctrlKey || event.metaKey, pageRows);\n if (intent === null) return;\n event.preventDefault();\n if (intent === \"activate\") {\n onActivate(index, event);\n return;\n }\n if (sel.selecting && event.shiftKey) sel.extendTo(intent);\n pendingFocus.current = true;\n setActive(intent);\n };\n\n const viewerItems = useMemo<ImageViewerItem[]>(\n () =>\n flat.map((i) => ({\n key: i.key,\n src: i.src,\n alt: i.alt,\n caption: i.caption,\n type: i.type,\n poster: i.poster,\n tracks: i.tracks,\n })),\n [flat]\n );\n\n // Görüntüleyicide gezinirken ızgara da izler (kapanınca küçük resme küçülerek dönebilsin).\n useEffect(() => {\n if (!viewerOpen) return;\n cellOf(viewerIndex)?.scrollIntoView?.({ block: \"nearest\" });\n }, [viewerOpen, viewerIndex]);\n\n // Görünür satırlar + odaktaki satır (uzakta olsa da DOM'da kalsın).\n const tileProps = { loader, cell: layout.cell, onActivate, onLongPress, onKeyDown };\n const rowIndexes = renderedRows(virtual.range, layout.rows.length, layout.rowOf[activeIndex]);\n\n if (skeleton) return <GallerySkeleton toolbar={toolbar} columns={columnsSetting} view={view} gap={gap} className={className} />;\n\n return (\n <div className={cn(\"relative\", className)}>\n {toolbar && (\n <GalleryToolbar\n ref={toolbarRef}\n title={title}\n selecting={sel.selecting}\n selectedKeys={sel.keys}\n selectionActions={selectionActions}\n empty={!count}\n selectable={selectable}\n onSelectAll={sel.selectAll}\n onExitSelection={sel.exit}\n onEnterSelection={sel.enter}\n view={view}\n views={hasDates ? views : []}\n onViewChange={setView}\n columns={columns}\n cell={layout.cell}\n onColumnsChange={setColumns}\n />\n )}\n\n {count === 0 ? (\n <div className=\"flex min-h-40 items-center justify-center text-sm text-mari-muted\">{emptyText}</div>\n ) : (\n <div\n ref={gridRef}\n role=\"grid\"\n aria-label={ariaLabel}\n aria-rowcount={layout.rows.length}\n aria-colcount={columns}\n aria-multiselectable={sel.selecting || undefined}\n className=\"relative w-full\"\n style={{ height: layout.height }}\n >\n {rowIndexes.map((r) => {\n const row = layout.rows[r]!;\n const style: React.CSSProperties = { position: \"absolute\", top: row.top, height: row.height, left: 0, right: 0 };\n if (row.kind === \"header\") {\n const section = sections[row.section]!;\n return (\n <SectionHeaderRow\n key={`h-${section.key}`}\n rowIndex={r}\n style={style}\n columns={columns}\n headingLevel={headingLevel}\n label={sectionLabel(section.date, view, locale)}\n count={section.entries.length}\n onDrillDown={DRILL_DOWN[view] ? () => drillDown(row.section) : undefined}\n />\n );\n }\n return (\n <ItemRow\n key={`r-${flat[row.start]!.key}`}\n rowIndex={r}\n style={style}\n columns={columns}\n gap={gap}\n items={flat.slice(row.start, row.end)}\n start={row.start}\n activeIndex={activeIndex}\n selecting={sel.selecting}\n isSelected={sel.has}\n tile={tileProps}\n />\n );\n })}\n </div>\n )}\n\n {infinite && count > 0 && <InfiniteScrollFooter options={infinite} className=\"mt-2\" />}\n\n <ImageViewer\n items={viewerItems}\n open={viewerOpen}\n onClose={() => setViewerOpen(false)}\n index={viewerIndex}\n onIndexChange={(i) => {\n setViewerIndex(i);\n setActive(i);\n }}\n loader={loader}\n actions={viewerActions}\n getOriginElement={cellOf}\n />\n </div>\n );\n}\n\ntype TileShared = Pick<React.ComponentProps<typeof GalleryTile>, \"loader\" | \"cell\" | \"onActivate\" | \"onLongPress\" | \"onKeyDown\">;\n\nfunction ItemRow({\n rowIndex,\n style,\n columns,\n gap,\n items,\n start,\n activeIndex,\n selecting,\n isSelected,\n tile,\n}: Readonly<{\n rowIndex: number;\n style: React.CSSProperties;\n columns: number;\n gap: number;\n items: ImageGalleryItem[];\n start: number;\n activeIndex: number;\n selecting: boolean;\n isSelected: (key: React.Key) => boolean;\n tile: TileShared;\n}>) {\n return (\n <div role=\"row\" aria-rowindex={rowIndex + 1} style={{ ...style, display: \"grid\", gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`, gap }}>\n {items.map((item, k) => (\n <GalleryTile\n key={item.key}\n {...tile}\n item={item}\n index={start + k}\n active={start + k === activeIndex}\n selecting={selecting}\n selected={isSelected(item.key)}\n />\n ))}\n </div>\n );\n}\n\nfunction SectionHeaderRow({\n rowIndex,\n style,\n columns,\n headingLevel,\n label,\n count,\n onDrillDown,\n}: Readonly<{\n rowIndex: number;\n style: React.CSSProperties;\n columns: number;\n headingLevel: number;\n label: string;\n count: number;\n onDrillDown?: () => void;\n}>) {\n const Heading = `h${headingLevel}` as \"h3\";\n return (\n <div role=\"row\" aria-rowindex={rowIndex + 1} style={style} className=\"flex items-end px-1 pb-1.5\">\n <div role=\"gridcell\" aria-colspan={columns} className=\"flex w-full items-baseline gap-2\">\n <Heading className=\"m-0 text-base font-semibold\">\n {onDrillDown ? (\n // Fareyle kısayol; klavyede aynı iş görünüm seçicisiyle.\n <button type=\"button\" tabIndex={-1} onClick={onDrillDown} className=\"cursor-pointer rounded-sm hover:text-mari-primary\">\n {label}\n </button>\n ) : (\n label\n )}\n </Heading>\n <span className=\"text-sm text-mari-muted tabular-nums\">{count} öğe</span>\n </div>\n </div>\n );\n}\n\ninterface GalleryToolbarProps {\n title: React.ReactNode;\n selecting: boolean;\n selectedKeys: React.Key[];\n selectionActions?: (keys: React.Key[]) => React.ReactNode;\n empty: boolean;\n /** `false`sa \"Seç\" düğmesi yok. */\n selectable: boolean;\n onSelectAll: () => void;\n onExitSelection: () => void;\n onEnterSelection: () => void;\n view: GalleryView;\n /** Birden azsa görünüm seçici yok. */\n views: GalleryView[];\n onViewChange: (view: GalleryView) => void;\n columns: number;\n /** Geçerli küçük resim genişliği (px) — çok küçülmesin. */\n cell: number;\n onColumnsChange: (columns: number) => void;\n}\n\n/** Yapışkan üst çubuk: normalde başlık + görünüm + sütun + \"Seç\"; seçim modunda sayı + eylemler. */\nconst GalleryToolbar = React.forwardRef<HTMLDivElement, GalleryToolbarProps>(function GalleryToolbar(\n {\n title,\n selecting,\n selectedKeys,\n selectionActions,\n empty,\n selectable,\n onSelectAll,\n onExitSelection,\n onEnterSelection,\n view,\n views,\n onViewChange,\n columns,\n cell,\n onColumnsChange,\n },\n ref\n) {\n const canZoomOut = columns < MAX_COLUMNS && cell > 40;\n const canZoomIn = columns > MIN_COLUMNS;\n const selectionLabel = selectedKeys.length ? `${selectedKeys.length} öğe seçildi` : \"Öğe seçin\";\n return (\n <div ref={ref} className=\"sticky top-0 z-mari-sticky flex min-h-12 flex-wrap items-center gap-2 bg-mari-surface/85 px-1 py-2 backdrop-blur-md\">\n {/* Seçim modunda sayı kırpılmasın: dar ekranda eylemler alt satıra sarar. */}\n <div\n className={cn(\"text-base font-semibold\", selecting ? \"flex-[1_0_auto]\" : \"min-w-0 flex-1 truncate\")}\n aria-live={selecting ? \"polite\" : undefined}\n >\n {selecting ? selectionLabel : title}\n </div>\n {selecting ? (\n <>\n {selectionActions?.(selectedKeys)}\n <Button size=\"sm\" variant=\"ghost\" color=\"neutral\" onClick={onSelectAll} disabled={empty}>\n Tümünü seç\n </Button>\n <Button size=\"sm\" variant=\"outline\" color=\"neutral\" onClick={onExitSelection}>\n Vazgeç\n </Button>\n </>\n ) : (\n <>\n {views.length > 1 && (\n <Segmented\n size=\"sm\"\n aria-label=\"Görünüm\"\n value={view}\n onChange={(v) => onViewChange(v as GalleryView)}\n options={views.map((v) => ({ value: v, label: VIEW_LABEL[v] }))}\n />\n )}\n <div className=\"flex items-center\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n icon={<ZoomOutIcon />}\n aria-label=\"Küçük resimleri küçült\"\n disabled={!canZoomOut}\n onClick={() => onColumnsChange(columns + 1)}\n />\n <Button\n size=\"sm\"\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n icon={<ZoomInIcon />}\n aria-label=\"Küçük resimleri büyüt\"\n disabled={!canZoomIn}\n onClick={() => onColumnsChange(columns - 1)}\n />\n </div>\n {selectable && (\n <Button size=\"sm\" variant=\"outline\" color=\"neutral\" onClick={onEnterSelection} disabled={empty}>\n Seç\n </Button>\n )}\n </>\n )}\n </div>\n );\n});\n\n/** Yüklü hâliyle aynı ölçü: aynı sütun hesabı (`autoColumns`, ölçülen genişlik), aynı başlık yüksekliği. */\nfunction GallerySkeleton({\n toolbar,\n columns,\n view,\n gap,\n className,\n}: Readonly<{\n toolbar: boolean;\n columns: number | \"auto\";\n view: GalleryView;\n gap: number;\n className?: string;\n}>) {\n const gridRef = useRef<HTMLDivElement>(null);\n const width = useWidth(gridRef, true);\n const cols = columns === \"auto\" ? autoColumns(width, view, gap) : clampColumns(columns);\n const box = skeletonBoxProps();\n return (\n <div aria-hidden aria-busy className={cn(\"relative\", className)}>\n {toolbar && (\n <div className=\"flex min-h-12 items-center gap-2 px-1 py-2\">\n <span {...box} className={cn(box.className, \"h-5 w-32 rounded-sm\")} />\n <span className=\"flex-1\" />\n <span {...box} className={cn(box.className, \"h-6 w-48 rounded-md\")} />\n </div>\n )}\n {view !== \"all\" && (\n <div className=\"flex items-end px-1 pb-1.5\" style={{ height: `${HEADER_REM}rem` }}>\n <span {...box} className={cn(box.className, \"h-4 w-40 rounded-sm\")} />\n </div>\n )}\n <div ref={gridRef} className=\"grid\" style={{ gridTemplateColumns: `repeat(${cols}, minmax(0, 1fr))`, gap }}>\n {Array.from({ length: SKELETON_ROWS * cols }, (_, i) => (\n <span key={i} {...box} className={cn(box.className, \"aspect-square rounded-none\")} />\n ))}\n </div>\n </div>\n );\n}\n","/**\n * Faz 16.7 — ImageGallery'nin saf mantığı: tarihe göre bölümleme, sütun\n * sayısı, sanal yerleşim (satır konumları), görünür aralık ve ızgara tuşları.\n * DOM'a dokunmaz → test edilebilir.\n */\n\nexport type GalleryView = \"all\" | \"day\" | \"month\" | \"year\";\n\nexport interface GalleryEntry<T> {\n item: T;\n /** Bölümlenmiş (düz) sıradaki yeri — görüntüleyici ve seçim bu sırayı kullanır. */\n index: number;\n}\n\nexport interface GallerySection<T> {\n key: string;\n /** Bölümün ilk öğesinin tarihi (başlık için). Tarihsiz bölümde `null`. */\n date: Date | null;\n entries: GalleryEntry<T>[];\n}\n\nexport function sectionKey(date: Date | null | undefined, view: GalleryView): string {\n if (view === \"all\") return \"all\";\n if (!date) return \"none\";\n const y = date.getFullYear();\n if (view === \"year\") return String(y);\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\n if (view === \"month\") return `${y}-${m}`;\n return `${y}-${m}-${String(date.getDate()).padStart(2, \"0\")}`;\n}\n\n/**\n * Öğeleri görünüme göre bölümler. Sıra korunur (tüketici zaten tarihe göre\n * sıralar); aynı anahtara düşen ayrık öğeler ilk görüldükleri bölüme toplanır.\n */\nexport function groupItems<T>(items: readonly T[], view: GalleryView, getDate: (item: T) => Date | null | undefined): GallerySection<T>[] {\n const map = new Map<string, GallerySection<T>>();\n for (const item of items) {\n const date = getDate(item) ?? null;\n const key = sectionKey(date, view);\n let section = map.get(key);\n if (!section) {\n section = { key, date, entries: [] };\n map.set(key, section);\n }\n section.entries.push({ item, index: 0 });\n }\n const sections = Array.from(map.values());\n let i = 0;\n for (const s of sections) for (const e of s.entries) e.index = i++;\n return sections;\n}\n\n/** Görünüme göre hedef küçük resim genişliği (px): gün iri, yıl sık — iPhone gibi. */\nexport const TARGET_TILE: Record<GalleryView, number> = { day: 160, all: 120, month: 100, year: 64 };\nexport const MIN_COLUMNS = 2;\nexport const MAX_COLUMNS = 16;\n\nexport const clampColumns = (n: number) => Math.min(MAX_COLUMNS, Math.max(MIN_COLUMNS, Math.round(n)));\n\nexport function autoColumns(width: number, view: GalleryView, gap: number): number {\n if (width <= 0) return 4;\n return clampColumns(Math.floor((width + gap) / (TARGET_TILE[view] + gap)));\n}\n\nexport type GalleryRow =\n | { kind: \"header\"; section: number; top: number; height: number }\n /** `start`..`end` (dahil değil) düz dizinler. */\n | { kind: \"items\"; section: number; start: number; end: number; top: number; height: number };\n\nexport interface GalleryLayout {\n rows: GalleryRow[];\n height: number;\n cell: number;\n columns: number;\n /** Düz dizin → satır numarası. */\n rowOf: number[];\n}\n\nexport function buildLayout(\n sections: readonly GallerySection<unknown>[],\n { width, columns, gap, headerHeight }: { width: number; columns: number; gap: number; headerHeight: number }\n): GalleryLayout {\n const cell = Math.max(0, (width - gap * (columns - 1)) / columns);\n const rows: GalleryRow[] = [];\n const rowOf: number[] = [];\n let top = 0;\n sections.forEach((section, s) => {\n if (headerHeight > 0) {\n rows.push({ kind: \"header\", section: s, top, height: headerHeight });\n top += headerHeight;\n } else if (s > 0) {\n top += gap;\n }\n const first = section.entries[0]?.index ?? 0;\n for (let k = 0; k < section.entries.length; k += columns) {\n const start = first + k;\n const end = first + Math.min(k + columns, section.entries.length);\n for (let i = start; i < end; i++) rowOf[i] = rows.length;\n rows.push({ kind: \"items\", section: s, start, end, top, height: cell });\n top += cell + (k + columns < section.entries.length ? gap : 0);\n }\n });\n return { rows, height: top, cell, columns, rowOf };\n}\n\n/** `[viewTop, viewBottom]` (galeriye göre px) ile kesişen satırlar + her iki yanda `overscan` satır. */\nexport function visibleRows(rows: readonly GalleryRow[], viewTop: number, viewBottom: number, overscan = 2): [number, number] {\n if (!rows.length || viewBottom <= viewTop) return [0, -1];\n // İlk `top + height > viewTop` satırı (ikili arama).\n let lo = 0;\n let hi = rows.length - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n const r = rows[mid]!;\n if (r.top + r.height > viewTop) hi = mid;\n else lo = mid + 1;\n }\n let last = lo;\n while (last + 1 < rows.length && rows[last + 1]!.top < viewBottom) last++;\n if (rows[lo]!.top >= viewBottom) return [Math.max(0, lo - overscan), Math.min(rows.length - 1, lo + overscan)];\n return [Math.max(0, lo - overscan), Math.min(rows.length - 1, last + overscan)];\n}\n\n/** Render edilecek satırlar: görünen aralık + (dışındaysa) odaktaki satır — odak sanallaştırmada kaybolmasın. */\nexport function renderedRows([first, last]: [number, number], total: number, activeRow: number | undefined): number[] {\n const rows: number[] = [];\n for (let r = first; r <= last && r < total; r++) rows.push(r);\n if (activeRow !== undefined && (activeRow < first || activeRow > last)) rows.push(activeRow);\n return rows;\n}\n\n/**\n * Izgara tuşları → yeni düz dizin. ←/→ sıradaki öğe (bölüm sınırını aşar),\n * ↑/↓ aynı sütun bir üst/alt öğe satırı (bölüm atlanırsa sütun kısalan\n * satıra kırpılır), Home/End satır başı/sonu, Ctrl+Home/End ilk/son,\n * PageUp/PageDown `pageRows` öğe satırı. Uygun değilse `null`.\n */\nexport function galleryKeyStep(layout: GalleryLayout, index: number, key: string, ctrl: boolean, pageRows = 3): number | null {\n const count = layout.rowOf.length;\n if (!count) return null;\n const itemRows = layout.rows.map((r, i) => (r.kind === \"items\" ? i : -1)).filter((i) => i >= 0);\n const rowAt = (n: number) => layout.rows[itemRows[n]!] as Extract<GalleryRow, { kind: \"items\" }>;\n const current = itemRows.indexOf(layout.rowOf[index]!);\n const row = rowAt(current);\n const col = index - row.start;\n const moveRows = (delta: number) => {\n const target = Math.min(itemRows.length - 1, Math.max(0, current + delta));\n if (target === current) return null;\n const r = rowAt(target);\n return Math.min(r.start + col, r.end - 1);\n };\n switch (key) {\n case \"ArrowLeft\":\n return index > 0 ? index - 1 : null;\n case \"ArrowRight\":\n return index < count - 1 ? index + 1 : null;\n case \"ArrowUp\":\n return moveRows(-1);\n case \"ArrowDown\":\n return moveRows(1);\n case \"PageUp\":\n return moveRows(-pageRows);\n case \"PageDown\":\n return moveRows(pageRows);\n case \"Home\":\n return ctrl ? 0 : row.start;\n case \"End\":\n return ctrl ? count - 1 : row.end - 1;\n default:\n return null;\n }\n}\n\n/** Hücrede basılan tuş: Enter/Space → `\"activate\"`, gezinme → yeni dizin, değilse `null`. */\nexport function gridKeyIntent(layout: GalleryLayout, index: number, key: string, ctrl: boolean, pageRows: number): \"activate\" | number | null {\n if (key === \"Enter\" || key === \" \") return \"activate\";\n return galleryKeyStep(layout, index, key, ctrl, Math.max(1, pageRows));\n}\n\n/** Shift ile aralık seçimi: `anchor`..`index` (dahil) düz dizinleri. */\nexport function rangeIndexes(anchor: number, index: number): number[] {\n const [a, b] = anchor < index ? [anchor, index] : [index, anchor];\n return Array.from({ length: b - a + 1 }, (_, i) => a + i);\n}\n\n/** Video süresi: 75 → \"1:15\", 3725 → \"1:02:05\". */\nexport function formatDuration(seconds: number): string {\n const s = Math.max(0, Math.round(seconds));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const ss = String(s % 60).padStart(2, \"0\");\n return h ? `${h}:${String(m).padStart(2, \"0\")}:${ss}` : `${m}:${ss}`;\n}\n\nconst sameDay = (a: Date, b: Date) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n\n/** Bölüm başlığı: gün → \"Bugün\" / \"Dün\" / \"28 Eylül 2026 Pazartesi\", ay → \"Eylül 2026\", yıl → \"2026\". */\nexport function sectionLabel(date: Date | null, view: GalleryView, locale = \"tr-TR\", now = new Date()): string {\n if (!date) return \"Tarihsiz\";\n if (view === \"year\") return String(date.getFullYear());\n if (view === \"month\") return new Intl.DateTimeFormat(locale, { month: \"long\", year: \"numeric\" }).format(date);\n if (sameDay(date, now)) return \"Bugün\";\n const yesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);\n if (sameDay(date, yesterday)) return \"Dün\";\n return new Intl.DateTimeFormat(locale, {\n day: \"numeric\",\n month: \"long\",\n weekday: \"long\",\n ...(date.getFullYear() === now.getFullYear() ? {} : { year: \"numeric\" }),\n }).format(date);\n}\n\n/** Bir üst görünümün başlığına tıklayınca inilecek görünüm (yıl → ay → gün). */\nexport const DRILL_DOWN: Partial<Record<GalleryView, GalleryView>> = { year: \"month\", month: \"day\" };\n\n/**\n * Üst görünümde bir bölüm başlığına tıklanınca: inilecek görünüm ve o\n * bölümün ilk öğesinin YENİ görünümdeki düz dizini (yeniden bölümlemede\n * sıra değişebilir → anahtar yerine öğenin kendisiyle bulunur).\n */\nexport function drillDownTarget<T>(\n items: readonly T[],\n sections: readonly GallerySection<T>[],\n view: GalleryView,\n sectionIndex: number,\n getDate: (item: T) => Date | null | undefined\n): { view: GalleryView; index: number } | null {\n const next = DRILL_DOWN[view];\n const first = sections[sectionIndex]?.entries[0]?.item;\n if (!next || first === undefined) return null;\n const regrouped = groupItems(items, next, getDate).flatMap((s) => s.entries);\n const hit = regrouped.find((e) => e.item === first);\n return { view: next, index: hit?.index ?? 0 };\n}\n"],"mappings":"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","names":["useEffect","useRef","useState","ImageOffIcon","cn","useControllableState","Fragment","jsx","jsxs","ImageOffIcon","cn","Image","useState","useRef","useEffect","useControllableState","React","useEffect","useLayoutEffect","useRef","useState","ZoomInIcon","ZoomOutIcon","cn","useControllableState","Fragment","jsx","jsxs","useEffect","useLayoutEffect","useState","useRef","cn","useControllableState","React","GalleryToolbar","ZoomOutIcon","ZoomInIcon"]}
|
|
1
|
+
{"version":3,"sources":["../src/image/Image.tsx","../src/image/ImageViewer.tsx","../src/image/utils.ts","../src/image/viewerUtils.ts","../src/image/ImageGallery.tsx","../src/image/galleryUtils.ts"],"sourcesContent":["\"use client\";\n\nimport React, { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { EyeIcon, ImageOffIcon } from \"lucide-react\";\nimport { cn, useControllableState } from \"@mari-ui/core\";\nimport { skeletonBoxProps } from \"../lib/skeleton\";\nimport { ImageViewer } from \"./ImageViewer\";\nimport type { ImageFit, ImageLoader, ImagePreviewConfig, ImageProps } from \"./types\";\nimport { getBoxStyle, imgAttributes, normalizeSource, resolveBlurSource, resolveImage } from \"./utils\";\n\nexport type { ImageProps };\n\nconst FIT_CLASS: Record<ImageFit, string> = {\n cover: \"object-cover\",\n contain: \"object-contain\",\n fill: \"object-fill\",\n none: \"object-none\",\n \"scale-down\": \"object-scale-down\",\n};\n\ntype Status = \"loading\" | \"loaded\" | \"error\";\n\nfunction DefaultFallback() {\n return (\n <span className=\"flex size-full min-h-16 flex-col items-center justify-center gap-1 p-2 text-center text-xs text-mari-muted\">\n <ImageOffIcon aria-hidden className=\"size-6\" />\n Görsel yüklenemedi\n </span>\n );\n}\n\n/** Yüklenirken: bulanık ön izleme → özel içerik → parıltı (öncelik sırasıyla). */\nfunction PlaceholderLayer({ blurSrc, custom, shimmer, fit }: Readonly<{ blurSrc: string | null; custom: React.ReactNode; shimmer: boolean; fit: ImageFit }>) {\n if (blurSrc) {\n return <img src={blurSrc} alt=\"\" aria-hidden draggable={false} className={cn(\"absolute inset-0 size-full scale-110 blur-lg\", FIT_CLASS[fit])} />;\n }\n if (custom) {\n return (\n <span aria-hidden className=\"absolute inset-0 flex items-center justify-center\">\n {custom}\n </span>\n );\n }\n return shimmer ? <span aria-hidden className={cn(\"absolute inset-0\", skeletonBoxProps().className)} /> : null;\n}\n\nfunction placeholderNode(placeholder: ImageProps[\"placeholder\"]): React.ReactNode {\n return placeholder !== undefined && typeof placeholder !== \"boolean\" && typeof placeholder !== \"string\" ? placeholder : null;\n}\n\n/*\n * yapı ant.design Image'dan (progressive loading: önce düşük\n * çözünürlüklü/bulanık ön izleme, asıl görsel yüklenince yumuşak geçiş;\n * `fallback`; `preview`), görünüm token'lardan. Framework'e bağlı değil: düz\n * `<img>` (`loading=\"lazy\"`, `decoding=\"async\"`, `srcSet`/`sizes`); CDN ve\n * boyutlandırma `loader` ile, `next/image`'a gerek yok.\n */\n/**\n * Dış kutu yeri önceden ayırır (`aspectRatio` ya da `width`/`height`) →\n * yüklenince sayfa kaymaz. `preview` ile kutu bir düğme olur ve tam ekran\n * `ImageViewer` açılır.\n */\nexport const Image = forwardRef<HTMLImageElement, ImageProps>(function Image(\n {\n src,\n alt,\n width,\n height,\n aspectRatio,\n fit = \"cover\",\n loader,\n widths,\n sizes,\n quality,\n placeholder,\n fallback,\n loading = \"lazy\",\n priority = false,\n preview = false,\n skeleton = false,\n className,\n wrapperClassName,\n style,\n onLoad,\n onError,\n ...imgProps\n },\n ref\n) {\n const source = normalizeSource(src);\n const [status, setStatus] = useState<Status>(\"loading\");\n const imgRef = useRef<HTMLImageElement | null>(null);\n\n const resolved = source ? resolveImage(source, { loader, width, widths, quality }) : null;\n const effectivePlaceholder = placeholder ?? (source?.blurDataURL ? true : undefined);\n const blurSrc = source ? resolveBlurSource(effectivePlaceholder, source, loader) : null;\n const customPlaceholder = placeholderNode(effectivePlaceholder);\n\n // Kaynak değişince baştan.\n const key = resolved ? `${resolved.src}|${resolved.srcSet ?? \"\"}` : \"\";\n useEffect(() => {\n setStatus(\"loading\");\n // SSR'dan gelen ya da önbellekteki görsel hidrasyondan önce yüklenmiş olabilir — `onLoad` hiç gelmez.\n const img = imgRef.current;\n if (img?.complete) setStatus(img.naturalWidth > 0 ? \"loaded\" : \"error\");\n }, [key]);\n\n const boxStyle = getBoxStyle({ width, height, aspectRatio, source });\n const boxClass = cn(\n \"relative isolate inline-block max-w-full overflow-hidden rounded-md align-middle\",\n status !== \"loaded\" && \"bg-mari-surface-alt\",\n wrapperClassName\n );\n\n if (skeleton) {\n const sk = skeletonBoxProps(boxClass);\n // Boyut bilinmiyorsa iskelet görünür kalsın diye makul bir oran.\n const skStyle = Object.keys(boxStyle).length ? boxStyle : { width: \"100%\", aspectRatio: \"4 / 3\" };\n return <span {...sk} className={cn(sk.className, \"block\")} style={{ ...skStyle, ...style }} />;\n }\n\n const setRefs = (el: HTMLImageElement | null) => {\n imgRef.current = el;\n if (typeof ref === \"function\") ref(el);\n else if (ref) ref.current = el;\n };\n\n const loaded = status === \"loaded\";\n const failed = status === \"error\" || !source;\n\n const content = (\n <>\n {!loaded && !failed && (\n <PlaceholderLayer blurSrc={blurSrc} custom={customPlaceholder} shimmer={effectivePlaceholder === true} fit={fit} />\n )}\n {resolved && status !== \"error\" && (\n <img\n {...imgProps}\n ref={setRefs}\n src={resolved.src}\n srcSet={resolved.srcSet}\n {...imgAttributes({ width, height, source, srcSet: resolved.srcSet, sizes, priority, loading, fetchPriority: imgProps.fetchPriority })}\n alt={alt}\n decoding=\"async\"\n onLoad={(event) => {\n setStatus(\"loaded\");\n onLoad?.(event);\n }}\n onError={(event) => {\n setStatus(\"error\");\n onError?.(event);\n }}\n className={cn(\n \"relative block size-full transition-opacity duration-500 motion-reduce:transition-none\",\n FIT_CLASS[fit],\n loaded ? \"opacity-100\" : \"opacity-0\",\n className\n )}\n />\n )}\n {failed && <FallbackLayer key={key} fallback={fallback} alt={alt} className={cn(FIT_CLASS[fit], className)} />}\n </>\n );\n\n if (!preview) {\n return (\n <span className={boxClass} style={{ ...boxStyle, ...style }}>\n {content}\n </span>\n );\n }\n\n return (\n <PreviewFrame\n config={typeof preview === \"object\" ? preview : {}}\n src={src}\n alt={alt}\n loader={loader}\n loaded={loaded}\n disabled={failed}\n thumbnail={() => imgRef.current?.currentSrc || resolved?.src}\n className={boxClass}\n style={{ ...boxStyle, ...style }}\n >\n {content}\n </PreviewFrame>\n );\n});\n\n/** Yüklenemezse: URL yedeği (o da yüklenemezse varsayılan), node ya da varsayılan. */\nfunction FallbackLayer({ fallback, alt, className }: Readonly<{ fallback: ImageProps[\"fallback\"]; alt: string; className?: string }>) {\n const [urlFailed, setUrlFailed] = useState(false);\n if (typeof fallback === \"string\" && !urlFailed) {\n return <img src={fallback} alt={alt} onError={() => setUrlFailed(true)} className={cn(\"block size-full\", className)} />;\n }\n if (typeof fallback !== \"string\" && fallback) return <>{fallback}</>;\n return <DefaultFallback />;\n}\n\n/** `preview`: kutu bir düğme olur, tam ekran görüntüleyiciyi açar; kapanınca odak düğmeye döner. */\nfunction PreviewFrame({\n config,\n src,\n alt,\n loader,\n loaded,\n disabled,\n thumbnail,\n className,\n style,\n children,\n}: Readonly<{\n config: ImagePreviewConfig;\n src: ImageProps[\"src\"];\n alt: string;\n loader?: ImageLoader;\n loaded: boolean;\n disabled: boolean;\n thumbnail: () => string | undefined;\n className: string;\n style: React.CSSProperties;\n children: React.ReactNode;\n}>) {\n const triggerRef = useRef<HTMLButtonElement>(null);\n const [open, setOpen] = useControllableState({ value: config.open, defaultValue: false, onChange: config.onOpenChange });\n const previewSource = config.src ?? src;\n return (\n <>\n <button\n ref={triggerRef}\n type=\"button\"\n aria-haspopup=\"dialog\"\n aria-label={alt ? `${alt} — büyüt` : \"Görseli büyüt\"}\n disabled={disabled}\n onClick={() => setOpen(true)}\n className={cn(\n className,\n \"group cursor-zoom-in focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-mari-ring disabled:cursor-default\"\n )}\n style={style}\n >\n {children}\n {loaded && (\n <span\n aria-hidden\n className=\"absolute inset-0 flex items-center justify-center gap-1.5 bg-mari-scrim text-sm font-medium text-white opacity-0 transition-opacity duration-200 group-hover:opacity-100 group-focus-visible:opacity-100 pointer-coarse:hidden\"\n >\n <EyeIcon className=\"size-4\" />\n Önizle\n </span>\n )}\n </button>\n {previewSource && (\n <ImageViewer\n open={open ?? false}\n onClose={() => setOpen(false)}\n loader={loader}\n getOriginElement={() => triggerRef.current}\n items={[{ key: \"preview\", src: previewSource, alt, caption: config.caption, thumbnail: thumbnail() }]}\n />\n )}\n </>\n );\n}\n","\"use client\";\n\nimport React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { ChevronLeftIcon, ChevronRightIcon, ImageOffIcon, Loader2Icon, XIcon, ZoomInIcon, ZoomOutIcon } from \"lucide-react\";\nimport { cn, useControllableState } from \"@mari-ui/core\";\nimport { Button } from \"../button\";\nimport { useModalBehavior, usePresence } from \"../lib/overlay\";\nimport type { ImageLoader, ImageSource } from \"./types\";\nimport { normalizeSource, resolveImage } from \"./utils\";\nimport {\n IDENTITY,\n MAX_SCALE,\n MIN_SCALE,\n clampPan,\n containSize,\n dismissProgress,\n dragIntent,\n originTransform,\n shouldDismiss,\n swipeOutcome,\n toggleZoom,\n visibleSlides,\n zoomAround,\n type Size,\n type ViewState,\n} from \"./viewerUtils\";\n\nexport interface ImageViewerItem {\n key: React.Key;\n /** Tam çözünürlüklü kaynak (video için video adresi). */\n src: ImageSource;\n alt: string;\n /** Asıl görsel yüklenene kadar altta gösterilen küçük boy; alt şeritte de kullanılır. */\n thumbnail?: string;\n caption?: React.ReactNode;\n /** Varsayılan: `\"image\"`. Videoda yakınlaştırma yoktur, yerel oynatıcı denetimleri kullanılır. */\n type?: \"image\" | \"video\";\n /** Video kapak görseli. */\n poster?: string;\n /** Video altyazı/açıklama izleri (WebVTT). Konuşma içeren videolarda verin. */\n tracks?: { src: string; srcLang: string; label: string; kind?: \"captions\" | \"subtitles\" | \"descriptions\"; default?: boolean }[];\n}\n\nexport interface ImageViewerProps {\n items: ImageViewerItem[];\n open: boolean;\n onClose: () => void;\n index?: number;\n defaultIndex?: number;\n onIndexChange?: (index: number) => void;\n loader?: ImageLoader;\n /**\n * Bir öğenin sayfadaki küçük resmi (genelde tetikleyici düğme): açılış/kapanış\n * o kutudan büyüyerek/küçülerek olur, kapanınca odak ona döner.\n */\n getOriginElement?: (index: number) => HTMLElement | null | undefined;\n /** Alt şerit. Varsayılan: birden fazla öğe varsa. */\n thumbnails?: boolean;\n /** Üst çubuğa ek eylemler (paylaş, sil…). */\n actions?: (item: ImageViewerItem, index: number) => React.ReactNode;\n \"aria-label\"?: string;\n}\n\nconst EXIT_MS = 250;\nconst ENTER_MS = 300;\nconst SETTLE_MS = 250;\nconst SLIDE_GAP = 24;\nconst DOUBLE_TAP_MS = 280;\nconst ZOOM_STEP = 1.5;\nconst EASE = \"cubic-bezier(0.2, 0.8, 0.2, 1)\";\n\ninterface Gesture {\n kind: \"pending\" | \"swipe\" | \"dismiss\" | \"pan\" | \"pinch\";\n startX: number;\n startY: number;\n lastX: number;\n lastY: number;\n lastT: number;\n vx: number;\n vy: number;\n dx: number;\n dy: number;\n startView: ViewState;\n startDist: number;\n startMid: { x: number; y: number };\n pointerType: string;\n}\n\nfunction reducedMotion(): boolean {\n return typeof window !== \"undefined\" && window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches === true;\n}\n\nfunction setStyle(el: HTMLElement | null | undefined, transform: string, ms: number) {\n if (!el) return;\n el.style.transition = ms > 0 ? `transform ${ms}ms ${EASE}, opacity ${ms}ms ${EASE}` : \"none\";\n el.style.transform = transform;\n}\n\nfunction zoomLevelOf(scale: number): \"min\" | \"mid\" | \"max\" {\n if (scale <= MIN_SCALE) return \"min\";\n return scale >= MAX_SCALE ? \"max\" : \"mid\";\n}\n\n/** Başlangıç durumunu uygula ki ardından gelen geçiş ondan başlasın. */\nfunction forceReflow(el: HTMLElement | null | undefined) {\n el?.getBoundingClientRect();\n}\n\nconst viewTransform = (v: ViewState) => `translate3d(${v.x}px, ${v.y}px, 0) scale(${v.scale})`;\n\n/** Küçük resim adresi: verilen `thumbnail` → `loader` küçük boy → kaynağın kendisi. */\nexport function viewerThumbnail(item: ImageViewerItem, loader: ImageLoader | undefined, width = 160): string | undefined {\n if (item.thumbnail) return item.thumbnail;\n if (item.type === \"video\") return item.poster;\n const source = normalizeSource(item.src);\n if (!source) return undefined;\n return loader ? loader({ src: source.src, width }) : source.src;\n}\n\nfunction ViewerSlide({\n item,\n offset,\n loader,\n}: Readonly<{\n item: ImageViewerItem;\n offset: number;\n loader?: ImageLoader;\n}>) {\n const active = offset === 0;\n const source = normalizeSource(item.src);\n const [loaded, setLoaded] = useState(false);\n const [failed, setFailed] = useState(false);\n const thumb = viewerThumbnail(item, loader);\n const resolved = source && item.type !== \"video\" ? resolveImage(source, { loader }) : null;\n\n return (\n <div\n data-viewer-slide=\"\"\n data-viewer-active={active ? \"\" : undefined}\n aria-hidden={active ? undefined : true}\n className=\"absolute inset-0\"\n style={{ transform: `translateX(calc(${offset * 100}% + ${offset * SLIDE_GAP}px))` }}\n >\n <div data-viewer-zoom=\"\" className=\"relative flex size-full items-center justify-center will-change-transform\">\n {item.type === \"video\" ? (\n source && (\n // Altyazılar `tracks` ile tüketiciden gelir (kural eşlenmiş <track>ları göremiyor).\n // eslint-disable-next-line jsx-a11y/media-has-caption\n <video\n src={source.src}\n poster={item.poster}\n controls\n playsInline\n preload=\"metadata\"\n tabIndex={active ? 0 : -1}\n aria-label={item.alt}\n className=\"max-h-full max-w-full\"\n >\n {item.tracks?.map((t) => (\n <track key={t.src} kind={t.kind ?? \"captions\"} src={t.src} srcLang={t.srcLang} label={t.label} default={t.default} />\n ))}\n </video>\n )\n ) : (\n <>\n {thumb && !loaded && !failed && (\n <img src={thumb} alt=\"\" aria-hidden draggable={false} className=\"absolute inset-0 size-full object-contain blur-sm\" />\n )}\n {resolved && !failed && (\n <img\n data-viewer-full=\"\"\n src={resolved.src}\n srcSet={resolved.srcSet}\n sizes=\"100vw\"\n alt={item.alt}\n draggable={false}\n decoding=\"async\"\n onLoad={() => setLoaded(true)}\n onError={() => setFailed(true)}\n className={cn(\n \"absolute inset-0 size-full object-contain transition-opacity duration-300 motion-reduce:transition-none\",\n loaded ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n )}\n {!loaded && !failed && !thumb && <Loader2Icon aria-hidden className=\"size-8 animate-spin text-mari-muted\" />}\n {failed && (\n <div className=\"flex flex-col items-center gap-2 text-sm text-mari-muted\">\n <ImageOffIcon aria-hidden className=\"size-10\" />\n Görsel yüklenemedi\n </div>\n )}\n </>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * Tam ekran görsel/video görüntüleyici. Yapı iPhone Fotoğraflar'dan:\n * küçük resimden büyüyerek açılış, yana kaydırarak geçiş, aşağı çekerek kapatma,\n * iki parmak / tekerlek / çift dokunuşla yakınlaştırma + kaydırma, dokununca\n * araç çubuklarını gizleme, alt şerit. Görünüm token'lardan (arka plan =\n * `mari-surface`: açık temada beyaz, koyu temada koyu — iPhone gibi).\n * `Image`'ın `preview`'ı ve `ImageGallery` bunu kullanır.\n */\nexport function ImageViewer({\n items,\n open,\n onClose,\n index: indexProp,\n defaultIndex = 0,\n onIndexChange,\n loader,\n getOriginElement,\n thumbnails,\n actions,\n \"aria-label\": ariaLabel = \"Görsel görüntüleyici\",\n}: ImageViewerProps) {\n const [rawIndex, setIndex] = useControllableState({ value: indexProp, defaultValue: defaultIndex, onChange: onIndexChange });\n const count = items.length;\n const index = Math.min(Math.max(rawIndex ?? 0, 0), Math.max(count - 1, 0));\n const item = items[index];\n const present = usePresence(open, EXIT_MS);\n\n const panelRef = useRef<HTMLDivElement>(null);\n const stageRef = useRef<HTMLDivElement>(null);\n const trackRef = useRef<HTMLDivElement>(null);\n const backdropRef = useRef<HTMLDivElement>(null);\n const stripRef = useRef<HTMLDivElement>(null);\n const view = useRef<ViewState>(IDENTITY);\n const pointers = useRef(new Map<number, { x: number; y: number }>());\n const gesture = useRef<Gesture | null>(null);\n const busy = useRef(false);\n const lastTap = useRef<{ t: number; x: number; y: number } | null>(null);\n const tapTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const goTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const indexRef = useRef(index);\n indexRef.current = index;\n // Yalnız eşik geçişlerinde render: hareket başına değil.\n const [zoomLevel, setZoomLevel] = useState<\"min\" | \"mid\" | \"max\">(\"min\");\n const zoomed = zoomLevel !== \"min\";\n const [chrome, setChrome] = useState(true);\n\n useModalBehavior(open, panelRef, onClose, {\n getInitialFocus: (panel) => panel.querySelector<HTMLElement>(\"[data-viewer-close]\"),\n });\n\n const isVideo = item?.type === \"video\";\n const showStrip = (thumbnails ?? count > 1) && count > 1;\n\n const zoomEl = () => trackRef.current?.querySelector<HTMLElement>(\"[data-viewer-active] [data-viewer-zoom]\") ?? null;\n const stageSize = (): Size => ({ width: stageRef.current?.clientWidth ?? 0, height: stageRef.current?.clientHeight ?? 0 });\n const baseSize = (): Size => {\n const imgs = zoomEl()?.querySelectorAll(\"img\");\n const img = Array.from(imgs ?? []).find((el) => el.naturalWidth > 0);\n return img ? containSize({ width: img.naturalWidth, height: img.naturalHeight }, stageSize()) : stageSize();\n };\n const toStagePoint = (clientX: number, clientY: number) => {\n const r = stageRef.current?.getBoundingClientRect();\n if (!r) return { x: 0, y: 0 };\n return { x: clientX - r.left - r.width / 2, y: clientY - r.top - r.height / 2 };\n };\n\n const applyView = useCallback((next: ViewState, ms = 0) => {\n view.current = next;\n setStyle(zoomEl(), viewTransform(next), ms);\n setZoomLevel(zoomLevelOf(next.scale));\n }, []);\n\n const setTrack = (dx: number, ms = 0) => setStyle(trackRef.current, `translate3d(${dx}px, 0, 0)`, ms);\n\n const setDismiss = (dx: number, dy: number, ms = 0) => {\n const p = dismissProgress(dy, stageSize().height);\n setStyle(zoomEl(), `translate3d(${dx}px, ${Math.max(dy, 0)}px, 0) scale(${1 - p * 0.3})`, ms);\n const backdrop = backdropRef.current;\n if (backdrop) {\n backdrop.style.transition = ms > 0 ? `opacity ${ms}ms ${EASE}` : \"none\";\n backdrop.style.opacity = String(1 - p);\n }\n };\n\n const go = useCallback(\n (dir: -1 | 1) => {\n const next = indexRef.current + dir;\n if (busy.current) return;\n if (next < 0 || next >= count) {\n setTrack(0, SETTLE_MS);\n return;\n }\n busy.current = true;\n const width = stageSize().width;\n setTrack(reducedMotion() ? 0 : -dir * (width + SLIDE_GAP), reducedMotion() ? 0 : SETTLE_MS);\n clearTimeout(goTimer.current);\n goTimer.current = setTimeout(() => {\n busy.current = false;\n setIndex(next);\n }, reducedMotion() ? 0 : SETTLE_MS);\n },\n [count, setIndex]\n );\n\n // Öğe değişince: şerit ve yakınlaştırma sıfır, komşu dilimlerdeki eski dönüşümler temizlenir, videolar durur.\n useLayoutEffect(() => {\n if (!present) return;\n setTrack(0);\n trackRef.current?.querySelectorAll<HTMLElement>(\"[data-viewer-zoom]\").forEach((el) => setStyle(el, \"\", 0));\n view.current = IDENTITY;\n setZoomLevel(\"min\");\n trackRef.current?.querySelectorAll(\"video\").forEach((v) => {\n if (!v.paused && !v.closest(\"[data-viewer-active]\")) v.pause();\n });\n }, [index, present]);\n\n // Alt şeritte geçerli öğe ortada.\n useEffect(() => {\n const strip = stripRef.current;\n const btn = strip?.querySelector<HTMLElement>('[aria-current=\"true\"]');\n if (!strip || !btn) return;\n strip.scrollTo?.({ left: btn.offsetLeft - strip.clientWidth / 2 + btn.offsetWidth / 2, behavior: reducedMotion() ? \"auto\" : \"smooth\" });\n }, [index, present, showStrip]);\n\n // Açılış: küçük resimden büyüyerek (FLIP), yoksa solarak.\n useLayoutEffect(() => {\n if (!open) return;\n setChrome(true);\n const zoom = zoomEl();\n const backdrop = backdropRef.current;\n const origin = getOriginElement?.(indexRef.current);\n const originImg = origin?.querySelector(\"img\");\n if (backdrop) {\n backdrop.style.transition = \"none\";\n backdrop.style.opacity = \"0\";\n }\n if (zoom && origin && !reducedMotion()) {\n const from = (originImg ?? origin).getBoundingClientRect();\n const stage = stageRef.current?.getBoundingClientRect();\n const fit =\n originImg && originImg.naturalWidth > 0\n ? containSize({ width: originImg.naturalWidth, height: originImg.naturalHeight }, stageSize())\n : stageSize();\n if (stage) {\n const t = originTransform(from, {\n left: stage.left + (stage.width - fit.width) / 2,\n top: stage.top + (stage.height - fit.height) / 2,\n width: fit.width,\n height: fit.height,\n });\n setStyle(zoom, `translate3d(${t.x}px, ${t.y}px, 0) scale(${t.scale})`, 0);\n }\n } else if (zoom) {\n zoom.style.opacity = \"0\";\n }\n forceReflow(zoom);\n const ms = reducedMotion() ? 0 : ENTER_MS;\n setStyle(zoom, viewTransform(IDENTITY), ms);\n if (zoom) zoom.style.opacity = \"1\";\n if (backdrop) {\n backdrop.style.transition = `opacity ${ms}ms ${EASE}`;\n backdrop.style.opacity = \"1\";\n }\n // Açılışta bir kez; `getOriginElement` her render'da yeni olabilir.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n\n // Kapanış: geçerli öğenin küçük resmine küçülerek; odak ona döner.\n const wasOpen = useRef(open);\n useEffect(() => {\n const closing = wasOpen.current && !open;\n wasOpen.current = open;\n if (!closing) return;\n clearTimeout(tapTimer.current);\n gesture.current = null;\n pointers.current.clear();\n const origin = getOriginElement?.(indexRef.current);\n const zoom = zoomEl();\n const ms = reducedMotion() ? 0 : EXIT_MS;\n const rect = origin?.getBoundingClientRect();\n const onScreen = rect && rect.bottom > 0 && rect.top < window.innerHeight && rect.width > 0;\n const zoomRect = zoom?.getBoundingClientRect();\n if (zoom && rect && onScreen && zoomRect && !reducedMotion()) {\n const base = baseSize();\n const current = view.current.scale > MIN_SCALE ? IDENTITY : view.current;\n const target = {\n left: zoomRect.left + (zoomRect.width - base.width) / 2,\n top: zoomRect.top + (zoomRect.height - base.height) / 2,\n width: base.width,\n height: base.height,\n };\n const t = originTransform(rect, target);\n setStyle(zoom, viewTransform(current), 0);\n forceReflow(zoom);\n setStyle(zoom, `translate3d(${t.x}px, ${t.y}px, 0) scale(${t.scale})`, ms);\n } else if (zoom) {\n zoom.style.transition = `opacity ${ms}ms ${EASE}`;\n zoom.style.opacity = \"0\";\n }\n const backdrop = backdropRef.current;\n if (backdrop) {\n backdrop.style.transition = `opacity ${ms}ms ${EASE}`;\n backdrop.style.opacity = \"0\";\n }\n setChrome(false);\n // Modal davranışı odağı açılıştan önceki öğeye döndürdü; geçerli öğenin küçük resmi daha doğru hedef.\n origin?.focus({ preventScroll: true });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n\n useEffect(\n () => () => {\n clearTimeout(tapTimer.current);\n clearTimeout(goTimer.current);\n },\n []\n );\n\n // Tekerlek / izleme dörtgeni sıkıştırması: imleç çevresinde yakınlaştır.\n useEffect(() => {\n const stage = stageRef.current;\n if (!present || !stage) return;\n const onWheel = (event: WheelEvent) => {\n if (isVideo) return;\n event.preventDefault();\n const factor = Math.exp(-event.deltaY * (event.ctrlKey ? 0.01 : 0.002));\n applyView(zoomAround(view.current, view.current.scale * factor, toStagePoint(event.clientX, event.clientY), baseSize(), stageSize()));\n };\n stage.addEventListener(\"wheel\", onWheel, { passive: false });\n return () => stage.removeEventListener(\"wheel\", onWheel);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [present, isVideo, applyView]);\n\n const handleTap = (event: React.PointerEvent) => {\n const now = event.timeStamp;\n const prev = lastTap.current;\n if (prev && now - prev.t < DOUBLE_TAP_MS && Math.hypot(event.clientX - prev.x, event.clientY - prev.y) < 30) {\n lastTap.current = null;\n clearTimeout(tapTimer.current);\n if (!isVideo) applyView(toggleZoom(view.current, toStagePoint(event.clientX, event.clientY), baseSize(), stageSize()), SETTLE_MS);\n return;\n }\n lastTap.current = { t: now, x: event.clientX, y: event.clientY };\n // Dokunmatikte tek dokunuş araç çubuklarını gizler/gösterir (çift dokunuştan ayırmak için bekler).\n if (event.pointerType !== \"mouse\") {\n clearTimeout(tapTimer.current);\n tapTimer.current = setTimeout(() => setChrome((c) => !c), DOUBLE_TAP_MS);\n }\n };\n\n const startSingle = (x: number, y: number, t: number, pointerType: string): Gesture => ({\n kind: view.current.scale > MIN_SCALE ? \"pan\" : \"pending\",\n startX: x,\n startY: y,\n lastX: x,\n lastY: y,\n lastT: t,\n vx: 0,\n vy: 0,\n dx: 0,\n dy: 0,\n startView: view.current,\n startDist: 0,\n startMid: { x: 0, y: 0 },\n pointerType,\n });\n\n const onPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (busy.current || !open) return;\n if (event.pointerType === \"mouse\" && event.button !== 0) return;\n // Fareyle videonun kendi denetimleri çalışsın.\n if (event.pointerType === \"mouse\" && (event.target as HTMLElement).closest(\"video\")) return;\n pointers.current.set(event.pointerId, { x: event.clientX, y: event.clientY });\n if (pointers.current.size === 2 && !isVideo) {\n const [a, b] = Array.from(pointers.current.values()) as [{ x: number; y: number }, { x: number; y: number }];\n gesture.current = {\n ...startSingle(event.clientX, event.clientY, event.timeStamp, event.pointerType),\n kind: \"pinch\",\n startView: view.current,\n startDist: Math.hypot(a.x - b.x, a.y - b.y) || 1,\n startMid: toStagePoint((a.x + b.x) / 2, (a.y + b.y) / 2),\n };\n setTrack(0, SETTLE_MS);\n return;\n }\n if (pointers.current.size === 1) gesture.current = startSingle(event.clientX, event.clientY, event.timeStamp, event.pointerType);\n };\n\n const movePinch = (g: Gesture) => {\n const pts = Array.from(pointers.current.values());\n if (pts.length < 2) return;\n const [a, b] = pts as [{ x: number; y: number }, { x: number; y: number }];\n const mid = toStagePoint((a.x + b.x) / 2, (a.y + b.y) / 2);\n const scale = g.startView.scale * (Math.hypot(a.x - b.x, a.y - b.y) / g.startDist);\n const z = zoomAround(g.startView, Math.max(scale, MIN_SCALE), g.startMid, baseSize(), stageSize());\n applyView({ scale: z.scale, x: z.x + mid.x - g.startMid.x, y: z.y + mid.y - g.startMid.y });\n };\n\n const trackDrag = (g: Gesture, event: React.PointerEvent) => {\n const dt = event.timeStamp - g.lastT;\n if (dt > 0) {\n g.vx = (event.clientX - g.lastX) / dt;\n g.vy = (event.clientY - g.lastY) / dt;\n }\n g.lastX = event.clientX;\n g.lastY = event.clientY;\n g.lastT = event.timeStamp;\n g.dx = event.clientX - g.startX;\n g.dy = event.clientY - g.startY;\n };\n\n const onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n const g = gesture.current;\n if (!g || !pointers.current.has(event.pointerId)) return;\n pointers.current.set(event.pointerId, { x: event.clientX, y: event.clientY });\n if (g.kind === \"pinch\") {\n movePinch(g);\n return;\n }\n trackDrag(g, event);\n\n if (g.kind === \"pending\") {\n const intent = dragIntent(g.dx, g.dy);\n if (!intent) return;\n g.kind = intent;\n try {\n stageRef.current?.setPointerCapture(event.pointerId);\n } catch {\n /* sentetik olaylarda pointer yakalanamayabilir */\n }\n }\n if (g.kind === \"swipe\") {\n const atEdge = (indexRef.current === 0 && g.dx > 0) || (indexRef.current === count - 1 && g.dx < 0);\n setTrack(atEdge ? g.dx * 0.35 : g.dx);\n } else if (g.kind === \"dismiss\") {\n setDismiss(g.dx, g.dy);\n } else if (g.kind === \"pan\") {\n applyView({ scale: g.startView.scale, x: g.startView.x + g.dx, y: g.startView.y + g.dy });\n }\n };\n\n const endPinch = (g: Gesture, timeStamp: number) => {\n const rest = Array.from(pointers.current.values())[0];\n if (rest) {\n // Bir parmak kaldı: kaydırmaya geç.\n gesture.current = { ...startSingle(rest.x, rest.y, timeStamp, g.pointerType), kind: \"pan\" };\n return;\n }\n gesture.current = null;\n const v = view.current;\n applyView(v.scale < 1.05 ? IDENTITY : clampPan(v, baseSize(), stageSize()), SETTLE_MS);\n };\n\n const endSwipe = (g: Gesture, stage: Size) => {\n const dir = swipeOutcome(g.dx, g.vx, stage.width);\n const target = indexRef.current + dir;\n if (dir !== 0 && target >= 0 && target < count) go(dir);\n else setTrack(0, SETTLE_MS);\n };\n\n const endDismiss = (g: Gesture, stage: Size) => {\n if (shouldDismiss(g.dy, g.vy, stage.height)) onClose();\n else setDismiss(0, 0, SETTLE_MS);\n };\n\n const onPointerEnd = (event: React.PointerEvent<HTMLDivElement>) => {\n const g = gesture.current;\n if (!pointers.current.delete(event.pointerId) || !g) return;\n if (g.kind === \"pinch\") {\n endPinch(g, event.timeStamp);\n return;\n }\n if (pointers.current.size > 0) return;\n gesture.current = null;\n const stage = stageSize();\n if (g.kind === \"pending\" && event.type === \"pointerup\") handleTap(event);\n else if (g.kind === \"swipe\") endSwipe(g, stage);\n else if (g.kind === \"dismiss\") endDismiss(g, stage);\n else if (g.kind === \"pan\") applyView(clampPan(view.current, baseSize(), stage), SETTLE_MS);\n };\n\n const zoomBy = (factor: number) => applyView(zoomAround(view.current, view.current.scale * factor, { x: 0, y: 0 }, baseSize(), stageSize()), SETTLE_MS);\n\n const onKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n if (target.closest(\"video, input, textarea, select\")) return;\n const keys: Record<string, () => void> = {\n ArrowLeft: () => go(-1),\n ArrowRight: () => go(1),\n \"+\": () => zoomBy(ZOOM_STEP),\n \"=\": () => zoomBy(ZOOM_STEP),\n \"-\": () => zoomBy(1 / ZOOM_STEP),\n \"0\": () => applyView(IDENTITY, SETTLE_MS),\n };\n const action = keys[event.key];\n if (!action || (isVideo && event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\")) return;\n event.preventDefault();\n action();\n };\n\n const keyHandler = useRef(onKeyDown);\n keyHandler.current = onKeyDown;\n useEffect(() => {\n const panel = panelRef.current;\n if (!present || !panel) return;\n const listener = (event: KeyboardEvent) => keyHandler.current(event);\n panel.addEventListener(\"keydown\", listener);\n return () => panel.removeEventListener(\"keydown\", listener);\n }, [present]);\n\n if (!present || typeof document === \"undefined\" || !item) return null;\n\n const chromeClass = cn(\n \"absolute inset-x-0 z-10 bg-mari-surface/80 backdrop-blur-md transition-opacity duration-200 motion-reduce:transition-none\",\n chrome && open ? \"opacity-100\" : \"pointer-events-none opacity-0\"\n );\n\n return createPortal(\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={ariaLabel}\n tabIndex={-1}\n onFocus={() => setChrome(true)}\n className={cn(\"fixed inset-0 z-mari-modal text-mari-foreground outline-none\", !open && \"pointer-events-none\")}\n >\n <div ref={backdropRef} className=\"absolute inset-0 bg-mari-surface\" />\n\n <div\n ref={stageRef}\n data-viewer-stage=\"\"\n className={cn(\"absolute inset-0 touch-none overflow-hidden select-none\", zoomed ? \"cursor-grab active:cursor-grabbing\" : \"cursor-zoom-in\", isVideo && \"cursor-auto\")}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerEnd}\n onPointerCancel={onPointerEnd}\n >\n <div ref={trackRef} className=\"absolute inset-0\">\n {visibleSlides(index, count).map((i) => (\n <ViewerSlide key={items[i]!.key} item={items[i]!} offset={i - index} loader={loader} />\n ))}\n </div>\n </div>\n\n <div className={cn(chromeClass, \"top-0 flex items-center gap-1 px-2 pt-[max(0.5rem,env(safe-area-inset-top))] pb-2\")}>\n <Button data-viewer-close variant=\"ghost\" color=\"neutral\" shape=\"circle\" icon={<XIcon />} aria-label=\"Kapat\" onClick={onClose} />\n <p className=\"min-w-0 flex-1 truncate text-center text-sm font-medium tabular-nums\">\n {count > 1 ? `${index + 1} / ${count}` : item.alt}\n </p>\n {actions?.(item, index)}\n {!isVideo && (\n <>\n <Button\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n icon={<ZoomOutIcon />}\n aria-label=\"Uzaklaştır\"\n disabled={zoomLevel === \"min\"}\n onClick={() => zoomBy(1 / ZOOM_STEP)}\n className=\"pointer-coarse:hidden\"\n />\n <Button\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n icon={<ZoomInIcon />}\n aria-label=\"Yakınlaştır\"\n disabled={zoomLevel === \"max\"}\n onClick={() => zoomBy(ZOOM_STEP)}\n className=\"pointer-coarse:hidden\"\n />\n </>\n )}\n </div>\n\n {count > 1 && (\n <>\n {index > 0 && (\n <Button\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n size=\"lg\"\n icon={<ChevronLeftIcon />}\n aria-label=\"Önceki\"\n onClick={() => go(-1)}\n className={cn(chromeClass, \"inset-x-auto top-1/2 left-3 hidden -translate-y-1/2 sm:inline-flex pointer-coarse:hidden\")}\n />\n )}\n {index < count - 1 && (\n <Button\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n size=\"lg\"\n icon={<ChevronRightIcon />}\n aria-label=\"Sonraki\"\n onClick={() => go(1)}\n className={cn(chromeClass, \"inset-x-auto top-1/2 right-3 hidden -translate-y-1/2 sm:inline-flex pointer-coarse:hidden\")}\n />\n )}\n </>\n )}\n\n {(item.caption || showStrip) && (\n <div className={cn(chromeClass, \"bottom-0 flex flex-col gap-2 pt-2 pb-[max(0.5rem,env(safe-area-inset-bottom))]\")}>\n {item.caption && <div className=\"px-4 text-center text-sm\">{item.caption}</div>}\n {showStrip && (\n <div ref={stripRef} role=\"group\" aria-label=\"Küçük resimler\" className=\"flex items-center gap-0.5 overflow-x-auto px-[50%] [scrollbar-width:none]\">\n {items.map((it, i) => {\n const current = i === index;\n const src = viewerThumbnail(it, loader, 96);\n return (\n <button\n key={it.key}\n type=\"button\"\n aria-label={it.alt || `Öğe ${i + 1}`}\n aria-current={current ? \"true\" : undefined}\n onClick={() => setIndex(i)}\n className={cn(\n \"relative h-11 shrink-0 overflow-hidden bg-mari-surface-alt transition-[width,margin] duration-200 motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-mari-ring\",\n current ? \"mx-1.5 w-11 rounded-sm\" : \"w-7\"\n )}\n >\n {src && <img src={src} alt=\"\" draggable={false} loading=\"lazy\" className=\"size-full object-cover\" />}\n </button>\n );\n })}\n </div>\n )}\n </div>\n )}\n\n <p className=\"sr-only\" aria-live=\"polite\">\n {count > 1 ? `${item.alt}, ${index + 1} / ${count}` : item.alt}\n </p>\n </div>,\n document.body\n );\n}\n","import type React from \"react\";\nimport type { ImageLoader, ImageSource, ImageStaticSource } from \"./types\";\n\n/** `srcSet` için varsayılan aday genişlikler (yaygın cihaz genişlikleri). */\nexport const DEFAULT_WIDTHS = [384, 640, 828, 1080, 1280, 1920, 2560];\n/** Bulanık ön izleme için `loader`dan istenen küçük boy. */\nexport const BLUR_WIDTH = 24;\n\nexport function normalizeSource(src: ImageSource | null | undefined): ImageStaticSource | null {\n if (src == null) return null;\n if (typeof src === \"string\") return src === \"\" ? null : { src };\n return src.src ? src : null;\n}\n\nexport interface ResolvedImage {\n src: string;\n srcSet?: string;\n}\n\n/**\n * Asıl `<img>` adresleri.\n * - `loader` yoksa: kaynak olduğu gibi, `srcSet` yok.\n * - Sayısal `width` varsa: 1x/2x yoğunluk adayları (sabit boyutlu görsel).\n * - Yoksa: `widths` genişlik adayları (`sizes` ile duyarlı görsel).\n */\nexport function resolveImage(\n source: ImageStaticSource,\n { loader, width, widths = DEFAULT_WIDTHS, quality }: { loader?: ImageLoader; width?: number | string; widths?: number[]; quality?: number }\n): ResolvedImage {\n if (!loader) return { src: source.src };\n const call = (w: number) => loader({ src: source.src, width: w, quality });\n if (typeof width === \"number\") {\n return { src: call(width), srcSet: `${call(width)} 1x, ${call(width * 2)} 2x` };\n }\n const sorted = [...new Set(widths)].sort((a, b) => a - b);\n const largest = sorted[sorted.length - 1] ?? 1080;\n return { src: call(largest), srcSet: sorted.map((w) => `${call(w)} ${w}w`).join(\", \") };\n}\n\n/** `placeholder` → bulanık ön izleme URL'si (yoksa `null`: parıltı ya da özel node). */\nexport function resolveBlurSource(\n placeholder: unknown,\n source: ImageStaticSource,\n loader: ImageLoader | undefined\n): string | null {\n if (typeof placeholder === \"string\") return placeholder;\n if (placeholder !== true) return null;\n if (source.blurDataURL) return source.blurDataURL;\n if (loader) return loader({ src: source.src, width: BLUR_WIDTH, quality: 30 });\n return null;\n}\n\nfunction toCssLength(value: number | string | undefined): string | undefined {\n if (value === undefined) return undefined;\n return typeof value === \"number\" ? `${value}px` : value;\n}\n\nfunction toAspectRatio(value: number | string | undefined): string | undefined {\n if (value === undefined) return undefined;\n return String(value);\n}\n\n/**\n * Dış kutunun boyutu. Öncelik: açık `aspectRatio` → sayısal `width`/`height` oranı\n * → statik kaynağın kendi boyutu. Oran varsa ve yalnız biri verilmişse diğeri\n * orandan gelir; hiç boyut yoksa kutu kabın genişliğini alır.\n */\nexport function getBoxStyle({\n width,\n height,\n aspectRatio,\n source,\n}: {\n width?: number | string;\n height?: number | string;\n aspectRatio?: number | string;\n source?: ImageStaticSource | null;\n}): React.CSSProperties {\n let ratio = toAspectRatio(aspectRatio);\n if (!ratio && typeof width === \"number\" && typeof height === \"number\") ratio = `${width} / ${height}`;\n if (!ratio && width === undefined && height === undefined && source?.width && source.height) {\n ratio = `${source.width} / ${source.height}`;\n }\n const style: React.CSSProperties = {};\n const w = toCssLength(width);\n const h = toCssLength(height);\n if (w) style.width = w;\n if (h && !(ratio && w)) style.height = h;\n if (ratio) {\n style.aspectRatio = ratio;\n if (!w && !h) style.width = \"100%\";\n }\n return style;\n}\n\n/** `<img>`ye gidecek boyut/öncelik öznitelikleri (tarayıcı oranı önceden bilsin, LCP görseli öne alınsın). */\nexport function imgAttributes({\n width,\n height,\n source,\n srcSet,\n sizes,\n priority,\n loading,\n fetchPriority,\n}: {\n width?: number | string;\n height?: number | string;\n source: ImageStaticSource | null;\n srcSet?: string;\n sizes?: string;\n priority: boolean;\n loading: \"lazy\" | \"eager\";\n fetchPriority?: \"high\" | \"low\" | \"auto\";\n}) {\n const fixedWidth = typeof width === \"number\";\n const lazy = loading === \"lazy\" && !priority;\n // `auto`: lazy görselde tarayıcı gerçek kutu genişliğine göre seçer (desteklemeyen 100vw'ye düşer).\n const defaultSizes = lazy ? \"auto, 100vw\" : \"100vw\";\n return {\n width: fixedWidth ? width : source?.width,\n height: typeof height === \"number\" ? height : source?.height,\n sizes: sizes ?? (srcSet && !fixedWidth ? defaultSizes : undefined),\n loading: lazy ? loading : (\"eager\" as const),\n fetchPriority: priority ? (\"high\" as const) : fetchPriority,\n };\n}\n","/**\n * Görüntüleyicinin (ImageViewer) saf jest/geometri mantığı — DOM'suz, ayrıca test edilir.\n * Koordinatlar sahnenin (stage) MERKEZİNE göredir; görsel ölçek 1'de sahneye\n * `contain` ile sığdırılmış boyuttadır (`base`).\n */\n\nexport const MIN_SCALE = 1;\nexport const MAX_SCALE = 4;\n/** Çift dokunuş / çift tıklama yakınlaştırması. */\nexport const DOUBLE_TAP_SCALE = 2.5;\n\nexport interface ViewState {\n scale: number;\n x: number;\n y: number;\n}\n\nexport interface Size {\n width: number;\n height: number;\n}\n\nexport const IDENTITY: ViewState = { scale: 1, x: 0, y: 0 };\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\n/** Görsel sahneden büyükse taşan kadar kaydırılabilir; küçükse ortada kalır. */\nexport function clampPan(view: ViewState, base: Size, stage: Size): ViewState {\n const maxX = Math.max(0, (base.width * view.scale - stage.width) / 2);\n const maxY = Math.max(0, (base.height * view.scale - stage.height) / 2);\n // `|| 0`: -0 yerine 0 (sınır 0 iken Math.max(-0, negatif) = -0).\n return { scale: view.scale, x: clamp(view.x, -maxX, maxX) || 0, y: clamp(view.y, -maxY, maxY) || 0 };\n}\n\n/**\n * `point` (sahne merkezine göre) sabit kalacak şekilde yeni ölçeğe geç —\n * imlecin/parmakların altındaki nokta yerinden oynamaz.\n */\nexport function zoomAround(view: ViewState, nextScale: number, point: { x: number; y: number }, base: Size, stage: Size): ViewState {\n const scale = clamp(nextScale, MIN_SCALE, MAX_SCALE);\n const ratio = scale / view.scale;\n const next = { scale, x: point.x - (point.x - view.x) * ratio, y: point.y - (point.y - view.y) * ratio };\n return scale === MIN_SCALE ? IDENTITY : clampPan(next, base, stage);\n}\n\n/** Çift dokunuş: yakın değilse noktaya yakınlaş, yakınsa sıfırla. */\nexport function toggleZoom(view: ViewState, point: { x: number; y: number }, base: Size, stage: Size): ViewState {\n return view.scale > MIN_SCALE ? IDENTITY : zoomAround(view, DOUBLE_TAP_SCALE, point, base, stage);\n}\n\n/** Sürükleme bırakılınca: -1 önceki, 1 sonraki, 0 yerine dön. Hız px/ms. */\nexport function swipeOutcome(dx: number, velocityX: number, stageWidth: number): -1 | 0 | 1 {\n const far = Math.abs(dx) > stageWidth * 0.25;\n const fast = Math.abs(velocityX) > 0.5 && Math.abs(dx) > 20;\n if (!far && !fast) return 0;\n return dx < 0 ? 1 : -1;\n}\n\n/** Aşağı çekerek kapatma: 0..1 ilerleme (arka plan saydamlaşır, görsel küçülür). */\nexport function dismissProgress(dy: number, stageHeight: number): number {\n return clamp(dy / (stageHeight * 0.5), 0, 1);\n}\n\nexport function shouldDismiss(dy: number, velocityY: number, stageHeight: number): boolean {\n return dy > stageHeight * 0.18 || (velocityY > 0.5 && dy > 30);\n}\n\n/**\n * İlk sürükleme yönü: yatay → kaydırma, aşağı → kapatma, belirsiz → bekle.\n * Yakınken her yön kaydırmadır (pan).\n */\nexport function dragIntent(dx: number, dy: number): \"swipe\" | \"dismiss\" | null {\n if (Math.hypot(dx, dy) < 8) return null;\n if (Math.abs(dx) > Math.abs(dy)) return \"swipe\";\n return dy > 0 ? \"dismiss\" : \"swipe\";\n}\n\nexport interface RectLike {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/**\n * Küçük resimden büyüyerek açılış (FLIP): hedef kutudaki görseli, kaynak\n * kutunun yerine ve boyutuna götüren dönüşüm. Küçük resim kare kırpılmış\n * olabilir — ölçek, kaynağı KAPLAYACAK (cover) şekilde seçilir.\n */\nexport function originTransform(from: RectLike, to: RectLike): { x: number; y: number; scale: number } {\n if (to.width === 0 || to.height === 0) return { x: 0, y: 0, scale: 1 };\n const scale = Math.max(from.width / to.width, from.height / to.height);\n return {\n x: from.left + from.width / 2 - (to.left + to.width / 2),\n y: from.top + from.height / 2 - (to.top + to.height / 2),\n scale,\n };\n}\n\n/** Görüntülenecek komşu dilimler (önceki, şimdiki, sonraki). */\nexport function visibleSlides(index: number, count: number): number[] {\n return [index - 1, index, index + 1].filter((i) => i >= 0 && i < count);\n}\n\n/** Doğal boyuttaki görselin sahneye `contain` ile sığmış boyutu (büyütmeden). */\nexport function containSize(natural: Size, stage: Size, upscale = true): Size {\n if (natural.width === 0 || natural.height === 0) return stage;\n let ratio = Math.min(stage.width / natural.width, stage.height / natural.height);\n if (!upscale) ratio = Math.min(1, ratio);\n return { width: natural.width * ratio, height: natural.height * ratio };\n}\n","\"use client\";\n\nimport React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { CheckIcon, PlayIcon, ZoomInIcon, ZoomOutIcon } from \"lucide-react\";\nimport { cn, useControllableState } from \"@mari-ui/core\";\nimport { Button } from \"../button\";\nimport { Segmented } from \"../segmented\";\nimport { InfiniteScrollFooter, type InfiniteScrollOptions } from \"../lib/infiniteScroll\";\nimport { skeletonBoxProps, type SkeletonableProps } from \"../lib/skeleton\";\nimport { Image } from \"./Image\";\nimport { ImageViewer, type ImageViewerItem, type ImageViewerProps } from \"./ImageViewer\";\nimport type { ImageLoader, ImageSource } from \"./types\";\nimport {\n DRILL_DOWN,\n drillDownTarget,\n MAX_COLUMNS,\n MIN_COLUMNS,\n autoColumns,\n buildLayout,\n clampColumns,\n formatDuration,\n gridKeyIntent,\n groupItems,\n rangeIndexes,\n renderedRows,\n sectionLabel,\n visibleRows,\n type GalleryLayout,\n type GalleryView,\n} from \"./galleryUtils\";\n\nexport type { GalleryView };\n\nexport interface ImageGalleryItem {\n key: React.Key;\n /** Tam çözünürlüklü kaynak (video için video adresi). */\n src: ImageSource;\n alt: string;\n /** Çekim tarihi — bölümler buna göre. Hiçbir öğede yoksa galeri tek düz ızgaradır. */\n date?: Date | null;\n /** Varsayılan: `\"image\"`. */\n type?: \"image\" | \"video\";\n /** Video kapak görseli (ızgarada ve görüntüleyicide) — hazır adres, `loader`dan geçmez. */\n poster?: string;\n /** Video süresi (sn) — küçük resmin köşesinde. */\n duration?: number;\n /** Izgarada `src` yerine gösterilecek küçük kaynak (CDN `loader`ı yoksa önerilir). */\n thumbnail?: ImageSource;\n caption?: React.ReactNode;\n tracks?: Exclude<ImageViewerItem[\"tracks\"], undefined>;\n}\n\nexport interface ImageGalleryProps extends SkeletonableProps {\n items: ImageGalleryItem[];\n /** Bölümleme: `day` / `month` / `year` başlıklı, `all` başlıksız tek ızgara. Varsayılan: `\"day\"`. */\n view?: GalleryView;\n defaultView?: GalleryView;\n onViewChange?: (view: GalleryView) => void;\n /** Araç çubuğundaki görünüm seçenekleri (sırasıyla). Varsayılan: Yıllar, Aylar, Günler, Tümü. */\n views?: GalleryView[];\n /** Sütun sayısı. `\"auto\"`: genişlik ve görünüme göre (gün iri, yıl sık). Varsayılan: `\"auto\"`. */\n columns?: number | \"auto\";\n defaultColumns?: number | \"auto\";\n onColumnsChange?: (columns: number | \"auto\") => void;\n /** Küçük resimler arası boşluk (px, kıl payı). Varsayılan: `2`. */\n gap?: number;\n loader?: ImageLoader;\n /** Araç çubuğu (görünüm, sütun, seçim). Varsayılan: `true`. */\n toolbar?: boolean;\n /** Araç çubuğunun solundaki başlık. */\n title?: React.ReactNode;\n /** Bölüm başlıklarının düzeyi. Varsayılan: `3`. */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** Sona yaklaşınca sonraki sayfayı ister (sanallaştırmayla birlikte çalışır). */\n infinite?: InfiniteScrollOptions;\n /** Araç çubuğunda \"Seç\" düğmesi; dokunmatikte uzun basış da seçim moduna alır. */\n selectable?: boolean;\n selectionMode?: boolean;\n defaultSelectionMode?: boolean;\n onSelectionModeChange?: (active: boolean) => void;\n selectedKeys?: React.Key[];\n defaultSelectedKeys?: React.Key[];\n onSelectionChange?: (keys: React.Key[]) => void;\n /** Seçim modunda araç çubuğuna eklenecek eylemler (paylaş, sil…). */\n selectionActions?: (keys: React.Key[]) => React.ReactNode;\n /** Görüntüleyicinin üst çubuğuna ek eylemler. */\n viewerActions?: Exclude<ImageViewerProps[\"actions\"], undefined>;\n /** Tarih biçimi. Varsayılan: `\"tr-TR\"`. */\n locale?: string;\n /** Öğe yokken. Varsayılan: \"Henüz fotoğraf yok\". */\n emptyText?: React.ReactNode;\n \"aria-label\"?: string;\n className?: string;\n}\n\nconst VIEW_LABEL: Record<GalleryView, string> = { year: \"Yıllar\", month: \"Aylar\", day: \"Günler\", all: \"Tümü\" };\nconst DEFAULT_VIEWS: GalleryView[] = [\"year\", \"month\", \"day\", \"all\"];\nconst TILE_WIDTHS = [96, 160, 256, 384, 640];\nconst HEADER_REM = 2.75;\nconst LONG_PRESS_MS = 500;\nconst SKELETON_ROWS = 4;\n\nconst useIsomorphicLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\nfunction scrollParent(el: HTMLElement): HTMLElement | null {\n for (let p = el.parentElement; p && p !== document.body; p = p.parentElement) {\n if (/(auto|scroll|overlay)/.test(getComputedStyle(p).overflowY)) return p;\n }\n return null;\n}\n\n/** Galerinin görünen dikey aralığı (galeriye göre px): kaydırma atası ve pencere ile kesişim. */\nfunction viewportOf(el: HTMLElement, scroller: HTMLElement | null): [number, number] {\n const rect = el.getBoundingClientRect();\n let top = 0;\n let bottom = window.innerHeight;\n if (scroller) {\n const s = scroller.getBoundingClientRect();\n top = Math.max(top, s.top);\n bottom = Math.min(bottom, s.bottom);\n }\n return [top - rect.top, bottom - rect.top];\n}\n\nfunction remToPx(rem: number): number {\n if (typeof window === \"undefined\") return rem * 16;\n return rem * (parseFloat(getComputedStyle(document.documentElement).fontSize) || 16);\n}\n\n/** Öğenin genişliği (ResizeObserver). `active` değişince (öğe DOM'a girince) yeniden bağlanır. */\nfunction useWidth(ref: React.RefObject<HTMLElement | null>, active: boolean): number {\n const [width, setWidth] = useState(0);\n useIsomorphicLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n setWidth(el.clientWidth);\n if (typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => setWidth(el.clientWidth));\n ro.observe(el);\n return () => ro.disconnect();\n }, [ref, active]);\n return width;\n}\n\n/**\n * Sanal ızgara: görünen aralık (sayfa ya da iç kaydırma alanı) kaydırma\n * olaylarıyla izlenir; yalnız görünen satırlar (+ birkaç yedek) render edilir.\n */\nfunction useVisibleRows(gridRef: React.RefObject<HTMLDivElement | null>, layout: GalleryLayout, active: boolean) {\n const [range, setRange] = useState<[number, number]>([0, 20]);\n const layoutRef = useRef(layout);\n layoutRef.current = layout;\n const viewportHeight = useRef(0);\n const update = useRef<() => void>(() => {});\n\n useIsomorphicLayoutEffect(() => {\n const el = gridRef.current;\n if (!el) return;\n const scroller = scrollParent(el);\n let frame = 0;\n update.current = () => {\n const [top, bottom] = viewportOf(el, scroller);\n viewportHeight.current = bottom - top;\n const next = visibleRows(layoutRef.current.rows, top, bottom);\n setRange((prev) => (prev[0] === next[0] && prev[1] === next[1] ? prev : next));\n };\n const onScroll = () => {\n if (frame) return;\n frame = requestAnimationFrame(() => {\n frame = 0;\n update.current();\n });\n };\n // Yakalama aşaması: hangi ata kaydırırsa kaydırsın haber alınır.\n window.addEventListener(\"scroll\", onScroll, { capture: true, passive: true });\n window.addEventListener(\"resize\", onScroll);\n return () => {\n cancelAnimationFrame(frame);\n update.current = () => {};\n window.removeEventListener(\"scroll\", onScroll, { capture: true });\n window.removeEventListener(\"resize\", onScroll);\n };\n }, [gridRef, active]);\n\n // Yerleşim değişince (genişlik, sütun, görünüm, yeni sayfa) aralığı yeniden hesapla.\n useIsomorphicLayoutEffect(() => update.current(), [layout, active]);\n\n return { range, viewportHeight };\n}\n\nfunction GalleryTile({\n item,\n index,\n active,\n selecting,\n selected,\n loader,\n cell,\n onActivate,\n onLongPress,\n onKeyDown,\n}: Readonly<{\n item: ImageGalleryItem;\n index: number;\n active: boolean;\n selecting: boolean;\n selected: boolean;\n loader?: ImageLoader;\n cell: number;\n onActivate: (index: number, event: React.MouseEvent | React.KeyboardEvent) => void;\n onLongPress: (index: number) => void;\n onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void;\n}>) {\n const press = useRef<{ timer: ReturnType<typeof setTimeout>; x: number; y: number; fired: boolean } | null>(null);\n const isVideo = item.type === \"video\";\n // Kapak görseli görüntüleyicideki gibi hazır bir adres: `loader`dan geçmez.\n const thumb = isVideo ? (item.poster ?? null) : (item.thumbnail ?? item.src);\n const thumbLoader = isVideo ? undefined : loader;\n\n const cancelPress = () => {\n const p = press.current;\n if (!p) return;\n clearTimeout(p.timer);\n // Uzun basış gerçekleştiyse bayrak, ardından gelen tıklamayı yutmak için kalır.\n if (!p.fired) press.current = null;\n };\n useEffect(() => cancelPress, []);\n\n return (\n <div\n role=\"gridcell\"\n tabIndex={active ? 0 : -1}\n data-index={index}\n aria-selected={selecting ? selected : undefined}\n onKeyDown={onKeyDown}\n onClick={(event) => {\n // Uzun basış seçimi zaten yaptı; ardından gelen tıklama geri almasın.\n if (press.current?.fired) {\n press.current = null;\n return;\n }\n onActivate(index, event);\n }}\n onPointerDown={(event) => {\n if (event.pointerType !== \"touch\" || selecting) return;\n cancelPress();\n const { clientX: x, clientY: y } = event;\n const timer = setTimeout(() => {\n if (press.current) press.current.fired = true;\n onLongPress(index);\n }, LONG_PRESS_MS);\n press.current = { timer, x, y, fired: false };\n }}\n onPointerMove={(event) => {\n const p = press.current;\n if (p && !p.fired && Math.hypot(event.clientX - p.x, event.clientY - p.y) > 10) cancelPress();\n }}\n onPointerUp={cancelPress}\n onPointerCancel={cancelPress}\n onContextMenu={(event) => {\n // Uzun basışta tarayıcının \"görseli kaydet\" menüsü açılmasın.\n if (press.current) event.preventDefault();\n }}\n className={cn(\n \"relative block size-full cursor-pointer overflow-hidden bg-mari-surface-alt outline-none select-none [-webkit-touch-callout:none]\",\n // Halka görselin üstünde kalsın: inset gölge içeriğin altında boyanır → ::after katmanı.\n \"scroll-mt-14 after:pointer-events-none after:absolute after:inset-0 after:content-[''] focus-visible:after:ring-2 focus-visible:after:ring-mari-ring focus-visible:after:ring-inset\"\n )}\n >\n <Image\n src={thumb}\n alt={item.alt}\n loader={thumbLoader}\n widths={TILE_WIDTHS}\n sizes={`${Math.max(1, Math.ceil(cell))}px`}\n draggable={false}\n wrapperClassName={cn(\n \"block size-full rounded-none transition-[transform,opacity] duration-150 motion-reduce:transition-none\",\n selected && \"opacity-70\"\n )}\n />\n {isVideo && (\n // Fotoğrafa bağlı, temadan bağımsız (native VIDEO_BADGE_BG ile aynı): açık temanın\n // yarı saydam scrim'i açık karede beyaz metni AA'nın altına düşürüyordu.\n <span className=\"pointer-events-none absolute right-1 bottom-1 inline-flex items-center gap-0.5 rounded-sm bg-black/72 px-1 text-xs font-medium text-white tabular-nums\">\n <PlayIcon aria-hidden className=\"size-3 fill-current\" />\n {item.duration !== undefined ? formatDuration(item.duration) : <span className=\"sr-only\">Video</span>}\n {item.duration !== undefined && <span className=\"sr-only\">, video</span>}\n </span>\n )}\n {selecting && (\n <span\n aria-hidden\n className={cn(\n \"pointer-events-none absolute right-1.5 bottom-1.5 flex size-5 items-center justify-center rounded-full border-2 border-white\",\n selected ? \"bg-mari-primary-solid text-mari-primary-solid-contrast\" : \"bg-mari-scrim\",\n isVideo && \"bottom-6\"\n )}\n >\n {selected && <CheckIcon className=\"size-3\" strokeWidth={3} />}\n </span>\n )}\n </div>\n );\n}\n\n/**\n * Görünüm değişince (yıl → ay → gün) bir öğenin bölüm başlığını araç\n * çubuğunun hemen altına kaydırır. Yeni yerleşim hesaplandıktan sonra çalışır.\n */\nfunction useSectionScroll(\n gridRef: React.RefObject<HTMLDivElement | null>,\n toolbarRef: React.RefObject<HTMLDivElement | null>,\n layout: GalleryLayout,\n width: number\n) {\n const pending = useRef<number | null>(null);\n useIsomorphicLayoutEffect(() => {\n const el = gridRef.current;\n const index = pending.current;\n const row = index === null ? undefined : layout.rowOf[index];\n if (!el || !width || row === undefined) return;\n pending.current = null;\n const header = layout.rows[row - 1];\n const top = header?.kind === \"header\" ? header.top : layout.rows[row]!.top;\n const scroller = scrollParent(el);\n const [viewTop] = viewportOf(el, scroller);\n const delta = top - viewTop - (toolbarRef.current?.offsetHeight ?? 0);\n // jsdom'da `scrollBy` yok.\n (scroller ?? window).scrollBy?.({ top: delta });\n }, [layout, width]);\n return (index: number) => {\n pending.current = index;\n };\n}\n\n/** Seçim modu + seçili anahtarlar (kontrollü/kontrolsüz) ve Shift aralığının çapası. */\nfunction useGallerySelection(\n flat: readonly ImageGalleryItem[],\n opts: {\n value?: React.Key[];\n defaultValue: React.Key[];\n onChange?: (keys: React.Key[]) => void;\n mode?: boolean;\n defaultMode: boolean;\n onModeChange?: (active: boolean) => void;\n }\n) {\n const [selecting = false, setSelecting] = useControllableState({ value: opts.mode, defaultValue: opts.defaultMode, onChange: opts.onModeChange });\n const [keys = [], setKeysState] = useControllableState({ value: opts.value, defaultValue: opts.defaultValue, onChange: opts.onChange });\n // Render beklemeden art arda gelen güncellemeler (hızlı tıklama) birbirini ezmesin.\n const latest = useRef(keys);\n latest.current = keys;\n const setKeys = (next: React.Key[]) => {\n latest.current = next;\n setKeysState(next);\n };\n const set = useMemo(() => new Set(keys), [keys]);\n const anchor = useRef<number | null>(null);\n\n const addRange = (to: number) => {\n if (anchor.current === null) return;\n const added = rangeIndexes(anchor.current, to).map((i) => flat[i]!.key);\n setKeys([...new Set([...latest.current, ...added])]);\n };\n\n const exit = () => {\n setSelecting(false);\n if (keys.length) setKeys([]);\n anchor.current = null;\n };\n\n const selectAll = () => setKeys(flat.map((i) => i.key));\n\n return {\n selecting,\n keys,\n has: (key: React.Key) => set.has(key),\n enter: () => setSelecting(true),\n exit,\n selectAll,\n /** Tıklama/Space: tek öğeyi aç/kapa; Shift ile çapadan buraya kadar ekle. */\n toggle: (index: number, range: boolean) => {\n const key = flat[index]?.key;\n if (key === undefined) return;\n if (range && anchor.current !== null) {\n addRange(index);\n return;\n }\n const current = latest.current;\n setKeys(current.includes(key) ? current.filter((k) => k !== key) : [...current, key]);\n anchor.current = index;\n },\n /** Shift+ok: çapadan hedefe kadar ekle. */\n extendTo: addRange,\n /** Uzun basış: seçim moduna gir, bu öğeyi seç. */\n startWith: (index: number) => {\n setSelecting(true);\n anchor.current = index;\n const key = flat[index]!.key;\n if (!latest.current.includes(key)) setKeys([...latest.current, key]);\n },\n /** Escape çıkar, Ctrl/⌘+A tümünü seçer. İşlendiyse `true`. */\n shortcut: (event: React.KeyboardEvent) => {\n const all = event.key.toLowerCase() === \"a\" && (event.ctrlKey || event.metaKey);\n if (event.key !== \"Escape\" && !all) return false;\n event.preventDefault();\n if (all) selectAll();\n else exit();\n return true;\n },\n };\n}\n\n/**\n * Fotoğraf/video galerisi. Yapı iPhone Fotoğraflar'dan: kare\n * küçük resimler kıl payı aralıkla, tarihe göre bölümler ve Yıllar / Aylar /\n * Günler / Tümü görünümleri (üst görünümün başlığına tıklayınca bir alta\n * inilir), sütun sayısı değiştirilebilir, seçim modu (uzun basış, Shift ile\n * aralık), tam ekran `ImageViewer` (video dahil). Binlerce öğe için sanal:\n * yalnız görünen satırlar DOM'da; `infinite` ile sonraki sayfalar istenir.\n *\n * Erişilebilirlik: APG `grid` — tek sekme durağı, ok tuşları / Home / End /\n * PageUp / PageDown ile gezinme (sanallaştırmada da: hedef satır render edilip\n * odaklanır), `aria-rowcount`/`aria-rowindex`; seçim modunda\n * `aria-multiselectable` + `aria-selected`.\n */\nexport function ImageGallery({\n items,\n view: viewProp,\n defaultView = \"day\",\n onViewChange,\n views = DEFAULT_VIEWS,\n columns: columnsProp,\n defaultColumns = \"auto\",\n onColumnsChange,\n gap = 2,\n loader,\n toolbar = true,\n title,\n headingLevel = 3,\n infinite,\n selectable = false,\n selectionMode: selectionModeProp,\n defaultSelectionMode = false,\n onSelectionModeChange,\n selectedKeys: selectedKeysProp,\n defaultSelectedKeys = [],\n onSelectionChange,\n selectionActions,\n viewerActions,\n locale = \"tr-TR\",\n emptyText = \"Henüz fotoğraf yok\",\n skeleton = false,\n \"aria-label\": ariaLabel = \"Fotoğraflar\",\n className,\n}: Readonly<ImageGalleryProps>) {\n const [rawView, setViewState] = useControllableState({ value: viewProp, defaultValue: defaultView, onChange: onViewChange });\n const [columnsSetting = \"auto\", setColumns] = useControllableState<number | \"auto\">({\n value: columnsProp,\n defaultValue: defaultColumns,\n onChange: onColumnsChange,\n });\n const hasDates = useMemo(() => items.some((i) => i.date), [items]);\n const view: GalleryView = hasDates ? (rawView ?? \"day\") : \"all\";\n\n const sections = useMemo(() => groupItems(items, view, (i) => i.date), [items, view]);\n const flat = useMemo(() => sections.flatMap((s) => s.entries.map((e) => e.item)), [sections]);\n const count = flat.length;\n const sel = useGallerySelection(flat, {\n value: selectedKeysProp,\n defaultValue: defaultSelectedKeys,\n onChange: onSelectionChange,\n mode: selectionModeProp,\n defaultMode: defaultSelectionMode,\n onModeChange: onSelectionModeChange,\n });\n\n const gridRef = useRef<HTMLDivElement>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n const gridMounted = !skeleton && count > 0;\n const width = useWidth(gridRef, gridMounted);\n const columns = columnsSetting === \"auto\" ? autoColumns(width, view, gap) : clampColumns(columnsSetting);\n const headerHeight = view === \"all\" ? 0 : remToPx(HEADER_REM);\n const layout = useMemo(() => buildLayout(sections, { width, columns, gap, headerHeight }), [sections, width, columns, gap, headerHeight]);\n const virtual = useVisibleRows(gridRef, layout, gridMounted);\n\n const [rawActive, setActive] = useState(0);\n const activeIndex = Math.min(rawActive, Math.max(count - 1, 0));\n const pendingFocus = useRef(false);\n\n const [viewerOpen, setViewerOpen] = useState(false);\n const [viewerIndex, setViewerIndex] = useState(0);\n\n const setView = (next: GalleryView) => {\n setViewState(next);\n // Kendiliğinden sütun sayısı yeni görünüme göre; tüketici kontrol ediyorsa ona kalır.\n if (columnsProp === undefined) setColumns(\"auto\");\n };\n\n const cellOf = (index: number) => gridRef.current?.querySelector<HTMLElement>(`[data-index=\"${index}\"]`) ?? null;\n\n // Odak taşınacaksa: hedef satır bu render'da DOM'a girdi → odakla (tarayıcı görünüme kaydırır).\n useIsomorphicLayoutEffect(() => {\n if (!pendingFocus.current) return;\n pendingFocus.current = false;\n cellOf(activeIndex)?.focus();\n });\n\n const scrollToItemSection = useSectionScroll(gridRef, toolbarRef, layout, width);\n\n const drillDown = (sectionIndex: number) => {\n const target = drillDownTarget(items, sections, view, sectionIndex, (i) => i.date);\n if (!target) return;\n setView(target.view);\n scrollToItemSection(target.index);\n setActive(target.index);\n };\n\n const openViewer = (index: number) => {\n setViewerIndex(index);\n setViewerOpen(true);\n };\n\n const onActivate = (index: number, event: React.MouseEvent | React.KeyboardEvent) => {\n setActive(index);\n if (sel.selecting) sel.toggle(index, event.shiftKey);\n else openViewer(index);\n };\n\n const onLongPress = (index: number) => {\n if (!selectable) return;\n setActive(index);\n sel.startWith(index);\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget || (sel.selecting && sel.shortcut(event))) return;\n const index = Number(event.currentTarget.dataset.index);\n const pageRows = Math.floor(virtual.viewportHeight.current / (layout.cell + gap)) - 1;\n const intent = gridKeyIntent(layout, index, event.key, event.ctrlKey || event.metaKey, pageRows);\n if (intent === null) return;\n event.preventDefault();\n if (intent === \"activate\") {\n onActivate(index, event);\n return;\n }\n if (sel.selecting && event.shiftKey) sel.extendTo(intent);\n pendingFocus.current = true;\n setActive(intent);\n };\n\n const viewerItems = useMemo<ImageViewerItem[]>(\n () =>\n flat.map((i) => ({\n key: i.key,\n src: i.src,\n alt: i.alt,\n caption: i.caption,\n type: i.type,\n poster: i.poster,\n tracks: i.tracks,\n })),\n [flat]\n );\n\n // Görüntüleyicide gezinirken ızgara da izler (kapanınca küçük resme küçülerek dönebilsin).\n useEffect(() => {\n if (!viewerOpen) return;\n cellOf(viewerIndex)?.scrollIntoView?.({ block: \"nearest\" });\n }, [viewerOpen, viewerIndex]);\n\n // Görünür satırlar + odaktaki satır (uzakta olsa da DOM'da kalsın).\n const tileProps = { loader, cell: layout.cell, onActivate, onLongPress, onKeyDown };\n const rowIndexes = renderedRows(virtual.range, layout.rows.length, layout.rowOf[activeIndex]);\n\n if (skeleton) return <GallerySkeleton toolbar={toolbar} columns={columnsSetting} view={view} gap={gap} className={className} />;\n\n return (\n <div className={cn(\"relative\", className)}>\n {toolbar && (\n <GalleryToolbar\n ref={toolbarRef}\n title={title}\n selecting={sel.selecting}\n selectedKeys={sel.keys}\n selectionActions={selectionActions}\n empty={!count}\n selectable={selectable}\n onSelectAll={sel.selectAll}\n onExitSelection={sel.exit}\n onEnterSelection={sel.enter}\n view={view}\n views={hasDates ? views : []}\n onViewChange={setView}\n columns={columns}\n cell={layout.cell}\n onColumnsChange={setColumns}\n />\n )}\n\n {count === 0 ? (\n <div className=\"flex min-h-40 items-center justify-center text-sm text-mari-muted\">{emptyText}</div>\n ) : (\n <div\n ref={gridRef}\n role=\"grid\"\n aria-label={ariaLabel}\n aria-rowcount={layout.rows.length}\n aria-colcount={columns}\n aria-multiselectable={sel.selecting || undefined}\n className=\"relative w-full\"\n style={{ height: layout.height }}\n >\n {rowIndexes.map((r) => {\n const row = layout.rows[r]!;\n const style: React.CSSProperties = { position: \"absolute\", top: row.top, height: row.height, left: 0, right: 0 };\n if (row.kind === \"header\") {\n const section = sections[row.section]!;\n return (\n <SectionHeaderRow\n key={`h-${section.key}`}\n rowIndex={r}\n style={style}\n columns={columns}\n headingLevel={headingLevel}\n label={sectionLabel(section.date, view, locale)}\n count={section.entries.length}\n onDrillDown={DRILL_DOWN[view] ? () => drillDown(row.section) : undefined}\n />\n );\n }\n return (\n <ItemRow\n key={`r-${flat[row.start]!.key}`}\n rowIndex={r}\n style={style}\n columns={columns}\n gap={gap}\n items={flat.slice(row.start, row.end)}\n start={row.start}\n activeIndex={activeIndex}\n selecting={sel.selecting}\n isSelected={sel.has}\n tile={tileProps}\n />\n );\n })}\n </div>\n )}\n\n {infinite && count > 0 && <InfiniteScrollFooter options={infinite} className=\"mt-2\" />}\n\n <ImageViewer\n items={viewerItems}\n open={viewerOpen}\n onClose={() => setViewerOpen(false)}\n index={viewerIndex}\n onIndexChange={(i) => {\n setViewerIndex(i);\n setActive(i);\n }}\n loader={loader}\n actions={viewerActions}\n getOriginElement={cellOf}\n />\n </div>\n );\n}\n\ntype TileShared = Pick<React.ComponentProps<typeof GalleryTile>, \"loader\" | \"cell\" | \"onActivate\" | \"onLongPress\" | \"onKeyDown\">;\n\nfunction ItemRow({\n rowIndex,\n style,\n columns,\n gap,\n items,\n start,\n activeIndex,\n selecting,\n isSelected,\n tile,\n}: Readonly<{\n rowIndex: number;\n style: React.CSSProperties;\n columns: number;\n gap: number;\n items: ImageGalleryItem[];\n start: number;\n activeIndex: number;\n selecting: boolean;\n isSelected: (key: React.Key) => boolean;\n tile: TileShared;\n}>) {\n return (\n <div role=\"row\" aria-rowindex={rowIndex + 1} style={{ ...style, display: \"grid\", gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`, gap }}>\n {items.map((item, k) => (\n <GalleryTile\n key={item.key}\n {...tile}\n item={item}\n index={start + k}\n active={start + k === activeIndex}\n selecting={selecting}\n selected={isSelected(item.key)}\n />\n ))}\n </div>\n );\n}\n\nfunction SectionHeaderRow({\n rowIndex,\n style,\n columns,\n headingLevel,\n label,\n count,\n onDrillDown,\n}: Readonly<{\n rowIndex: number;\n style: React.CSSProperties;\n columns: number;\n headingLevel: number;\n label: string;\n count: number;\n onDrillDown?: () => void;\n}>) {\n const Heading = `h${headingLevel}` as \"h3\";\n return (\n <div role=\"row\" aria-rowindex={rowIndex + 1} style={style} className=\"flex items-end px-1 pb-1.5\">\n <div role=\"gridcell\" aria-colspan={columns} className=\"flex w-full items-baseline gap-2\">\n <Heading className=\"m-0 text-base font-semibold\">\n {onDrillDown ? (\n // Fareyle kısayol; klavyede aynı iş görünüm seçicisiyle.\n <button type=\"button\" tabIndex={-1} onClick={onDrillDown} className=\"cursor-pointer rounded-sm hover:text-mari-primary\">\n {label}\n </button>\n ) : (\n label\n )}\n </Heading>\n <span className=\"text-sm text-mari-muted tabular-nums\">{count} öğe</span>\n </div>\n </div>\n );\n}\n\ninterface GalleryToolbarProps {\n title: React.ReactNode;\n selecting: boolean;\n selectedKeys: React.Key[];\n selectionActions?: (keys: React.Key[]) => React.ReactNode;\n empty: boolean;\n /** `false`sa \"Seç\" düğmesi yok. */\n selectable: boolean;\n onSelectAll: () => void;\n onExitSelection: () => void;\n onEnterSelection: () => void;\n view: GalleryView;\n /** Birden azsa görünüm seçici yok. */\n views: GalleryView[];\n onViewChange: (view: GalleryView) => void;\n columns: number;\n /** Geçerli küçük resim genişliği (px) — çok küçülmesin. */\n cell: number;\n onColumnsChange: (columns: number) => void;\n}\n\n/** Yapışkan üst çubuk: normalde başlık + görünüm + sütun + \"Seç\"; seçim modunda sayı + eylemler. */\nconst GalleryToolbar = React.forwardRef<HTMLDivElement, GalleryToolbarProps>(function GalleryToolbar(\n {\n title,\n selecting,\n selectedKeys,\n selectionActions,\n empty,\n selectable,\n onSelectAll,\n onExitSelection,\n onEnterSelection,\n view,\n views,\n onViewChange,\n columns,\n cell,\n onColumnsChange,\n },\n ref\n) {\n const canZoomOut = columns < MAX_COLUMNS && cell > 40;\n const canZoomIn = columns > MIN_COLUMNS;\n const selectionLabel = selectedKeys.length ? `${selectedKeys.length} öğe seçildi` : \"Öğe seçin\";\n return (\n <div ref={ref} className=\"sticky top-0 z-mari-sticky flex min-h-12 flex-wrap items-center gap-2 bg-mari-surface/85 px-1 py-2 backdrop-blur-md\">\n {/* Seçim modunda sayı kırpılmasın: dar ekranda eylemler alt satıra sarar. */}\n <div\n className={cn(\"text-base font-semibold\", selecting ? \"flex-[1_0_auto]\" : \"min-w-0 flex-1 truncate\")}\n aria-live={selecting ? \"polite\" : undefined}\n >\n {selecting ? selectionLabel : title}\n </div>\n {selecting ? (\n <>\n {selectionActions?.(selectedKeys)}\n <Button size=\"sm\" variant=\"ghost\" color=\"neutral\" onClick={onSelectAll} disabled={empty}>\n Tümünü seç\n </Button>\n <Button size=\"sm\" variant=\"outline\" color=\"neutral\" onClick={onExitSelection}>\n Vazgeç\n </Button>\n </>\n ) : (\n <>\n {views.length > 1 && (\n <Segmented\n size=\"sm\"\n aria-label=\"Görünüm\"\n value={view}\n onChange={(v) => onViewChange(v as GalleryView)}\n options={views.map((v) => ({ value: v, label: VIEW_LABEL[v] }))}\n />\n )}\n <div className=\"flex items-center\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n icon={<ZoomOutIcon />}\n aria-label=\"Küçük resimleri küçült\"\n disabled={!canZoomOut}\n onClick={() => onColumnsChange(columns + 1)}\n />\n <Button\n size=\"sm\"\n variant=\"ghost\"\n color=\"neutral\"\n shape=\"circle\"\n icon={<ZoomInIcon />}\n aria-label=\"Küçük resimleri büyüt\"\n disabled={!canZoomIn}\n onClick={() => onColumnsChange(columns - 1)}\n />\n </div>\n {selectable && (\n <Button size=\"sm\" variant=\"outline\" color=\"neutral\" onClick={onEnterSelection} disabled={empty}>\n Seç\n </Button>\n )}\n </>\n )}\n </div>\n );\n});\n\n/** Yüklü hâliyle aynı ölçü: aynı sütun hesabı (`autoColumns`, ölçülen genişlik), aynı başlık yüksekliği. */\nfunction GallerySkeleton({\n toolbar,\n columns,\n view,\n gap,\n className,\n}: Readonly<{\n toolbar: boolean;\n columns: number | \"auto\";\n view: GalleryView;\n gap: number;\n className?: string;\n}>) {\n const gridRef = useRef<HTMLDivElement>(null);\n const width = useWidth(gridRef, true);\n const cols = columns === \"auto\" ? autoColumns(width, view, gap) : clampColumns(columns);\n const box = skeletonBoxProps();\n return (\n <div aria-hidden aria-busy className={cn(\"relative\", className)}>\n {toolbar && (\n <div className=\"flex min-h-12 items-center gap-2 px-1 py-2\">\n <span {...box} className={cn(box.className, \"h-5 w-32 rounded-sm\")} />\n <span className=\"flex-1\" />\n <span {...box} className={cn(box.className, \"h-6 w-48 rounded-md\")} />\n </div>\n )}\n {view !== \"all\" && (\n <div className=\"flex items-end px-1 pb-1.5\" style={{ height: `${HEADER_REM}rem` }}>\n <span {...box} className={cn(box.className, \"h-4 w-40 rounded-sm\")} />\n </div>\n )}\n <div ref={gridRef} className=\"grid\" style={{ gridTemplateColumns: `repeat(${cols}, minmax(0, 1fr))`, gap }}>\n {Array.from({ length: SKELETON_ROWS * cols }, (_, i) => (\n <span key={i} {...box} className={cn(box.className, \"aspect-square rounded-none\")} />\n ))}\n </div>\n </div>\n );\n}\n","/**\n * ImageGallery'nin saf mantığı: tarihe göre bölümleme, sütun\n * sayısı, sanal yerleşim (satır konumları), görünür aralık ve ızgara tuşları.\n * DOM'a dokunmaz → test edilebilir.\n */\n\nexport type GalleryView = \"all\" | \"day\" | \"month\" | \"year\";\n\nexport interface GalleryEntry<T> {\n item: T;\n /** Bölümlenmiş (düz) sıradaki yeri — görüntüleyici ve seçim bu sırayı kullanır. */\n index: number;\n}\n\nexport interface GallerySection<T> {\n key: string;\n /** Bölümün ilk öğesinin tarihi (başlık için). Tarihsiz bölümde `null`. */\n date: Date | null;\n entries: GalleryEntry<T>[];\n}\n\nexport function sectionKey(date: Date | null | undefined, view: GalleryView): string {\n if (view === \"all\") return \"all\";\n if (!date) return \"none\";\n const y = date.getFullYear();\n if (view === \"year\") return String(y);\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\n if (view === \"month\") return `${y}-${m}`;\n return `${y}-${m}-${String(date.getDate()).padStart(2, \"0\")}`;\n}\n\n/**\n * Öğeleri görünüme göre bölümler. Sıra korunur (tüketici zaten tarihe göre\n * sıralar); aynı anahtara düşen ayrık öğeler ilk görüldükleri bölüme toplanır.\n */\nexport function groupItems<T>(items: readonly T[], view: GalleryView, getDate: (item: T) => Date | null | undefined): GallerySection<T>[] {\n const map = new Map<string, GallerySection<T>>();\n for (const item of items) {\n const date = getDate(item) ?? null;\n const key = sectionKey(date, view);\n let section = map.get(key);\n if (!section) {\n section = { key, date, entries: [] };\n map.set(key, section);\n }\n section.entries.push({ item, index: 0 });\n }\n const sections = Array.from(map.values());\n let i = 0;\n for (const s of sections) for (const e of s.entries) e.index = i++;\n return sections;\n}\n\n/** Görünüme göre hedef küçük resim genişliği (px): gün iri, yıl sık — iPhone gibi. */\nexport const TARGET_TILE: Record<GalleryView, number> = { day: 160, all: 120, month: 100, year: 64 };\nexport const MIN_COLUMNS = 2;\nexport const MAX_COLUMNS = 16;\n\nexport const clampColumns = (n: number) => Math.min(MAX_COLUMNS, Math.max(MIN_COLUMNS, Math.round(n)));\n\nexport function autoColumns(width: number, view: GalleryView, gap: number): number {\n if (width <= 0) return 4;\n return clampColumns(Math.floor((width + gap) / (TARGET_TILE[view] + gap)));\n}\n\nexport type GalleryRow =\n | { kind: \"header\"; section: number; top: number; height: number }\n /** `start`..`end` (dahil değil) düz dizinler. */\n | { kind: \"items\"; section: number; start: number; end: number; top: number; height: number };\n\nexport interface GalleryLayout {\n rows: GalleryRow[];\n height: number;\n cell: number;\n columns: number;\n /** Düz dizin → satır numarası. */\n rowOf: number[];\n}\n\nexport function buildLayout(\n sections: readonly GallerySection<unknown>[],\n { width, columns, gap, headerHeight }: { width: number; columns: number; gap: number; headerHeight: number }\n): GalleryLayout {\n const cell = Math.max(0, (width - gap * (columns - 1)) / columns);\n const rows: GalleryRow[] = [];\n const rowOf: number[] = [];\n let top = 0;\n sections.forEach((section, s) => {\n if (headerHeight > 0) {\n rows.push({ kind: \"header\", section: s, top, height: headerHeight });\n top += headerHeight;\n } else if (s > 0) {\n top += gap;\n }\n const first = section.entries[0]?.index ?? 0;\n for (let k = 0; k < section.entries.length; k += columns) {\n const start = first + k;\n const end = first + Math.min(k + columns, section.entries.length);\n for (let i = start; i < end; i++) rowOf[i] = rows.length;\n rows.push({ kind: \"items\", section: s, start, end, top, height: cell });\n top += cell + (k + columns < section.entries.length ? gap : 0);\n }\n });\n return { rows, height: top, cell, columns, rowOf };\n}\n\n/** `[viewTop, viewBottom]` (galeriye göre px) ile kesişen satırlar + her iki yanda `overscan` satır. */\nexport function visibleRows(rows: readonly GalleryRow[], viewTop: number, viewBottom: number, overscan = 2): [number, number] {\n if (!rows.length || viewBottom <= viewTop) return [0, -1];\n // İlk `top + height > viewTop` satırı (ikili arama).\n let lo = 0;\n let hi = rows.length - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n const r = rows[mid]!;\n if (r.top + r.height > viewTop) hi = mid;\n else lo = mid + 1;\n }\n let last = lo;\n while (last + 1 < rows.length && rows[last + 1]!.top < viewBottom) last++;\n if (rows[lo]!.top >= viewBottom) return [Math.max(0, lo - overscan), Math.min(rows.length - 1, lo + overscan)];\n return [Math.max(0, lo - overscan), Math.min(rows.length - 1, last + overscan)];\n}\n\n/** Render edilecek satırlar: görünen aralık + (dışındaysa) odaktaki satır — odak sanallaştırmada kaybolmasın. */\nexport function renderedRows([first, last]: [number, number], total: number, activeRow: number | undefined): number[] {\n const rows: number[] = [];\n for (let r = first; r <= last && r < total; r++) rows.push(r);\n if (activeRow !== undefined && (activeRow < first || activeRow > last)) rows.push(activeRow);\n return rows;\n}\n\n/**\n * Izgara tuşları → yeni düz dizin. ←/→ sıradaki öğe (bölüm sınırını aşar),\n * ↑/↓ aynı sütun bir üst/alt öğe satırı (bölüm atlanırsa sütun kısalan\n * satıra kırpılır), Home/End satır başı/sonu, Ctrl+Home/End ilk/son,\n * PageUp/PageDown `pageRows` öğe satırı. Uygun değilse `null`.\n */\nexport function galleryKeyStep(layout: GalleryLayout, index: number, key: string, ctrl: boolean, pageRows = 3): number | null {\n const count = layout.rowOf.length;\n if (!count) return null;\n const itemRows = layout.rows.map((r, i) => (r.kind === \"items\" ? i : -1)).filter((i) => i >= 0);\n const rowAt = (n: number) => layout.rows[itemRows[n]!] as Extract<GalleryRow, { kind: \"items\" }>;\n const current = itemRows.indexOf(layout.rowOf[index]!);\n const row = rowAt(current);\n const col = index - row.start;\n const moveRows = (delta: number) => {\n const target = Math.min(itemRows.length - 1, Math.max(0, current + delta));\n if (target === current) return null;\n const r = rowAt(target);\n return Math.min(r.start + col, r.end - 1);\n };\n switch (key) {\n case \"ArrowLeft\":\n return index > 0 ? index - 1 : null;\n case \"ArrowRight\":\n return index < count - 1 ? index + 1 : null;\n case \"ArrowUp\":\n return moveRows(-1);\n case \"ArrowDown\":\n return moveRows(1);\n case \"PageUp\":\n return moveRows(-pageRows);\n case \"PageDown\":\n return moveRows(pageRows);\n case \"Home\":\n return ctrl ? 0 : row.start;\n case \"End\":\n return ctrl ? count - 1 : row.end - 1;\n default:\n return null;\n }\n}\n\n/** Hücrede basılan tuş: Enter/Space → `\"activate\"`, gezinme → yeni dizin, değilse `null`. */\nexport function gridKeyIntent(layout: GalleryLayout, index: number, key: string, ctrl: boolean, pageRows: number): \"activate\" | number | null {\n if (key === \"Enter\" || key === \" \") return \"activate\";\n return galleryKeyStep(layout, index, key, ctrl, Math.max(1, pageRows));\n}\n\n/** Shift ile aralık seçimi: `anchor`..`index` (dahil) düz dizinleri. */\nexport function rangeIndexes(anchor: number, index: number): number[] {\n const [a, b] = anchor < index ? [anchor, index] : [index, anchor];\n return Array.from({ length: b - a + 1 }, (_, i) => a + i);\n}\n\n/** Video süresi: 75 → \"1:15\", 3725 → \"1:02:05\". */\nexport function formatDuration(seconds: number): string {\n const s = Math.max(0, Math.round(seconds));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const ss = String(s % 60).padStart(2, \"0\");\n return h ? `${h}:${String(m).padStart(2, \"0\")}:${ss}` : `${m}:${ss}`;\n}\n\nconst sameDay = (a: Date, b: Date) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n\n/** Bölüm başlığı: gün → \"Bugün\" / \"Dün\" / \"28 Eylül 2026 Pazartesi\", ay → \"Eylül 2026\", yıl → \"2026\". */\nexport function sectionLabel(date: Date | null, view: GalleryView, locale = \"tr-TR\", now = new Date()): string {\n if (!date) return \"Tarihsiz\";\n if (view === \"year\") return String(date.getFullYear());\n if (view === \"month\") return new Intl.DateTimeFormat(locale, { month: \"long\", year: \"numeric\" }).format(date);\n if (sameDay(date, now)) return \"Bugün\";\n const yesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);\n if (sameDay(date, yesterday)) return \"Dün\";\n return new Intl.DateTimeFormat(locale, {\n day: \"numeric\",\n month: \"long\",\n weekday: \"long\",\n ...(date.getFullYear() === now.getFullYear() ? {} : { year: \"numeric\" }),\n }).format(date);\n}\n\n/** Bir üst görünümün başlığına tıklayınca inilecek görünüm (yıl → ay → gün). */\nexport const DRILL_DOWN: Partial<Record<GalleryView, GalleryView>> = { year: \"month\", month: \"day\" };\n\n/**\n * Üst görünümde bir bölüm başlığına tıklanınca: inilecek görünüm ve o\n * bölümün ilk öğesinin YENİ görünümdeki düz dizini (yeniden bölümlemede\n * sıra değişebilir → anahtar yerine öğenin kendisiyle bulunur).\n */\nexport function drillDownTarget<T>(\n items: readonly T[],\n sections: readonly GallerySection<T>[],\n view: GalleryView,\n sectionIndex: number,\n getDate: (item: T) => Date | null | undefined\n): { view: GalleryView; index: number } | null {\n const next = DRILL_DOWN[view];\n const first = sections[sectionIndex]?.entries[0]?.item;\n if (!next || first === undefined) return null;\n const regrouped = groupItems(items, next, getDate).flatMap((s) => s.entries);\n const hit = regrouped.find((e) => e.item === first);\n return { view: next, index: hit?.index ?? 0 };\n}\n"],"mappings":"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","names":["useEffect","useRef","useState","ImageOffIcon","cn","useControllableState","Fragment","jsx","jsxs","ImageOffIcon","cn","Image","useState","useRef","useEffect","useControllableState","React","useEffect","useLayoutEffect","useRef","useState","ZoomInIcon","ZoomOutIcon","cn","useControllableState","Fragment","jsx","jsxs","useEffect","useLayoutEffect","useState","useRef","cn","useControllableState","React","GalleryToolbar","ZoomOutIcon","ZoomInIcon"]}
|