@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
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/toast/Toast.tsx","../src/toast/utils.ts","../src/toast/useToast.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { XIcon } from \"lucide-react\";\nimport { cn } from \"@mari-ui/core\";\nimport { SkeletonBlock } from \"../skeleton\";\nimport { ContentSkeleton } from \"../lib/ContentSkeleton\";\nimport { touchTargetClass } from \"../lib/sizeClasses\";\nimport type { ToastProps } from \"./types\";\nimport { getToastIcon } from \"./utils\";\n\nexport type { ToastProps };\n\n/** Ölçülecek içerik yoksa (yerleşimsiz ortam) genel yer tutucu. */\nconst PLACEHOLDER = (\n <div className=\"flex flex-col gap-2 py-0.5\">\n <SkeletonBlock active width=\"55%\" height=\"0.875rem\" radius=\"sm\" />\n <SkeletonBlock active width=\"80%\" height=\"0.75rem\" radius=\"sm\" />\n </div>\n);\n\n/**\n * Faz 13.6 — eski sürümdeki sorunlar:\n * - Kapat \"düğmesi\" `onClick`li bir SVG'ydi: klavyeyle ulaşılamıyor, adı yoktu.\n * - Başlık `<h1>`, açıklama `<h6>`dı — sayfanın başlık hiyerarşisini bozuyordu.\n * - 5 sn sabit süre, üzerine gelince/odaklanınca DURMUYORDU (WCAG 2.2.1).\n * - Çıkış animasyonu yoktu; kaldırılınca bir anda kayboluyordu.\n *\n * Duyuru Provider'daki kalıcı canlı bölgeden yapılır (bkz. useToast.tsx) —\n * bu kart sadece görsel + etkileşimli kısım.\n *\n * Faz 15.6 — `skeleton` (ikon/başlık/açıklama/aksiyon `ContentSkeleton`,\n * Kapat canlı, sayaç durur); Kapat (28px) ve aksiyon bağlantısı (20px)\n * dokunmatikte 44px hedef.\n */\nexport function Toast({ title, description, type = \"none\", onClose, closeIcon = true, duration, action, exiting = false, skeleton = false }: Readonly<ToastProps>) {\n const icon = getToastIcon(type);\n const [paused, setPaused] = useState(false);\n const remaining = useRef(duration ?? 0);\n const startedAt = useRef(0);\n\n // Kalan süre sayacı: üzerine gelince/odak içerideyken durur, çıkınca kaldığı yerden devam eder.\n // İskeletteyken işlemez — veri gelmeden kapanmasın.\n useEffect(() => {\n if (!duration || paused || exiting || skeleton) return;\n startedAt.current = Date.now();\n const timer = setTimeout(() => onClose?.(), remaining.current);\n return () => {\n clearTimeout(timer);\n remaining.current -= Date.now() - startedAt.current;\n };\n }, [duration, paused, exiting, skeleton, onClose]);\n\n return (\n // Fare/odak olayları sadece sayacı duraklatır; etkileşim içteki düğmelerde.\n <div\n onMouseEnter={() => setPaused(true)}\n onMouseLeave={() => setPaused(false)}\n onFocus={() => setPaused(true)}\n onBlur={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) setPaused(false);\n }}\n aria-busy={skeleton || undefined}\n className={cn(\n \"pointer-events-auto relative flex w-full items-start gap-3 rounded-xl border border-mari-border bg-mari-surface p-4 shadow-mari-lg sm:w-[22rem]\",\n \"transition-[opacity,translate,scale] duration-200 ease-out motion-reduce:transition-none starting:translate-y-2 starting:scale-95 starting:opacity-0\",\n exiting ? \"scale-95 opacity-0\" : \"translate-y-0 scale-100 opacity-100\"\n )}\n >\n <ContentSkeleton on={skeleton} fallback={PLACEHOLDER} className=\"min-w-0 flex-1\">\n <div className=\"flex min-w-0 flex-1 items-start gap-3\">\n {icon}\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold text-mari-foreground\">{title}</p>\n {description && <p className=\"mt-0.5 text-sm text-mari-muted\">{description}</p>}\n {action && (\n <button\n type=\"button\"\n onClick={() => {\n action.onClick();\n onClose?.();\n }}\n className={cn(\n \"relative mt-2 cursor-pointer rounded-sm text-sm font-medium text-mari-primary hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-mari-ring\",\n touchTargetClass.xs\n )}\n >\n {action.label}\n </button>\n )}\n </div>\n </div>\n </ContentSkeleton>\n {closeIcon && (\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Bildirimi kapat\"\n className={cn(\n \"relative -m-1 inline-flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-md text-mari-muted transition-colors hover:bg-mari-surface-alt hover:text-mari-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-mari-ring\",\n // 28px → 44px (her yönde 8px); hazır tablolar 24/32px'lik kontroller için.\n \"pointer-coarse:before:absolute pointer-coarse:before:-inset-2\"\n )}\n >\n <XIcon size={16} aria-hidden />\n </button>\n )}\n </div>\n );\n}\n","import React from \"react\";\nimport { CircleAlertIcon, CircleCheckIcon, CircleXIcon, InfoIcon } from \"lucide-react\";\nimport { textClass } from \"../lib/colorClasses\";\nimport type { ToastPosition, ToastType } from \"./types\";\n\n/** Durum ikonu rol renginde (eskiden içi dolu daire + kontrast renk — küçükte seçilmiyordu). */\nexport function getToastIcon(type: ToastType | undefined): React.ReactNode {\n const map = { error: CircleXIcon, success: CircleCheckIcon, warning: CircleAlertIcon, info: InfoIcon } as const;\n if (!type || !(type in map)) return null;\n const role = type as keyof typeof map;\n return React.createElement(map[role], { size: 20, \"aria-hidden\": true, className: `shrink-0 ${textClass[role]}` });\n}\n\n/**\n * Konum başına kap. Mobilde (sm altı) üst/alt kenarda tam genişlik — dar\n * ekranda köşeye sıkışmış 288px'lik kart yerine.\n */\nexport function getContainerPositionClass(position: ToastPosition): string {\n switch (position) {\n case \"top\":\n return \"top-4 inset-x-4 items-center sm:inset-x-auto sm:left-1/2 sm:-translate-x-1/2\";\n case \"bottom\":\n return \"bottom-4 inset-x-4 items-center sm:inset-x-auto sm:left-1/2 sm:-translate-x-1/2\";\n case \"topLeft\":\n return \"top-4 inset-x-4 items-stretch sm:inset-x-auto sm:left-4 sm:items-start\";\n case \"topRight\":\n return \"top-4 inset-x-4 items-stretch sm:inset-x-auto sm:right-4 sm:items-end\";\n case \"bottomLeft\":\n return \"bottom-4 inset-x-4 items-stretch sm:inset-x-auto sm:left-4 sm:items-start\";\n case \"bottomRight\":\n return \"bottom-4 inset-x-4 items-stretch sm:inset-x-auto sm:right-4 sm:items-end\";\n }\n}\n\n/** Alttaki konumlarda en yeni toast en altta (kenara yakın) değil, en üstte değil — kenara yakın olan en yeni. */\nexport const isBottom = (position: ToastPosition) => position.startsWith(\"bottom\");\n","\"use client\";\n\nimport React, { createContext, useCallback, useContext, useMemo, useRef, useState } from \"react\";\nimport { cn } from \"@mari-ui/core\";\nimport { Toast } from \"./Toast\";\nimport type { ToastData, ToastOptions, ToastPosition } from \"./types\";\nimport { getContainerPositionClass, isBottom } from \"./utils\";\n\nconst DEFAULT_DURATION = 5000;\nconst ACTION_DURATION = 8000;\nconst EXIT_MS = 200;\nconst MAX_PER_POSITION = 4;\nconst DEFAULT_POSITION: ToastPosition = \"bottomRight\";\nconst POSITIONS: ToastPosition[] = [\"top\", \"bottom\", \"topLeft\", \"topRight\", \"bottomLeft\", \"bottomRight\"];\n\ninterface ToastContextType {\n /** Toast gösterir, `id` döndürür (`dismiss` için). */\n showToast: (t: ToastOptions) => string;\n /** Belirli bir toast'u kapatır; `id` verilmezse hepsini. */\n dismiss: (id?: string) => void;\n /**\n * Açık bir toast'u günceller — ör. iskeletten içeriğe:\n * `update(id, { skeleton: false, title: \"Rapor hazır\", type: \"success\" })`.\n * İskeletten çıkınca ekran okuyucuya duyurulur ve kapanma sayacı başlar.\n */\n update: (id: string, changes: Partial<Omit<ToastOptions, \"position\">>) => void;\n}\n\ninterface ToastEntry extends ToastData {\n exiting?: boolean;\n}\n\nconst ToastContext = createContext<ToastContextType | undefined>(undefined);\n\n/** Modül seviyesinde — `useCallback > setTimeout > setState > filter` iç içeliği 4'ü aşmasın. */\nconst withoutToast = (id: string) => (prev: ToastEntry[]) => prev.filter((t) => t.id !== id);\nconst markExiting = (id: string) => (prev: ToastEntry[]) => {\n if (!prev.some((t) => t.id === id && !t.exiting)) return prev;\n return prev.map((t) => (t.id === id ? { ...t, exiting: true } : t));\n};\n\n/** Canlı bölgeye okunacak metin: başlık + (düz metinse) açıklama. */\nconst announcementText = (t: Pick<ToastOptions, \"title\" | \"description\">) =>\n [t.title, typeof t.description === \"string\" ? t.description : \"\"].filter(Boolean).join(\". \");\n\nfunction ToastGroup({ position, toasts, onClose }: Readonly<{ position: ToastPosition; toasts: ToastEntry[]; onClose: (id: string) => void }>) {\n if (toasts.length === 0) return null;\n // Kenara en yakın olan en yeni — altta sıra ters çevrilir.\n const ordered = isBottom(position) ? toasts : [...toasts].reverse();\n return (\n <section\n aria-label=\"Bildirimler\"\n className={cn(\"pointer-events-none fixed z-mari-toast flex flex-col gap-2\", isBottom(position) ? \"justify-end\" : \"justify-start\", getContainerPositionClass(position))}\n >\n {ordered.map((t) => (\n <Toast\n key={t.id}\n title={t.title}\n description={t.description}\n type={t.type}\n closeIcon={t.closeIcon}\n action={t.action}\n duration={t.duration}\n exiting={t.exiting}\n skeleton={t.skeleton}\n onClose={() => onClose(t.id)}\n />\n ))}\n </section>\n );\n}\n\n/**\n * Faz 13.6: ekran okuyucu duyurusu için KALICI iki canlı bölge (polite +\n * assertive). Eskiden hiç yoktu — hiçbir toast duyurulmuyordu. Bölgeler hep\n * DOM'da; sadece metinleri değişir (yeni eklenen canlı bölgeyi bazı ekran\n * okuyucular kaçırır). Hata toast'ları `assertive`.\n */\nexport function ToastProvider({ children }: Readonly<{ children: React.ReactNode }>) {\n const [toasts, setToasts] = useState<ToastEntry[]>([]);\n const [announce, setAnnounce] = useState({ polite: \"\", assertive: \"\" });\n const closers = useRef(new Map<string, (() => void) | undefined>());\n const toastsRef = useRef(toasts);\n toastsRef.current = toasts;\n\n const announceToast = useCallback((t: ToastOptions) => {\n const text = announcementText(t);\n setAnnounce((a) => (t.type === \"error\" ? { ...a, assertive: text } : { ...a, polite: text }));\n }, []);\n\n const remove = useCallback((id: string) => {\n if (!closers.current.has(id)) return; // zaten kapanıyor\n setToasts(markExiting(id));\n const onClose = closers.current.get(id);\n closers.current.delete(id);\n onClose?.();\n setTimeout(() => setToasts(withoutToast(id)), EXIT_MS);\n }, []);\n\n const showToast = useCallback((options: ToastOptions) => {\n const id = crypto.randomUUID();\n const duration = options.duration ?? (options.action ? ACTION_DURATION : DEFAULT_DURATION);\n closers.current.set(id, options.onClose);\n setToasts((prev) => {\n const position = options.position ?? DEFAULT_POSITION;\n const next = [...prev, { ...options, id, duration, position }];\n // Konum başına en fazla N görünür — en eskiler düşer.\n const same = next.filter((t) => (t.position ?? DEFAULT_POSITION) === position && !t.exiting);\n const overflow = same.slice(0, Math.max(0, same.length - MAX_PER_POSITION)).map((t) => t.id);\n return next.filter((t) => !overflow.includes(t.id));\n });\n // İskeletteki içerik yer tutucu — duyurulmaz; veri gelince `update` duyurur.\n if (!options.skeleton) announceToast(options);\n return id;\n }, [announceToast]);\n\n const update = useCallback((id: string, changes: Partial<Omit<ToastOptions, \"position\">>) => {\n const current = toastsRef.current.find((t) => t.id === id);\n if (!current || current.exiting) return;\n const next = { ...current, ...changes };\n if (changes.onClose !== undefined) closers.current.set(id, changes.onClose);\n setToasts((prev) => prev.map((t) => (t.id === id ? { ...t, ...changes } : t)));\n const contentChanged = current.skeleton || changes.title !== undefined || changes.description !== undefined;\n if (!next.skeleton && contentChanged) announceToast(next);\n }, [announceToast]);\n\n const dismiss = useCallback(\n (id?: string) => {\n if (id) remove(id);\n else toastsRef.current.forEach((t) => remove(t.id));\n },\n [remove]\n );\n\n const contextValue = useMemo(() => ({ showToast, dismiss, update }), [showToast, dismiss, update]);\n\n return (\n <ToastContext.Provider value={contextValue}>\n {children}\n {POSITIONS.map((position) => (\n <ToastGroup key={position} position={position} toasts={toasts.filter((t) => (t.position ?? DEFAULT_POSITION) === position)} onClose={remove} />\n ))}\n <div aria-live=\"polite\" role=\"status\" className=\"sr-only\">\n {announce.polite}\n </div>\n <div aria-live=\"assertive\" role=\"alert\" className=\"sr-only\">\n {announce.assertive}\n </div>\n </ToastContext.Provider>\n );\n}\n\nexport function useToast(): ToastContextType {\n const context = useContext(ToastContext);\n if (!context) {\n throw new Error(\"useToast, <ToastProvider> içinde kullanılmalı.\");\n }\n return context;\n}\n"],"mappings":"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","names":["useRef","useState","cn","jsx","jsxs","cn","useState","useRef"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/sizeClasses.ts"],"sourcesContent":["import type { ExtendedSize } from \"@mari-ui/core\";\n\n/**\n * `@mari-ui/core`'un `componentSize` tablosuyla (height/paddingX/paddingY/\n * fontSize) BİLİNÇLİ OLARAK sayısal olarak hizalı, ama burada Tailwind'in\n * kendi built-in utility'leri kullanılır (`h-8`, `px-3`, `rounded-md`),\n * `@mari-ui/tokens`'ın `--mari-*` CSS değişkenleri değil.\n *\n * Neden: renk ekseni tema stüdyosunda ÇALIŞMA ZAMANINDA değişebilir\n * (kullanıcı primary/accent'i değiştirir) — bu yüzden renk CSS değişkeni\n * üzerinden akmalı. Boyut/radius skalası ise `mari-ui.config.json`'da\n * sadece bir PRESET seçimi (Faz 6'daki `density.radius`); rastgele bir\n * değere çekilebilir olması gerekmiyor. Bu ayrım, gereksiz yere ikinci bir\n * özel Tailwind namespace'i icat etmekten kaçınır.\n *\n * Her class ismi burada da (renk tablolarındaki gibi) literal string'tir —\n * Tailwind'in derleme-zamanı tarayıcısı için.\n */\nexport const sizeClass: Record<ExtendedSize, string> = {\n xs: \"h-5 px-2 py-0.5 text-xs gap-1 rounded-sm\",\n sm: \"h-6 px-2 py-1 text-xs gap-1.5 rounded-sm\",\n md: \"h-8 px-3 py-1.5 text-sm gap-2 rounded-md\",\n lg: \"h-10 px-4 py-2 text-base gap-2 rounded-md\",\n xl: \"h-12 px-5 py-2.5 text-lg gap-2.5 rounded-lg\",\n};\n\n/**\n * Kontrol içindeki ikonun (doğrudan `<svg>` çocuk) boyutu — yazı boyutuyla\n * orantılı. Tüketici `<PlusIcon />`ı boyut vermeden geçebilsin: lucide'ın\n * varsayılanı 24px'ti, küçük butonda metinden iri duruyordu. CSS, SVG'nin\n * `width`/`height` niteliğini ezer → `size={16}` verilse de tutarlı kalır.\n */\nexport const iconSizeClass: Record<ExtendedSize, string> = {\n xs: \"[&>svg]:size-3\",\n sm: \"[&>svg]:size-3.5\",\n md: \"[&>svg]:size-4\",\n lg: \"[&>svg]:size-[1.125rem]\",\n xl: \"[&>svg]:size-5\",\n};\n\n/** Sadece font boyutu gereken (Typography gibi) bileşenler için. */\nexport const fontSizeClass: Record<ExtendedSize, string> = {\n xs: \"text-xs\",\n sm: \"text-xs\",\n md: \"text-sm\",\n lg: \"text-base\",\n xl: \"text-lg\",\n};\n\n/**\n * Faz 15 — dokunmatik hedef. Varsayılan kontroller masaüstü yoğunluğunda\n * (md = 32px); parmakla kullanımda önerilen en az 44px. GÖRÜNÜMÜ DEĞİŞTİRMEDEN\n * yalnızca kaba işaretçili (dokunmatik) cihazlarda görünmez bir `::before`\n * katmanı tıklama alanını 44px'e tamamlar. Öğe `relative` olmalı.\n *\n * Dikey: (44 − yükseklik) / 2 → xs 20→12px, sm 24→10px, md 32→6px, lg 40→2px,\n * xl 48 zaten yeterli. Yatay genişletme YOK: yan yana butonlar arasında\n * (gap-2) hedefler çakışırdı; ikon-only (kare) kontroller için\n * `touchTargetSquareClass` kullanın.\n */\nexport const touchTargetClass: Record<ExtendedSize, string> = {\n xs: \"pointer-coarse:before:absolute pointer-coarse:before:inset-x-0 pointer-coarse:before:-inset-y-3\",\n sm: \"pointer-coarse:before:absolute pointer-coarse:before:inset-x-0 pointer-coarse:before:-inset-y-2.5\",\n md: \"pointer-coarse:before:absolute pointer-coarse:before:inset-x-0 pointer-coarse:before:-inset-y-1.5\",\n lg: \"pointer-coarse:before:absolute pointer-coarse:before:inset-x-0 pointer-coarse:before:-inset-y-0.5\",\n xl: \"\",\n};\n\n/** Kare/daire ikon-only kontroller: her yönde 44px'e tamamlar. */\nexport const touchTargetSquareClass: Record<ExtendedSize, string> = {\n xs: \"pointer-coarse:before:absolute pointer-coarse:before:-inset-3\",\n sm: \"pointer-coarse:before:absolute pointer-coarse:before:-inset-2.5\",\n md: \"pointer-coarse:before:absolute pointer-coarse:before:-inset-1.5\",\n lg: \"pointer-coarse:before:absolute pointer-coarse:before:-inset-0.5\",\n xl: \"\",\n};\n\n/**\n * Checkbox/Radio satırı (kutu + etiket) için dokunmatik hedef: satır\n * yüksekliği etiketin satır yüksekliğidir (sm 16 / md 20 / lg 24px) → 44px'e\n * tamamlar. `<label>` içindeki bir öğeye uygulanır; pseudo alana dokunmak\n * etikete dokunmak sayılır ve kontrolü değiştirir.\n */\nexport const checkableTouchTargetClass: Record<\"sm\" | \"md\" | \"lg\", string> = {\n sm: \"pointer-coarse:before:absolute pointer-coarse:before:-inset-x-1 pointer-coarse:before:-inset-y-3.5\",\n md: \"pointer-coarse:before:absolute pointer-coarse:before:-inset-x-1 pointer-coarse:before:-inset-y-3\",\n lg: \"pointer-coarse:before:absolute pointer-coarse:before:-inset-x-1 pointer-coarse:before:-inset-y-2.5\",\n};\n"],"mappings":";AAkBO,IAAM,YAA0C;AAAA,EACrD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAQO,IAAM,gBAA8C;AAAA,EACzD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAGO,IAAM,gBAA8C;AAAA,EACzD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAaO,IAAM,mBAAiD;AAAA,EAC5D,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAGO,IAAM,yBAAuD;AAAA,EAClE,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAQO,IAAM,4BAAgE;AAAA,EAC3E,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dropdown/Dropdown.tsx","../src/dropdown/useDropdown.tsx","../src/dropdown/utils.ts","../src/dropdown/_components/DropdownTrigger.tsx","../src/dropdown/_components/DropdownContent.tsx","../src/dropdown/_components/DropdownItem.tsx","../src/lib/linkBehavior.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useEffect } from \"react\";\nimport { cn } from \"@mari-ui/core\";\nimport type { DropdownProps } from \"./types\";\nimport { DropdownProvider, useDropdown } from \"./useDropdown\";\nimport { getFocusable, getRovingTarget } from \"./utils\";\n\nexport type { DropdownProps };\n\n/**\n * Faz 13.5 bulgusu: sarmalayıcı `role=\"menu\"` + `tabIndex={0}` taşıyordu ama\n * hem trigger'ı HEM de içeriği kapsıyordu — `DropdownContent`in çocukları\n * gerçek `menuitem`ler değil, tamamen keyfi içerik (bkz. Dropdown.stories.tsx),\n * yani `role=\"menu\"` semantik olarak yanlıştı ve `tabIndex={0}` anlamsız bir\n * ekstra tab durağı ekliyordu. İkisi de kaldırıldı — gerçek etkileşim zaten\n * `DropdownTrigger`in kendi `<button>`ı üzerinden klavyeyle erişilebilir.\n *\n * Eskiden ne Escape ile kapanma ne de dışarı tıklayınca kapanma vardı —\n * açık kalan bir dropdown'ı klavyeyle veya mouse'la kapatmanın tek yolu\n * trigger'a tekrar tıklamaktı. İkisi de eklendi.\n */\nfunction DropdownRoot({ children, hover = false, className }: Readonly<DropdownProps>) {\n const { visible, setVisible, anchorRef, panelRef, triggerRef, scheduleHoverClose, cancelHoverClose, skeleton } = useDropdown();\n\n useEffect(() => {\n if (!visible) return;\n\n // Faz 13.5 kullanıcı bulgusu (round 2): panel artık `document.body`'e\n // portal edildiğinden `anchorRef`in ALT AĞACINDA DEĞİL — bu kontrol\n // sadece `anchorRef`e bakıyor olsaydı panelin İÇİNE (örn. bir menü\n // öğesine) tıklamak bile \"dışarı tıklama\" sanılıp dropdown'ı ANINDA\n // kapatırdı, tıklamanın kendi `onClick`i hiç işlemeden. `panelRef` de\n // kontrol ediliyor.\n const handlePointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (anchorRef.current?.contains(target)) return;\n if (panelRef.current?.contains(target)) return;\n setVisible(false);\n };\n // Panel `body`'ye portal edildiğinden DOM sırasında tetikleyicinin\n // ardından gelmez: odak panelin İÇİNDEYKEN Escape ya da panelin\n // sınırından Tab/Shift+Tab, paneli kapatıp odağı tetikleyiciye geri verir\n // (aksi halde odak `body`nin sonunda kaybolurdu).\n const handleKeyDown = (event: KeyboardEvent) => {\n const panel = panelRef.current;\n const focusInPanel = !!panel && panel.contains(document.activeElement);\n\n if (event.key === \"Escape\") {\n setVisible(false);\n if (focusInPanel) triggerRef.current?.focus();\n return;\n }\n\n // Faz 15.5: panel içi ↑/↓/Home/End/harf gezinmesi (bkz. `getRovingTarget`).\n // Bir metin alanındaki (panel içi arama vb.) tuşlar o alana aittir.\n const typing = document.activeElement instanceof HTMLInputElement || document.activeElement instanceof HTMLTextAreaElement;\n if (focusInPanel && !typing && !event.metaKey && !event.ctrlKey && !event.altKey) {\n const target = getRovingTarget(getFocusable(panel), document.activeElement, event.key);\n if (target) {\n event.preventDefault();\n target.focus();\n return;\n }\n }\n\n if (event.key === \"Tab\" && focusInPanel) {\n const focusable = getFocusable(panel);\n const active = document.activeElement;\n const leavingForward = !event.shiftKey && (focusable.length === 0 || active === (focusable.at(-1) ?? null));\n const leavingBackward = event.shiftKey && (focusable.length === 0 || active === (focusable[0] ?? null) || active === panel);\n if (leavingForward || leavingBackward) {\n event.preventDefault();\n setVisible(false);\n triggerRef.current?.focus();\n }\n }\n };\n\n document.addEventListener(\"mousedown\", handlePointerDown);\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"mousedown\", handlePointerDown);\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [visible, setVisible, anchorRef, panelRef, triggerRef]);\n\n // `anchorRef` artık sadece dışarı-tıklama tespiti için değil, aynı zamanda\n // `DropdownContent`in `position: fixed` konumunu hesapladığı referans kutu\n // (bkz. DropdownContent.tsx) — bu yüzden `useDropdown()`dan geliyor,\n // `DropdownContent` da aynı ref'e erişebilsin diye.\n //\n // Faz 13.5 kullanıcı bulgusu (round 2): `onMouseLeave` eskiden ANINDA\n // `setVisible(false)` çağırıyordu — panel artık tetikleyiciden `GAP_PX`\n // kadar uzakta VE ayrı bir DOM alt ağacında (portal) olduğundan, mouse\n // tetikleyiciden panele doğru hareket ederken bu boşluğu geçerken\n // `anchorRef`in dışına çıkıyor, kullanıcı paneli görmeye fırsat\n // bulamadan menü kapanıyordu. Artık kapatma `scheduleHoverClose` ile\n // GECİKMELİ planlanıyor; mouse panele ulaşırsa (bkz. DropdownContent.tsx)\n // `cancelHoverClose` bunu iptal ediyor.\n return (\n <div\n ref={anchorRef}\n className={cn(\"inline-block self-start\", className)}\n onMouseEnter={\n hover && !skeleton\n ? () => {\n cancelHoverClose();\n setVisible(true);\n }\n : undefined\n }\n onMouseLeave={hover ? scheduleHoverClose : undefined}\n >\n {children}\n </div>\n );\n}\n\n/** `DropdownProvider`ı kendi içine gömer — tüketicinin ayrıca sarması gerekmez. */\nexport function Dropdown(props: Readonly<DropdownProps>) {\n return (\n <DropdownProvider hover={props.hover} skeleton={props.skeleton}>\n <DropdownRoot {...props} />\n </DropdownProvider>\n );\n}\n","\"use client\";\n\nimport React, { createContext, useCallback, useContext, useId, useMemo, useRef } from \"react\";\nimport { useDisclosure } from \"@mari-ui/core\";\n\n/**\n * Faz 13.5 kullanıcı bulgusu (round 2): panel `document.body`'e portal\n * edildiğinden beri (kırpma düzeltmesi) tetikleyici ile panel arasında\n * `GAP_PX` kadar bir BOŞLUK var ve panel artık `anchorRef`in DOM alt ağacında\n * DEĞİL — mouse tetikleyiciden panele doğru hareket ederken bu boşluğu\n * geçerken `anchorRef`in dışına çıkıyor, `onMouseLeave` ANINDA kapatıyor.\n * Kullanıcı paneli görmeye bile fırsat bulamadan menü kapanıyordu. Standart\n * \"hover-intent\" çözümü: kapatma anında değil, kısa bir gecikmeyle\n * planlanır; mouse bu süre içinde tetikleyiciye VEYA panele (ikisi de aynı\n * `cancelHoverClose`i çağırıyor) geri dönerse iptal edilir.\n */\nconst HOVER_CLOSE_DELAY_MS = 200;\n\ninterface DropdownContextType {\n visible: boolean;\n setVisible: (val: boolean) => void;\n /** `DropdownContent`in `position: fixed` konumunu hesaplarken referans aldığı kutu — bkz. `Dropdown.tsx`. */\n anchorRef: React.RefObject<HTMLDivElement | null>;\n /**\n * Portal edilen panelin kendi DOM düğümü. `Dropdown.tsx`'teki dışarı-tıklama\n * algılaması eskiden sadece `anchorRef`i kontrol ediyordu — panel artık\n * `document.body`'e portal edildiğinden `anchorRef`in ALT AĞACINDA DEĞİL,\n * bu yüzden panelin İÇİNE (örn. bir menü öğesine) tıklamak bile \"dışarı\n * tıklama\" sanılıp dropdown'ı KAPATIYORDU. Bu ref ikisinin de kontrol\n * edilebilmesi için paylaşılıyor.\n */\n panelRef: React.RefObject<HTMLDivElement | null>;\n /** Tetikleyici `<button>` — Escape/Tab ile panelden çıkılınca odak buraya döner. */\n triggerRef: React.RefObject<HTMLButtonElement | null>;\n /** Panelin `id`si — tetikleyicinin `aria-controls`ü bunu gösterir. */\n panelId: string;\n /** Klavyeyle açıldıysa panel görünür olunca odağın gideceği uç (Enter/Boşluk/↓ → ilk öğe, ↑ → son öğe); `false` → odak taşınmaz. */\n focusPanelOnOpenRef: React.RefObject<false | \"first\" | \"last\">;\n /** `skeleton` açıkken tetikleyici yer tutucu çizer ve panel açılmaz. */\n skeleton: boolean;\n /** `hover` modundayken hem tetikleyici hem panel tarafından paylaşılan gecikmeli kapatma. */\n hoverMode: boolean;\n scheduleHoverClose: () => void;\n cancelHoverClose: () => void;\n}\n\nconst DropdownContext = createContext<DropdownContextType | null>(null);\n\n/**\n * Artık `@mari-ui/core`'un `useDisclosure` hook'u üzerine kurulu. Bu\n * Provider dışa aktarılmıyor (bkz. index.ts) — eskiden `DropdownProvider`\n * `useDropdown.tsx`'te tanımlıydı ama `index.ts`'te export EDİLMİYORDU,\n * yani tüketici `Dropdown`ı kullanabilmek için derin import yapmak zorunda\n * kalıyordu (bkz. plan denetimi). Artık `Dropdown` component'i Provider'ı\n * kendi içine gömüyor; tüketicinin bundan haberi olmasına gerek yok.\n */\nexport function DropdownProvider({ children, hover = false, skeleton = false }: Readonly<{ children: React.ReactNode; hover?: boolean; skeleton?: boolean }>) {\n const { isOpen, open, close } = useDisclosure();\n const anchorRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const focusPanelOnOpenRef = useRef<false | \"first\" | \"last\">(false);\n const panelId = useId();\n const closeTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const cancelHoverClose = useCallback(() => {\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n closeTimeoutRef.current = null;\n }\n }, []);\n\n const scheduleHoverClose = useCallback(() => {\n cancelHoverClose();\n closeTimeoutRef.current = setTimeout(close, HOVER_CLOSE_DELAY_MS);\n }, [cancelHoverClose, close]);\n\n const value = useMemo<DropdownContextType>(\n () => ({ visible: isOpen, setVisible: (v: boolean) => (v ? open() : close()), anchorRef, panelRef, triggerRef, panelId, focusPanelOnOpenRef, hoverMode: hover, skeleton, scheduleHoverClose, cancelHoverClose }),\n [isOpen, open, close, hover, skeleton, scheduleHoverClose, cancelHoverClose, panelId]\n );\n return <DropdownContext.Provider value={value}>{children}</DropdownContext.Provider>;\n}\n\nexport function useDropdown(): DropdownContextType {\n const context = useContext(DropdownContext);\n if (!context) {\n throw new Error(\"useDropdown, <Dropdown> içinde kullanılmalı.\");\n }\n return context;\n}\n","import { cn, resolveColorVariant, type ColorRole, type Variant } from \"@mari-ui/core\";\nimport { colorVariantToClassName } from \"../lib/colorClasses\";\n\nexport { computePanelPosition, parsePlacement } from \"../lib/floating\";\n\nconst FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nexport function getFocusable(root: HTMLElement | null): HTMLElement[] {\n // `tabIndex < 0`: seçici `a[href]`/`button` ile eşleşse de Tab sırasından bilerek çıkarılmış\n // (kapalı akordeonun satırları gibi) — ok tuşu gezinmesi de onları atlamalı.\n return root ? Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter((el) => el.tabIndex >= 0) : [];\n}\n\n/**\n * Faz 15.5 — panel içi klavye gezinmesi (APG \"menu button\" tuş modeli). İçerik\n * keyfi olabildiği için `role=\"menu\"` verilmez; ama odaklanabilir öğeler\n * arasında ↑/↓ (sarar), Home/End ve harfle atlama (başlığı o harfle başlayan\n * sonraki öğe) çalışır. Hedef öğeyi döner, tuş bu modele ait değilse `null`.\n */\nexport function getRovingTarget(items: HTMLElement[], current: Element | null, key: string): HTMLElement | null {\n if (items.length === 0) return null;\n const index = current ? items.indexOf(current as HTMLElement) : -1;\n switch (key) {\n case \"ArrowDown\":\n return items[(index + 1) % items.length] ?? null;\n case \"ArrowUp\":\n return items[index <= 0 ? items.length - 1 : index - 1] ?? null;\n case \"Home\":\n return items[0] ?? null;\n case \"End\":\n return items[items.length - 1] ?? null;\n default: {\n if (key.length !== 1 || key === \" \") return null;\n const char = foldCase(key);\n for (let step = 1; step <= items.length; step++) {\n const candidate = items[(index + step) % items.length];\n if (candidate && foldCase(candidate.textContent?.trim() ?? \"\").startsWith(char)) return candidate;\n }\n return null;\n }\n }\n}\n\n/**\n * Harfle atlama için katlama. `toLocaleLowerCase(\"tr\")` Latin \"I\"yı \"ı\" yapar\n * (\"Info\" → \"ınfo\") ve \"i\" tuşu onu bulamaz. ı→i katlanır: i/ı/I/İ aynı harf\n * sayılır (Tree ve AutoComplete aramasıyla aynı kural).\n */\nfunction foldCase(text: string): string {\n return text.toLocaleLowerCase(\"tr\").replace(/ı/g, \"i\");\n}\n\n/** Renk/variant verilmemişse (eski `variant=\"none\"` varsayılanı) düz, renksiz bir trigger döner. */\nexport function getTriggerClasses(color: ColorRole | undefined, variant: Variant | undefined): string {\n if (!color || !variant) return \"\";\n return cn(colorVariantToClassName(resolveColorVariant(color, variant)), \"rounded-md px-3 py-1.5\");\n}\n","\"use client\";\n\nimport React from \"react\";\nimport { cn } from \"@mari-ui/core\";\nimport type { DropdownTriggerProps } from \"../types\";\nimport { useDropdown } from \"../useDropdown\";\nimport { getTriggerClasses } from \"../utils\";\nimport { skeletonBoxProps } from \"../../lib/skeleton\";\n\nexport function DropdownTrigger({ children, className, color, variant, onClick, \"aria-label\": ariaLabel }: Readonly<DropdownTriggerProps>) {\n const { visible, setVisible, triggerRef, panelId, focusPanelOnOpenRef, hoverMode, skeleton } = useDropdown();\n const classes = cn(\"cursor-pointer\", getTriggerClasses(color, variant), className);\n\n // İskelet: tetikleyicinin kendi sınıfları (boyut, radius, flex düzeni) korunur,\n // içerik görünmez olarak yerinde kalır → yüklenince kutu zıplamaz; tıklanamaz.\n if (skeleton) {\n return (\n <span {...skeletonBoxProps(cn(\"inline-block\", classes, \"*:invisible\"))}>\n {children}\n </span>\n );\n }\n\n return (\n <button\n ref={triggerRef}\n type=\"button\"\n aria-label={ariaLabel}\n aria-expanded={visible}\n aria-controls={visible ? panelId : undefined}\n className={classes}\n onClick={(event) => {\n // `detail === 0`: click'i fare değil klavye (Enter/Boşluk) üretti.\n const fromKeyboard = event.detail === 0;\n if (!visible && fromKeyboard) focusPanelOnOpenRef.current = \"first\";\n // `hover` modunda fare zaten üzerine gelince açtı — ardından gelen\n // tıklama toggle etseydi menü kullanıcının gözü önünde KAPANIRDI.\n // Fare tıklaması orada sadece açık tutar; klavye toggle etmeye devam eder.\n setVisible(hoverMode && !fromKeyboard ? true : !visible);\n onClick?.(event);\n }}\n // APG menu button: ↓ açar ve ilk öğeye, ↑ açar ve son öğeye odaklanır.\n onKeyDown={(event) => {\n if (event.key !== \"ArrowDown\" && event.key !== \"ArrowUp\") return;\n event.preventDefault();\n focusPanelOnOpenRef.current = event.key === \"ArrowDown\" ? \"first\" : \"last\";\n setVisible(true);\n }}\n >\n {children}\n </button>\n );\n}\n","\"use client\";\n\nimport React, { useEffect } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"@mari-ui/core\";\nimport type { DropdownContentProps } from \"../types\";\nimport { useDropdown } from \"../useDropdown\";\nimport { elevationClass } from \"../../lib/elevationClass\";\nimport { FLOATING_ARROW_GAP_PX, FLOATING_ARROW_INSET_PX, FLOATING_EDGE_PX, FLOATING_GAP_PX, FloatingArrow } from \"../../lib/FloatingArrow\";\nimport { useFloatingPosition } from \"../../lib/useFloatingPosition\";\nimport { getFocusable } from \"../utils\";\n\n\n/**\n * Panel `document.body`'e portal edilip `position: fixed` ile konumlanır\n * (`overflow: hidden` atalar tarafından kırpılmasın diye). Konum tek seferlik\n * değil, panel AÇIK KALDIĞI SÜRECE her karede yeniden hesaplanır: içerik\n * asenkron yüklenip sayfa düzenini geç kaydırdığında ölçüm eskimesin. Hesabın\n * kendisi (yön, hiza, flip, kelepçeleme, ok) `computePanelPosition`da —\n * floating-ui gibi bir kütüphaneye geçilmedi (bkz. plan: \"floating-ui kapsam dışı\").\n *\n * Yükseklik, foundations/Elevation'daki kurala göre `elevationClass.md`\n * (Dropdown/popover için `shadow-mari-md` + ince `border-mari-border`);\n * dikey yönlerde en az tetikleyici genişliğinde.\n */\nexport function DropdownContent({ placement = \"bottom-end\", children, className, customVisible, arrow, offset = 0 }: DropdownContentProps) {\n const { visible, anchorRef, panelRef, panelId, focusPanelOnOpenRef, hoverMode, scheduleHoverClose, cancelHoverClose } = useDropdown();\n const isVisible = customVisible ?? visible;\n const hasArrow = !!arrow;\n const pointAtCenter = typeof arrow === \"object\" && !!arrow.pointAtCenter;\n const coords = useFloatingPosition(isVisible, anchorRef, panelRef, {\n placement,\n gap: (hasArrow ? FLOATING_ARROW_GAP_PX : FLOATING_GAP_PX) + offset,\n edge: FLOATING_EDGE_PX,\n arrow: hasArrow ? { inset: FLOATING_ARROW_INSET_PX, pointAtCenter } : undefined,\n });\n\n // Panel `body`'nin sonuna portal edildiğinden Tab ile tetikleyiciden panele\n // DOM sırasıyla ulaşılamaz. Klavyeyle (Enter/Boşluk) açıldıysa odağı\n // panele biz taşırız — ama `invisible` (visibility: hidden) bir öğeye odak\n // verilemediğinden konum hesaplanana (`coords`) kadar beklenir.\n useEffect(() => {\n const edge = focusPanelOnOpenRef.current;\n if (!isVisible || !coords || !edge) return;\n focusPanelOnOpenRef.current = false;\n const panel = panelRef.current;\n const focusable = getFocusable(panel);\n const target = edge === \"last\" ? focusable.at(-1) : focusable[0];\n (target ?? panel)?.focus();\n }, [isVisible, coords, focusPanelOnOpenRef, panelRef]);\n\n if (!isVisible || typeof document === \"undefined\") return null;\n\n return createPortal(\n <div\n ref={panelRef}\n id={panelId}\n tabIndex={-1}\n // `hover` modundayken panel de tetikleyiciyle AYNI gecikmeli kapatma\n // mekanizmasını paylaşıyor — mouse tetikleyiciden panele geçerken\n // (bkz. useDropdown.tsx'teki açıklama) `cancelHoverClose` bekleyen\n // kapatmayı iptal ediyor, panelden ayrılınca `scheduleHoverClose`\n // yeniden planlıyor.\n onMouseEnter={hoverMode ? cancelHoverClose : undefined}\n onMouseLeave={hoverMode ? scheduleHoverClose : undefined}\n className={cn(\n // Genişlik viewport'tan 1rem dar kalır: 375px'te geniş bir panel ekrandan taşmaz.\n \"fixed text-wrap z-mari-dropdown w-max max-w-[min(42rem,calc(100vw-1rem))] text-sm p-1 rounded-lg bg-mari-surface outline-none\",\n elevationClass.md,\n !coords && \"invisible\",\n className\n )}\n style={{ top: coords?.top ?? 0, left: coords?.left ?? 0, minWidth: coords?.anchorWidth }}\n >\n {hasArrow && coords && <FloatingArrow side={coords.side} offset={coords.arrowOffset} />}\n {children}\n </div>,\n document.body\n );\n}\n","\"use client\";\n\nimport React from \"react\";\nimport { cn } from \"@mari-ui/core\";\nimport type { DropdownItemProps } from \"../types\";\nimport { useDropdown } from \"../useDropdown\";\nimport { NewTabHint, getLinkAttrs } from \"../../lib/linkBehavior\";\n\n/**\n * Yapı ant.design menü öğesinden: 32px yükseklik (5px/12px iç boşluk, 22px\n * satır yüksekliği), 4px yarıçap, ikon + metin, disabled durumu. Renkler kendi\n * token'larımızdan: hover'da hafif zemin, danger'da hafif kırmızı zemin.\n */\nexport function DropdownItem({ children, icon, extra, danger = false, disabled = false, href, target, onClick, className }: Readonly<DropdownItemProps>) {\n const { setVisible, triggerRef } = useDropdown();\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {\n onClick?.(event);\n setVisible(false);\n // Link sayfadan çıkarır; odağı tetikleyiciye döndürmek yalnızca yerinde kalan eylemlerde anlamlı.\n if (!href) triggerRef.current?.focus();\n };\n\n const classes = cn(\n \"flex min-h-8 pointer-coarse:min-h-11 w-full cursor-pointer items-center gap-2 rounded-sm px-3 py-[0.3125rem] text-start text-sm leading-[1.375rem] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-mari-ring disabled:cursor-not-allowed disabled:opacity-25\",\n danger\n ? \"text-mari-error hover:bg-mari-error-subtle disabled:hover:bg-transparent\"\n : \"text-mari-foreground hover:bg-mari-foreground/[0.04] disabled:hover:bg-transparent\",\n className\n );\n\n const content = (\n <>\n {icon && (\n <span aria-hidden=\"true\" className=\"inline-flex shrink-0 items-center [&_svg]:size-3.5\">\n {icon}\n </span>\n )}\n <span className=\"min-w-0 flex-1\">{children}</span>\n {href && <NewTabHint target={target} />}\n {extra && <span className=\"ms-4 shrink-0 text-xs text-mari-muted\">{extra}</span>}\n </>\n );\n\n // `href` → gerçek bir link (orta tık / yeni sekmede aç / adres önizlemesi çalışır).\n // Devre dışı öğe her durumda `disabled` bir düğmedir: `<a>`nın `disabled` özniteliği yok.\n if (href && !disabled) {\n return (\n <a href={href} {...getLinkAttrs(target)} onClick={handleClick} className={classes}>\n {content}\n </a>\n );\n }\n\n return (\n <button type=\"button\" disabled={disabled} onClick={handleClick} className={classes}>\n {content}\n </button>\n );\n}\n\n/** Grup başlığı (\"Hesap\", kullanıcı e-postası…): odaklanılamaz, soluk küçük metin. */\nexport function DropdownLabel({ children, className }: Readonly<{ children: React.ReactNode; className?: string }>) {\n return <div className={cn(\"px-3 pb-1 pt-1.5 text-xs text-mari-muted\", className)}>{children}</div>;\n}\n\n/** Menü ayırıcısı: 1px, dikeyde 4px boşluk, hafif çizgi. */\nexport function DropdownDivider({ className }: Readonly<{ className?: string }>) {\n return <div role=\"separator\" className={cn(\"my-1 h-px bg-mari-foreground/[0.06]\", className)} />;\n}\n","import React from \"react\";\nimport { ExternalLinkIcon } from \"lucide-react\";\n\n/** HTML `target` değerleri; isimli bir çerçeve/pencere adı da verilebilir. */\nexport type LinkTarget = \"_self\" | \"_blank\" | \"_parent\" | \"_top\" | (string & {});\n\n/**\n * Faz 15.5 — bir linkin router'a (`onNavigate`) devredilip devredilmeyeceğini\n * belirleyen ortak alanlar (menü öğeleri, Breadcrumb, DropdownItem).\n */\nexport interface LinkBehaviorProps {\n /** Linkin açılacağı yer. `_blank` → yeni sekme (`rel=\"noopener noreferrer\"` otomatik). */\n target?: LinkTarget;\n /**\n * Aynı sekmede ama router'ı ATLAYARAK tam sayfa yükleme: `onNavigate`\n * verilmiş olsa bile tarayıcı sayfayı baştan yükler. Aynı domain'de ama\n * uygulamanın parçası olmayan sayfalar (`/blog` ayrı bir site) ya da\n * sunucunun yönlendirdiği adresler (`/logout`) için.\n */\n reloadDocument?: boolean;\n}\n\n/** `https:`, `mailto:`, `tel:` gibi şemalı ya da `//` ile başlayan adresler — router bunlara gidemez. */\nexport function isExternalHref(href: string): boolean {\n return /^([a-z][a-z\\d+.-]*:|\\/\\/)/i.test(href);\n}\n\n/** Bu link tarayıcıya mı bırakılmalı (router'a devredilmemeli)? */\nexport function bypassesRouter(href: string, { target, reloadDocument }: LinkBehaviorProps): boolean {\n return !!reloadDocument || (!!target && target !== \"_self\") || isExternalHref(href);\n}\n\n/** Değiştirici tuşsuz, sol tuşla yapılan tıklama — yalnızca bu router'a devredilir (⌘/Ctrl/Shift/orta tık tarayıcının). */\nexport function isPlainLeftClick(event: React.MouseEvent): boolean {\n return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;\n}\n\n/** `<a>`ya yayılacak `target` + `rel` (yeni bağlamda açılan linkler açanın `window.opener`ına erişemesin). */\nexport function getLinkAttrs(target: LinkTarget | undefined): { target?: string; rel?: string } {\n if (!target || target === \"_self\") return {};\n return { target, rel: target === \"_blank\" ? \"noopener noreferrer\" : undefined };\n}\n\n/**\n * Yeni sekmede açılan linkin görsel + sesli işareti: küçük bir dış bağlantı\n * ikonu ve ekran okuyucu için \"(yeni sekmede açılır)\". WCAG 3.2.5 — bağlam\n * değişikliği önceden bildirilmeli.\n */\nexport function NewTabHint({ target }: Readonly<{ target?: LinkTarget }>) {\n if (target !== \"_blank\") return null;\n return (\n <>\n <ExternalLinkIcon aria-hidden=\"true\" className=\"size-3 shrink-0 opacity-60\" />\n <span className=\"sr-only\">(yeni sekmede açılır)</span>\n </>\n );\n}\n"],"mappings":"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","names":["cn","jsx","cn","cn","jsx","cn","useEffect","cn","jsx","useEffect","cn","cn","jsx","jsxs","Fragment","jsx","jsxs","cn"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/select/Select.tsx","../src/select/useSelectState.ts"],"sourcesContent":["\"use client\";\n\nimport React, { useId, useRef } from \"react\";\nimport { ChevronDownIcon, Loader2Icon } from \"lucide-react\";\nimport { cn } from \"@mari-ui/core\";\nimport { ClearButton } from \"../input/_components/FieldAdornments\";\nimport { FIELD_BASE_CLASS, FIELD_DISABLED_CLASS, FIELD_MOBILE_TEXT_CLASS, getShapeClasses, getVariantClasses } from \"../input/utils\";\nimport { useFieldControl } from \"../lib/fieldContext\";\nimport { skeletonBoxProps } from \"../lib/skeleton\";\nimport { sizeClass, touchTargetClass } from \"../lib/sizeClasses\";\nimport { useFloatingPosition } from \"../lib/useFloatingPosition\";\nimport { Tag } from \"../tag\";\nimport { optionDomId, SelectPanel } from \"./_components/SelectPanel\";\nimport type { SelectMultipleProps, SelectOption, SelectProps } from \"./types\";\nimport { useSelectState, type SelectState } from \"./useSelectState\";\n\nexport type { SelectProps };\n\nconst GAP_PX = 4;\n\n/** Çoklu modda kutu sabit yükseklik değil, en az o yükseklik — etiketler satırlara sarar. */\nconst MULTI_HEIGHT_CLASS = { sm: \"h-auto min-h-6 py-0.5\", md: \"h-auto min-h-8 py-1\", lg: \"h-auto min-h-10 py-1.5\" } as const;\n\nfunction optionLabel(option: SelectOption): React.ReactNode {\n return option.label ?? option.value;\n}\n\n/** Aramasız tetikleyicide görünen metin: seçilen (tekli), hiç seçim yokken yer tutucu; çokluda etiketler kendini gösterir. */\nfunction buttonText(single: SelectOption | undefined, hasValue: boolean, placeholder: string): React.ReactNode {\n if (single) return optionLabel(single);\n if (!hasValue) return <span className=\"truncate text-mari-muted\">{placeholder}</span>;\n return null;\n}\n\ntype KeyHandler = (e: React.KeyboardEvent, state: SelectState, searchable: boolean) => void;\n\nconst onArrow: KeyHandler = (e, state) => {\n e.preventDefault();\n const down = e.key === \"ArrowDown\";\n if (!state.open) state.openAt(!down && !e.altKey ? \"last\" : \"selected\");\n else state.move(down ? 1 : -1);\n};\n\nconst onEdge: KeyHandler = (e, state, searchable) => {\n // Arama kutusunda Home/End imleci taşır.\n if (!state.open || searchable) return;\n e.preventDefault();\n state.setActiveIndex(e.key === \"Home\" ? state.visibleOptions.findIndex((o) => !o.disabled) : state.visibleOptions.length - 1);\n};\n\nconst onConfirm: KeyHandler = (e, state, searchable) => {\n // Arama kutusunda boşluk bir karakterdir.\n if (e.key === \" \" && searchable) return;\n e.preventDefault();\n if (!state.open) state.openAt();\n else if (state.activeOption) state.pick(state.activeOption);\n};\n\nconst onEscape: KeyHandler = (e, state) => {\n if (!state.open) return;\n e.preventDefault();\n state.setOpen(false);\n};\n\n// APG: Tab tekli seçimde aktif seçeneği onaylar ve listeyi kapatır; odak normal akışla ilerler.\nconst onTab: KeyHandler = (_e, state) => {\n if (!state.open) return;\n if (!state.multiple && state.activeOption) state.pick(state.activeOption);\n else state.setOpen(false);\n};\n\nconst onBackspace: KeyHandler = (_e, state, searchable) => {\n if (searchable && state.multiple && !state.search && state.values.length > 0) state.removeValue(state.values.at(-1)!);\n};\n\nconst KEY_HANDLERS: Partial<Record<string, KeyHandler>> = {\n ArrowDown: onArrow,\n ArrowUp: onArrow,\n Home: onEdge,\n End: onEdge,\n Enter: onConfirm,\n \" \": onConfirm,\n Escape: onEscape,\n Tab: onTab,\n Backspace: onBackspace,\n};\n\n/** Tetikleyicideki tuşlar (APG combobox). Arama kutusu varsa harfler kutuya yazılır, yoksa harfle atlama. */\nfunction handleTriggerKey(e: React.KeyboardEvent, state: SelectState, searchable: boolean) {\n const handler = KEY_HANDLERS[e.key];\n if (handler) handler(e, state, searchable);\n else if (!searchable && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) state.typeChar(e.key);\n}\n\nfunction SelectTags({ state, maxTagCount, disabled }: Readonly<{ state: SelectState; maxTagCount?: number; disabled: boolean }>) {\n const shown = maxTagCount === undefined ? state.selectedOptions : state.selectedOptions.slice(0, maxTagCount);\n const hidden = state.selectedOptions.length - shown.length;\n return (\n <>\n {shown.map((option) => {\n const label = optionLabel(option);\n return (\n <Tag\n key={String(option.value)}\n onClose={disabled ? undefined : () => state.removeValue(option.value)}\n closeLabel={typeof label === \"string\" ? `${label} seçimini kaldır` : \"Seçimi kaldır\"}\n className=\"max-w-full\"\n >\n {label}\n </Tag>\n );\n })}\n {hidden > 0 && <Tag>+{hidden}</Tag>}\n </>\n );\n}\n\nfunction SelectSuffix({ loading, open }: Readonly<{ loading: boolean; open: boolean }>) {\n return (\n <span aria-hidden className=\"flex shrink-0 items-center text-mari-muted\">\n {loading ? (\n <Loader2Icon size={16} className=\"animate-spin motion-reduce:animate-[spin_2s_linear_infinite]\" />\n ) : (\n <ChevronDownIcon size={16} className={cn(\"transition-transform duration-150 motion-reduce:transition-none\", open && \"rotate-180\")} />\n )}\n </span>\n );\n}\n\n/**\n * Faz 16.1 — yapı/davranış ant.design Select'ten, görünüm Input'la birebir\n * aynı (boyut, varyant, kenarlık, odak halkası, dokunma hedefi `lib`\n * paylaşımlı). Tekli ve çoklu (`mode=\"multiple\"`, etiketler) seçim, gruplar,\n * arama (`showSearch`, Türkçe/aksansız), temizleme, yükleniyor, `skeleton`.\n *\n * Erişilebilirlik (APG combobox): arama yoksa tetikleyici `<button\n * role=\"combobox\">` (label `htmlFor` ile bağlanabilir, native disabled),\n * aramada `<input role=\"combobox\">`. Odak HİÇ listeye geçmez; aktif seçenek\n * `aria-activedescendant`. ↑/↓/Home/End, Enter/Boşluk, Escape, Tab (seçip\n * geçer), harfle atlama; çokluda Backspace son etiketi siler.\n */\nexport function Select(outerProps: SelectProps) {\n // Field içindeyse id / aria-describedby / hata / required / disabled oradan tamamlanır.\n const props = useFieldControl(outerProps) as SelectProps;\n const {\n placeholder = \"Seçin\",\n showSearch = false,\n allowClear = false,\n clearLabel = \"Temizle\",\n loading = false,\n notFoundContent = \"Sonuç bulunamadı\",\n disabled = false,\n size = \"md\",\n variant = \"outline\",\n shape = \"default\",\n color,\n placement = \"bottom-start\",\n listHeight = \"16rem\",\n optionRender,\n id,\n name,\n required,\n className,\n skeleton = false,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n } = props;\n const maxTagCount = props.mode === \"multiple\" ? (props as SelectMultipleProps).maxTagCount : undefined;\n\n const state = useSelectState(props);\n const { multiple, open, values, selectedOptions, search } = state;\n const anchorRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const controlRef = useRef<HTMLButtonElement & HTMLInputElement>(null);\n const listboxId = useId();\n const coords = useFloatingPosition(open, anchorRef, panelRef, { placement, gap: GAP_PX });\n\n // Klavyeyle gezinirken aktif satır listenin görünür alanında kalsın.\n React.useEffect(() => {\n if (open && state.activeOption) document.getElementById(optionDomId(listboxId, state.activeOption))?.scrollIntoView?.({ block: \"nearest\" });\n }, [open, state.activeOption, listboxId]);\n\n const geometry = cn(\"flex w-full items-center gap-2\", sizeClass[size], multiple && MULTI_HEIGHT_CLASS[size], getShapeClasses(shape, variant));\n if (skeleton) return <div {...skeletonBoxProps(cn(geometry, className))} />;\n\n const hasValue = values.length > 0;\n const showClear = allowClear && hasValue && !disabled;\n const single = multiple ? undefined : selectedOptions[0];\n\n const comboboxProps = {\n id,\n role: \"combobox\" as const,\n \"aria-expanded\": open,\n \"aria-controls\": open ? listboxId : undefined,\n \"aria-haspopup\": \"listbox\" as const,\n \"aria-activedescendant\": open && state.activeOption ? optionDomId(listboxId, state.activeOption) : undefined,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-required\": required || undefined,\n \"aria-invalid\": color === \"error\" || undefined,\n disabled,\n onKeyDown: (e: React.KeyboardEvent) => handleTriggerKey(e, state, showSearch),\n onBlur: (e: React.FocusEvent) => {\n // Odak kutunun içindeki bir düğmeye (temizle, etiket sil) geçtiyse kapatma.\n if (!anchorRef.current?.contains(e.relatedTarget as Node | null)) state.setOpen(false);\n },\n };\n\n // Kutunun herhangi bir yerine tıklamak odaklar ve açar/kapatır; iç düğmeler kendi işini yapar.\n const handleBoxMouseDown = (e: React.MouseEvent) => {\n if (disabled || (e.target as HTMLElement).closest(\"button:not([role=combobox])\")) return;\n e.preventDefault();\n controlRef.current?.focus();\n if (open) state.setOpen(false);\n else state.openAt();\n };\n\n return (\n <>\n {/* Fare kısayolu; klavye kullanıcısı doğrudan combobox'a sekmeyle gelir. */}\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}\n <div\n ref={anchorRef}\n onMouseDown={handleBoxMouseDown}\n className={cn(\n geometry,\n \"group relative cursor-pointer\",\n touchTargetClass[size],\n FIELD_BASE_CLASS,\n getVariantClasses(variant, color),\n disabled && FIELD_DISABLED_CLASS,\n className\n )}\n >\n <div className={cn(\"flex min-w-0 flex-1 items-center gap-1\", multiple && \"flex-wrap\")}>\n {multiple && <SelectTags state={state} maxTagCount={maxTagCount} disabled={disabled} />}\n {showSearch ? (\n <span className=\"relative flex min-w-[4ch] flex-1 items-center\">\n {/* Tekli seçimde seçili değer, yazmaya başlayınca kaybolur. Yer tutucu native `placeholder`\n (Input gibi) — ayrı bir span olsaydı devre dışı alanda axe onu kontrast ihlali sayıyordu. */}\n {!search && single && (\n <span aria-hidden className=\"pointer-events-none absolute inset-x-0 truncate\">\n {optionLabel(single)}\n </span>\n )}\n <input\n ref={controlRef}\n {...comboboxProps}\n type=\"text\"\n aria-autocomplete=\"list\"\n autoComplete=\"off\"\n placeholder={hasValue ? undefined : placeholder}\n value={search}\n onChange={(e) => {\n state.setSearch(e.target.value);\n state.setOpen(true);\n }}\n className={cn(\"w-full min-w-0 bg-transparent placeholder:text-mari-muted focus:outline-none disabled:cursor-not-allowed\", FIELD_MOBILE_TEXT_CLASS)}\n />\n </span>\n ) : (\n <button ref={controlRef} type=\"button\" {...comboboxProps} className={cn(\"min-w-0 flex-1 truncate text-left focus:outline-none\", FIELD_MOBILE_TEXT_CLASS)}>\n {buttonText(single, hasValue, placeholder)}\n </button>\n )}\n </div>\n\n {allowClear && (\n <ClearButton\n visible={showClear}\n label={clearLabel}\n onClear={() => {\n state.clear();\n controlRef.current?.focus();\n }}\n />\n )}\n <SelectSuffix loading={loading} open={open} />\n\n {name && (multiple ? values : values.slice(0, 1)).map((v) => <input key={String(v)} type=\"hidden\" name={name} value={String(v)} />)}\n </div>\n\n {open && (\n <SelectPanel\n ref={panelRef}\n listboxId={listboxId}\n coords={coords}\n sections={state.sections}\n flatOptions={state.visibleOptions}\n activeIndex={state.activeIndex}\n isSelected={state.isSelected}\n multiple={multiple}\n loading={loading}\n notFoundContent={notFoundContent}\n listHeight={listHeight}\n optionRender={optionRender}\n labelledBy={ariaLabelledBy}\n label={ariaLabel}\n onPick={(option) => {\n state.pick(option);\n controlRef.current?.focus();\n }}\n onHover={state.setActiveIndex}\n />\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useControllableState } from \"@mari-ui/core\";\nimport type { SelectOption, SelectProps, SelectValue } from \"./types\";\nimport { buildSections, firstEnabled, flattenOptions, lastEnabled, nextEnabled, typeAheadMatch } from \"./utils\";\n\nconst TYPE_AHEAD_RESET_MS = 500;\n\n/**\n * Select'in durumu: seçili değer(ler), açık/kapalı, arama metni, aktif\n * (klavyeyle/fareyle üzerinde durulan) seçenek ve bunları değiştiren\n * eylemler. Tekli ve çoklu mod içeride aynı dizi olarak tutulur.\n */\nexport function useSelectState(props: SelectProps) {\n const multiple = props.mode === \"multiple\";\n const toArray = (v: SelectValue | SelectValue[] | null | undefined): SelectValue[] | undefined => {\n if (v === undefined) return undefined;\n if (v === null) return [];\n return Array.isArray(v) ? v : [v];\n };\n\n const allOptions = useMemo(() => flattenOptions(props.options), [props.options]);\n const findOption = (value: SelectValue) => allOptions.find((o) => o.value === value);\n\n const [values, setValuesState] = useControllableState<SelectValue[]>({\n value: toArray(props.value),\n defaultValue: toArray(props.defaultValue) ?? [],\n });\n const [open, setOpenState] = useControllableState<boolean>({ value: props.open, defaultValue: false, onChange: props.onOpenChange });\n const [search, setSearchState] = useState(\"\");\n const [activeIndex, setActiveIndex] = useState(-1);\n\n const sections = useMemo(() => buildSections(props.options, props.showSearch ? search : \"\"), [props.options, props.showSearch, search]);\n const visibleOptions = useMemo(() => sections.flatMap((s) => s.options), [sections]);\n const activeOption = activeIndex >= 0 ? visibleOptions[activeIndex] : undefined;\n\n // Yazdıkça aktif satır ilk eşleşme olur (Enter onu seçer); liste kısalınca sınır dışına düşmesin.\n useEffect(() => {\n if (search) setActiveIndex(firstEnabled(visibleOptions));\n // eslint-disable-next-line react-hooks/exhaustive-deps -- yalnız arama metni değişince\n }, [search]);\n useEffect(() => {\n if (activeIndex >= visibleOptions.length) setActiveIndex(firstEnabled(visibleOptions));\n }, [visibleOptions, activeIndex]);\n\n const commit = (next: SelectValue[]) => {\n setValuesState(next);\n if (multiple) {\n const onChange = props.onChange as ((v: SelectValue[], o: SelectOption[]) => void) | undefined;\n onChange?.(next, next.map(findOption).filter((o): o is SelectOption => !!o));\n } else {\n const onChange = props.onChange as ((v: SelectValue | null, o: SelectOption | null) => void) | undefined;\n const value = next[0] ?? null;\n onChange?.(value, value === null ? null : (findOption(value) ?? null));\n }\n };\n\n const setSearch = (text: string) => {\n setSearchState(text);\n props.onSearch?.(text);\n };\n\n const setOpen = (next: boolean) => {\n if (next === open) return;\n setOpenState(next);\n if (!next) {\n setActiveIndex(-1);\n if (search) setSearch(\"\");\n }\n };\n\n /** Açarken aktif satır: seçili olan (tekli) ya da ilk seçilebilir. */\n const openAt = (edge: \"selected\" | \"first\" | \"last\" = \"selected\") => {\n const selectedIndex = visibleOptions.findIndex((o) => values.includes(o.value));\n if (edge === \"last\") setActiveIndex(lastEnabled(visibleOptions));\n else if (edge === \"selected\" && selectedIndex >= 0 && !multiple) setActiveIndex(selectedIndex);\n else setActiveIndex(firstEnabled(visibleOptions));\n setOpen(true);\n };\n\n const pick = (option: SelectOption) => {\n if (option.disabled) return;\n if (!multiple) {\n commit([option.value]);\n setOpen(false);\n return;\n }\n const has = values.includes(option.value);\n commit(has ? values.filter((v) => v !== option.value) : [...values, option.value]);\n // Çoklu seçimde liste açık kalır; arama temizlenir ki sonraki seçim kolay olsun.\n if (search) setSearch(\"\");\n };\n\n const move = (step: 1 | -1) => {\n // Henüz etkin seçenek yoksa yukarı ok sondan, aşağı ok baştan başlar.\n const edge = step === -1 ? lastEnabled : firstEnabled;\n setActiveIndex((i) => (i < 0 ? edge(visibleOptions) : nextEnabled(visibleOptions, i, step)));\n };\n\n // Harfle atlama (arama kutusu yokken): art arda harfler 500ms içinde birikir.\n const typeAhead = useRef({ buffer: \"\", timer: 0 as ReturnType<typeof setTimeout> | 0 });\n useEffect(() => () => clearTimeout(typeAhead.current.timer || undefined), []);\n const typeChar = (char: string) => {\n const state = typeAhead.current;\n state.buffer += char;\n clearTimeout(state.timer || undefined);\n state.timer = setTimeout(() => (state.buffer = \"\"), TYPE_AHEAD_RESET_MS);\n const match = typeAheadMatch(visibleOptions, activeIndex, state.buffer);\n if (match < 0) return;\n setActiveIndex(match);\n setOpen(true);\n };\n\n const removeValue = (value: SelectValue) => commit(values.filter((v) => v !== value));\n const clear = () => commit([]);\n\n return {\n multiple,\n values,\n selectedOptions: values.map((v) => findOption(v) ?? { value: v }),\n open,\n setOpen,\n openAt,\n search,\n setSearch,\n sections,\n visibleOptions,\n activeIndex,\n setActiveIndex,\n activeOption,\n pick,\n move,\n typeChar,\n removeValue,\n clear,\n isSelected: (option: SelectOption) => values.includes(option.value),\n };\n}\n\nexport type SelectState = ReturnType<typeof useSelectState>;\n"],"mappings":"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","names":["useRef","useRef"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/colorClasses.ts"],"sourcesContent":["import { cn, type ColorRole, type ColorVariantStyle } from \"@mari-ui/core\";\n\n/**\n * `@mari-ui/tokens`'ın ürettiği `--color-mari-*` CSS değişkenlerine karşılık\n * gelen Tailwind utility class'ları.\n *\n * ÖNEMLİ: Her class ismi burada HARFİ HARFİNE, literal string olarak\n * yazılıdır — `` `bg-mari-${role}-solid` `` gibi bir template literal\n * KULLANILMAZ. Sebebi: Tailwind'in derleme-zamanı tarayıcısı kaynak\n * dosyanın METNİNİ okur, kodu çalıştırmaz. `${role}` içeren bir satır\n * çalışma zamanında \"bg-mari-primary-solid\" olur ama tarayıcı bunu asla\n * göremez — kaynak metinde hâlâ kesik bir template literal olarak durur.\n * Bu repoda `Skeleton`/`Tag`/`Loading`'i sessizce bozan hata tam olarak\n * buydu (bkz. plan Faz 3); burada aynı hatayı tekrarlamamak için tabloyu\n * elle, tam string'lerle yazıyoruz.\n */\nexport const bgSolidClass: Record<ColorRole, string> = {\n primary: \"bg-mari-primary-solid\",\n accent: \"bg-mari-accent-solid\",\n success: \"bg-mari-success-solid\",\n error: \"bg-mari-error-solid\",\n warning: \"bg-mari-warning-solid\",\n info: \"bg-mari-info-solid\",\n neutral: \"bg-mari-neutral-solid\",\n};\n\nexport const bgSolidHoverClass: Record<ColorRole, string> = {\n primary: \"hover:bg-mari-primary-solid-hover\",\n accent: \"hover:bg-mari-accent-solid-hover\",\n success: \"hover:bg-mari-success-solid-hover\",\n error: \"hover:bg-mari-error-solid-hover\",\n warning: \"hover:bg-mari-warning-solid-hover\",\n info: \"hover:bg-mari-info-solid-hover\",\n neutral: \"hover:bg-mari-neutral-solid-hover\",\n};\n\n/** Dolgu üzerindeki ikon/anahtar topu, solidContrast ile aynı kontrastı korur. */\nexport const bgSolidContrastClass: Record<ColorRole, string> = {\n primary: \"bg-mari-primary-solid-contrast\",\n accent: \"bg-mari-accent-solid-contrast\",\n success: \"bg-mari-success-solid-contrast\",\n error: \"bg-mari-error-solid-contrast\",\n warning: \"bg-mari-warning-solid-contrast\",\n info: \"bg-mari-info-solid-contrast\",\n neutral: \"bg-mari-neutral-solid-contrast\",\n};\n\nexport const textSolidContrastClass: Record<ColorRole, string> = {\n primary: \"text-mari-primary-solid-contrast\",\n accent: \"text-mari-accent-solid-contrast\",\n success: \"text-mari-success-solid-contrast\",\n error: \"text-mari-error-solid-contrast\",\n warning: \"text-mari-warning-solid-contrast\",\n info: \"text-mari-info-solid-contrast\",\n neutral: \"text-mari-neutral-solid-contrast\",\n};\n\nexport const bgSubtleClass: Record<ColorRole, string> = {\n primary: \"bg-mari-primary-subtle\",\n accent: \"bg-mari-accent-subtle\",\n success: \"bg-mari-success-subtle\",\n error: \"bg-mari-error-subtle\",\n warning: \"bg-mari-warning-subtle\",\n info: \"bg-mari-info-subtle\",\n neutral: \"bg-mari-neutral-subtle\",\n};\n\nexport const textSubtleContrastClass: Record<ColorRole, string> = {\n primary: \"text-mari-primary-subtle-contrast\",\n accent: \"text-mari-accent-subtle-contrast\",\n success: \"text-mari-success-subtle-contrast\",\n error: \"text-mari-error-subtle-contrast\",\n warning: \"text-mari-warning-subtle-contrast\",\n info: \"text-mari-info-subtle-contrast\",\n neutral: \"text-mari-neutral-subtle-contrast\",\n};\n\nexport const textClass: Record<ColorRole, string> = {\n primary: \"text-mari-primary\",\n accent: \"text-mari-accent\",\n success: \"text-mari-success\",\n error: \"text-mari-error\",\n warning: \"text-mari-warning\",\n info: \"text-mari-info\",\n neutral: \"text-mari-neutral\",\n};\n\n/** `textClass`in `hover:` varyantı — örn. Menu öğelerinde primary rengi SADECE hover metin rengi olarak uygulamak için. */\nexport const textHoverClass: Record<ColorRole, string> = {\n primary: \"hover:text-mari-primary\",\n accent: \"hover:text-mari-accent\",\n success: \"hover:text-mari-success\",\n error: \"hover:text-mari-error\",\n warning: \"hover:text-mari-warning\",\n info: \"hover:text-mari-info\",\n neutral: \"hover:text-mari-neutral\",\n};\n\nexport const borderColorClass: Record<ColorRole, string> = {\n primary: \"border-mari-primary-border\",\n accent: \"border-mari-accent-border\",\n success: \"border-mari-success-border\",\n error: \"border-mari-error-border\",\n warning: \"border-mari-warning-border\",\n info: \"border-mari-info-border\",\n neutral: \"border-mari-neutral-border\",\n};\n\n/** Rolün KENDİ rengiyle (açık `-border` tonuyla değil) çizilen kenarlık — `outline` varyantı bunu kullanır. */\nexport const borderStrongColorClass: Record<ColorRole, string> = {\n primary: \"border-mari-primary\",\n accent: \"border-mari-accent\",\n success: \"border-mari-success\",\n error: \"border-mari-error\",\n warning: \"border-mari-warning\",\n info: \"border-mari-info\",\n neutral: \"border-mari-neutral\",\n};\n\n/** `bgSubtleClass`in `hover:` varyantı — outline/ghost butonların hover dolgusu. */\nexport const bgSubtleHoverClass: Record<ColorRole, string> = {\n primary: \"hover:bg-mari-primary-subtle\",\n accent: \"hover:bg-mari-accent-subtle\",\n success: \"hover:bg-mari-success-subtle\",\n error: \"hover:bg-mari-error-subtle\",\n warning: \"hover:bg-mari-warning-subtle\",\n info: \"hover:bg-mari-info-subtle\",\n neutral: \"hover:bg-mari-neutral-subtle\",\n};\n\n/** `borderColorClass`in `hover:` varyantı. */\nexport const borderColorHoverClass: Record<ColorRole, string> = {\n primary: \"hover:border-mari-primary-border\",\n accent: \"hover:border-mari-accent-border\",\n success: \"hover:border-mari-success-border\",\n error: \"hover:border-mari-error-border\",\n warning: \"hover:border-mari-warning-border\",\n info: \"hover:border-mari-info-border\",\n neutral: \"hover:border-mari-neutral-border\",\n};\n\n/** SVG `fill`/`stroke` için — örn. Tooltip'in ok işareti. */\nexport const fillSolidClass: Record<ColorRole, string> = {\n primary: \"fill-mari-primary-solid\",\n accent: \"fill-mari-accent-solid\",\n success: \"fill-mari-success-solid\",\n error: \"fill-mari-error-solid\",\n warning: \"fill-mari-warning-solid\",\n info: \"fill-mari-info-solid\",\n neutral: \"fill-mari-neutral-solid\",\n};\n\nexport const strokeSolidClass: Record<ColorRole, string> = {\n primary: \"stroke-mari-primary-solid\",\n accent: \"stroke-mari-accent-solid\",\n success: \"stroke-mari-success-solid\",\n error: \"stroke-mari-error-solid\",\n warning: \"stroke-mari-warning-solid\",\n info: \"stroke-mari-info-solid\",\n neutral: \"stroke-mari-neutral-solid\",\n};\n\n/** `soft` varyantlı yüzeyler (örn. Tooltip'in soft rengi) için — arka planla eşleşsin diye SVG `fill`. */\nexport const fillSubtleClass: Record<ColorRole, string> = {\n primary: \"fill-mari-primary-subtle\",\n accent: \"fill-mari-accent-subtle\",\n success: \"fill-mari-success-subtle\",\n error: \"fill-mari-error-subtle\",\n warning: \"fill-mari-warning-subtle\",\n info: \"fill-mari-info-subtle\",\n neutral: \"fill-mari-neutral-subtle\",\n};\n\nexport const strokeSubtleClass: Record<ColorRole, string> = {\n primary: \"stroke-mari-primary-subtle\",\n accent: \"stroke-mari-accent-subtle\",\n success: \"stroke-mari-success-subtle\",\n error: \"stroke-mari-error-subtle\",\n warning: \"stroke-mari-warning-subtle\",\n info: \"stroke-mari-info-subtle\",\n neutral: \"stroke-mari-neutral-subtle\",\n};\n\n/**\n * `resolveColorVariant()`'ın döndürdüğü soyut token referanslarını gerçek\n * Tailwind class'larına çevirir. Web renderer'ının (bu paketin) tek görevi\n * budur — aynı soyut çıktı, `@mari-ui/native`'de `StyleSheet` objesine\n * çevrilir.\n */\nexport function colorVariantToClassName(style: ColorVariantStyle): string {\n const slotTable = {\n text: textClass,\n solid: bgSolidClass,\n solidContrast: textSolidContrastClass,\n solidHover: bgSolidHoverClass,\n subtle: bgSubtleClass,\n subtleContrast: textSubtleContrastClass,\n border: borderColorClass,\n } as const;\n\n // `background`/`foreground` slot adını doğrudan kullanır; `border` ve\n // `hoverBackground` ise AYNI slot'u kendi CSS özelliğine çevirmek zorunda\n // (örn. `text` slot'u bir kenarlıkta `border-mari-primary`, bir metinde\n // `text-mari-primary` demektir — native tarafında ikisi de aynı ham renge\n // çözüldüğü için `slot` seti değişmeden kalıyor).\n const borderSlotTable = { text: borderStrongColorClass, border: borderColorClass } as const;\n const hoverBgSlotTable = { solidHover: bgSolidHoverClass, subtle: bgSubtleHoverClass } as const;\n\n const bg = style.background ? slotTable[style.background.slot][style.background.role] : undefined;\n const hoverBg = style.hoverBackground\n ? hoverBgSlotTable[style.hoverBackground.slot as keyof typeof hoverBgSlotTable]?.[style.hoverBackground.role]\n : undefined;\n const text = style.foreground ? slotTable[style.foreground.slot][style.foreground.role] : undefined;\n const border = style.border ? borderSlotTable[style.border.slot as keyof typeof borderSlotTable]?.[style.border.role] : undefined;\n\n return cn(bg, hoverBg, text, border, border && \"border\");\n}\n\n/**\n * Faz 15 — işaretlenebilir kontroller (Checkbox/Radio) için `checked:` önekli\n * literal tablolar. Önek runtime'da birleştirilmez (Tailwind taraması).\n * Kenarlık dolguyla AYNI (`-solid`): eskiden açık `-border` tonuydu, dolu\n * kutunun etrafında soluk bir hare gibi duruyordu ve 3:1'i geçmiyordu.\n */\nexport const checkedBgSolidClass: Record<ColorRole, string> = {\n primary: \"checked:bg-mari-primary-solid\",\n accent: \"checked:bg-mari-accent-solid\",\n success: \"checked:bg-mari-success-solid\",\n error: \"checked:bg-mari-error-solid\",\n warning: \"checked:bg-mari-warning-solid\",\n info: \"checked:bg-mari-info-solid\",\n neutral: \"checked:bg-mari-neutral-solid\",\n};\n\nexport const checkedBgSolidHoverClass: Record<ColorRole, string> = {\n primary: \"checked:hover:bg-mari-primary-solid-hover\",\n accent: \"checked:hover:bg-mari-accent-solid-hover\",\n success: \"checked:hover:bg-mari-success-solid-hover\",\n error: \"checked:hover:bg-mari-error-solid-hover\",\n warning: \"checked:hover:bg-mari-warning-solid-hover\",\n info: \"checked:hover:bg-mari-info-solid-hover\",\n neutral: \"checked:hover:bg-mari-neutral-solid-hover\",\n};\n\nexport const checkedBorderSolidClass: Record<ColorRole, string> = {\n primary: \"checked:border-mari-primary-solid\",\n accent: \"checked:border-mari-accent-solid\",\n success: \"checked:border-mari-success-solid\",\n error: \"checked:border-mari-error-solid\",\n warning: \"checked:border-mari-warning-solid\",\n info: \"checked:border-mari-info-solid\",\n neutral: \"checked:border-mari-neutral-solid\",\n};\n\n/** Radio'nun dış halkası seçiliyken rol rengi (outline varyantı — içi boş, nokta ayrı). */\nexport const checkedBorderStrongClass: Record<ColorRole, string> = {\n primary: \"checked:border-mari-primary\",\n accent: \"checked:border-mari-accent\",\n success: \"checked:border-mari-success\",\n error: \"checked:border-mari-error\",\n warning: \"checked:border-mari-warning\",\n info: \"checked:border-mari-info\",\n neutral: \"checked:border-mari-neutral\",\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/overlay.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type RefObject } from \"react\";\n\n/**\n * Kenardan açılan modal katmanların (Drawer, NavDrawer) ortak davranışı.\n * Faz 13.6'dan önce bu mantık yalnız `menu/_shared/NavDrawer.tsx`'te vardı;\n * `Drawer`da HİÇBİRİ yoktu (odak tuzağı, Escape, kaydırma kilidi, portal) —\n * kapalı Drawer DOM'da kalıyor, içindeki düğmeler Tab ile odaklanabiliyordu.\n * Artık tek yerde.\n */\n\nexport const FOCUSABLE_SELECTOR =\n 'button:not([disabled]), a[href], input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * Gerçekten odaklanabilen öğeler. `aria-hidden`/`inert` bir atanın içindekiler\n * elenir: iskelette gerçek içerik `SkeletonSlot` ile görünmez kopya olarak\n * DOM'da kalır (`visibility: hidden` → `focus()` sessizce başarısız olur);\n * bunlar sayılırsa odak tuzağının ilk/son öğesi görünmez bir düğme olur ve\n * Tab takılır.\n */\nexport function getFocusables(root: ParentNode): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n (el) => !el.closest('[aria-hidden=\"true\"], [inert]')\n );\n}\n\nexport function firstFocusable(root: ParentNode): HTMLElement | null {\n return getFocusables(root)[0] ?? null;\n}\n\n/** Öğe var ve iskeletin görünmez kopyasında (aria-hidden/inert) değilse kendisi. */\nexport function reachable(el: HTMLElement | null | undefined): HTMLElement | null {\n return el && !el.closest('[aria-hidden=\"true\"], [inert]') ? el : null;\n}\n\n/**\n * İskelet → içerik geldi: iskelette odak \"Kapat\"a (ya da panele) düşer;\n * içerik gelince odak hâlâ orada ise normal ilk odağa taşınır. Kullanıcı\n * bu arada odağı başka yere taşıdıysa dokunulmaz.\n */\nexport function useRefocusAfterSkeleton(\n open: boolean,\n skeleton: boolean,\n panelRef: RefObject<HTMLElement | null>,\n getInitialFocus: (panel: HTMLElement) => HTMLElement | null | undefined,\n closeSelector: string\n) {\n const wasSkeleton = useRef(skeleton);\n const getInitialFocusRef = useRef(getInitialFocus);\n getInitialFocusRef.current = getInitialFocus;\n useEffect(() => {\n const panel = panelRef.current;\n if (open && wasSkeleton.current && !skeleton && panel) {\n const active = document.activeElement;\n if (active === panel || (active instanceof HTMLElement && active.matches(closeSelector))) {\n const target = getInitialFocusRef.current(panel);\n if (target && target !== active) target.focus();\n }\n }\n wasSkeleton.current = skeleton;\n }, [skeleton, open, panelRef, closeSelector]);\n}\n\n/**\n * Açılışta hemen mount; kapanışta `exitMs` (çıkış animasyonu) bitince\n * unmount. `mounted` false iken hiç render etmeyin.\n */\nexport function usePresence(open: boolean, exitMs: number): boolean {\n const [mounted, setMounted] = useState(open);\n useEffect(() => {\n if (open) {\n setMounted(true);\n return;\n }\n const timer = setTimeout(() => setMounted(false), exitMs);\n return () => clearTimeout(timer);\n }, [open, exitMs]);\n return open || mounted;\n}\n\nexport interface ModalBehaviorOptions {\n /** Escape kapatsın mı. Varsayılan: `true`. */\n closeOnEscape?: boolean;\n /** Sayfa kaydırmasını kilitle. Varsayılan: `true`. */\n lockScroll?: boolean;\n /**\n * Açılışta odaklanacak öğeyi seçer. Verilmezse: `[data-autofocus]` → ilk\n * odaklanabilir → panelin kendisi.\n */\n getInitialFocus?: (panel: HTMLElement) => HTMLElement | null | undefined;\n}\n\n/** `[data-autofocus]` — kendisi odaklanabilir değilse (bileşen data-* iletmiyorsa) içindeki ilk odaklanabilir. */\nexport function findAutofocus(root: ParentNode): HTMLElement | null {\n const auto = root.querySelector<HTMLElement>(\"[data-autofocus]\");\n if (!auto || auto.closest('[aria-hidden=\"true\"], [inert]')) return null;\n return auto.matches(FOCUSABLE_SELECTOR) ? auto : firstFocusable(auto);\n}\n\n/**\n * Açıkken:\n * - sayfa kaydırması kilitlenir (kaydırma çubuğu genişliği kadar sağ dolgu\n * eklenir — kilitlenince içerik yana kaymasın),\n * - odak panelin ilk odaklanabilir öğesine (yoksa panelin kendisine) taşınır\n * ve Tab/Shift+Tab ile panel içinde döner,\n * - Escape `onClose` çağırır,\n * - kapanınca odak açılıştan önceki öğeye (genelde tetikleyici) döner.\n */\nexport function useModalBehavior(\n open: boolean,\n panelRef: RefObject<HTMLElement | null>,\n onClose: () => void,\n { closeOnEscape = true, lockScroll = true, getInitialFocus }: ModalBehaviorOptions = {}\n) {\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n const getInitialFocusRef = useRef(getInitialFocus);\n getInitialFocusRef.current = getInitialFocus;\n\n useEffect(() => {\n if (!open) return;\n const panel = panelRef.current;\n const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n\n const { body, documentElement } = document;\n const previousOverflow = body.style.overflow;\n const previousPaddingRight = body.style.paddingRight;\n if (lockScroll) {\n const scrollbar = window.innerWidth - documentElement.clientWidth;\n body.style.overflow = \"hidden\";\n if (scrollbar > 0) body.style.paddingRight = `${scrollbar}px`;\n }\n\n if (panel) {\n const target = getInitialFocusRef.current\n ? getInitialFocusRef.current(panel)\n : (findAutofocus(panel) ?? firstFocusable(panel));\n (target ?? panel).focus();\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && closeOnEscape) {\n // İçteki açılır bir parça (Select listesi, DatePicker/Popover paneli) Escape'i zaten işlediyse\n // yalnız o kapanır — pencere değil.\n if (event.defaultPrevented) return;\n event.preventDefault();\n onCloseRef.current();\n return;\n }\n if (event.key !== \"Tab\" || !panel) return;\n const focusables = getFocusables(panel);\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (!first || !last) {\n event.preventDefault();\n return;\n }\n const active = document.activeElement;\n if (event.shiftKey && (active === first || !panel.contains(active))) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && (active === last || !panel.contains(active))) {\n event.preventDefault();\n first.focus();\n }\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n if (lockScroll) {\n body.style.overflow = previousOverflow;\n body.style.paddingRight = previousPaddingRight;\n }\n previouslyFocused?.focus();\n };\n }, [open, panelRef, closeOnEscape, lockScroll]);\n}\n"],"mappings":";AAEA,SAAS,WAAW,QAAQ,gBAAgC;AAUrD,IAAM,qBACX;AASK,SAAS,cAAc,MAAiC;AAC7D,SAAO,MAAM,KAAK,KAAK,iBAA8B,kBAAkB,CAAC,EAAE;AAAA,IACxE,CAAC,OAAO,CAAC,GAAG,QAAQ,+BAA+B;AAAA,EACrD;AACF;AAEO,SAAS,eAAe,MAAsC;AACnE,SAAO,cAAc,IAAI,EAAE,CAAC,KAAK;AACnC;AAGO,SAAS,UAAU,IAAwD;AAChF,SAAO,MAAM,CAAC,GAAG,QAAQ,+BAA+B,IAAI,KAAK;AACnE;AAOO,SAAS,wBACd,MACA,UACA,UACA,iBACA,eACA;AACA,QAAM,cAAc,OAAO,QAAQ;AACnC,QAAM,qBAAqB,OAAO,eAAe;AACjD,qBAAmB,UAAU;AAC7B,YAAU,MAAM;AACd,UAAM,QAAQ,SAAS;AACvB,QAAI,QAAQ,YAAY,WAAW,CAAC,YAAY,OAAO;AACrD,YAAM,SAAS,SAAS;AACxB,UAAI,WAAW,SAAU,kBAAkB,eAAe,OAAO,QAAQ,aAAa,GAAI;AACxF,cAAM,SAAS,mBAAmB,QAAQ,KAAK;AAC/C,YAAI,UAAU,WAAW,OAAQ,QAAO,MAAM;AAAA,MAChD;AAAA,IACF;AACA,gBAAY,UAAU;AAAA,EACxB,GAAG,CAAC,UAAU,MAAM,UAAU,aAAa,CAAC;AAC9C;AAMO,SAAS,YAAY,MAAe,QAAyB;AAClE,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,YAAU,MAAM;AACd,QAAI,MAAM;AACR,iBAAW,IAAI;AACf;AAAA,IACF;AACA,UAAM,QAAQ,WAAW,MAAM,WAAW,KAAK,GAAG,MAAM;AACxD,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,MAAM,MAAM,CAAC;AACjB,SAAO,QAAQ;AACjB;AAeO,SAAS,cAAc,MAAsC;AAClE,QAAM,OAAO,KAAK,cAA2B,kBAAkB;AAC/D,MAAI,CAAC,QAAQ,KAAK,QAAQ,+BAA+B,EAAG,QAAO;AACnE,SAAO,KAAK,QAAQ,kBAAkB,IAAI,OAAO,eAAe,IAAI;AACtE;AAWO,SAAS,iBACd,MACA,UACA,SACA,EAAE,gBAAgB,MAAM,aAAa,MAAM,gBAAgB,IAA0B,CAAC,GACtF;AACA,QAAM,aAAa,OAAO,OAAO;AACjC,aAAW,UAAU;AACrB,QAAM,qBAAqB,OAAO,eAAe;AACjD,qBAAmB,UAAU;AAE7B,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,UAAM,QAAQ,SAAS;AACvB,UAAM,oBAAoB,SAAS,yBAAyB,cAAc,SAAS,gBAAgB;AAEnG,UAAM,EAAE,MAAM,gBAAgB,IAAI;AAClC,UAAM,mBAAmB,KAAK,MAAM;AACpC,UAAM,uBAAuB,KAAK,MAAM;AACxC,QAAI,YAAY;AACd,YAAM,YAAY,OAAO,aAAa,gBAAgB;AACtD,WAAK,MAAM,WAAW;AACtB,UAAI,YAAY,EAAG,MAAK,MAAM,eAAe,GAAG,SAAS;AAAA,IAC3D;AAEA,QAAI,OAAO;AACT,YAAM,SAAS,mBAAmB,UAC9B,mBAAmB,QAAQ,KAAK,IAC/B,cAAc,KAAK,KAAK,eAAe,KAAK;AACjD,OAAC,UAAU,OAAO,MAAM;AAAA,IAC1B;AAEA,UAAM,gBAAgB,CAAC,UAAyB;AAC9C,UAAI,MAAM,QAAQ,YAAY,eAAe;AAG3C,YAAI,MAAM,iBAAkB;AAC5B,cAAM,eAAe;AACrB,mBAAW,QAAQ;AACnB;AAAA,MACF;AACA,UAAI,MAAM,QAAQ,SAAS,CAAC,MAAO;AACnC,YAAM,aAAa,cAAc,KAAK;AACtC,YAAM,QAAQ,WAAW,CAAC;AAC1B,YAAM,OAAO,WAAW,WAAW,SAAS,CAAC;AAC7C,UAAI,CAAC,SAAS,CAAC,MAAM;AACnB,cAAM,eAAe;AACrB;AAAA,MACF;AACA,YAAM,SAAS,SAAS;AACxB,UAAI,MAAM,aAAa,WAAW,SAAS,CAAC,MAAM,SAAS,MAAM,IAAI;AACnE,cAAM,eAAe;AACrB,aAAK,MAAM;AAAA,MACb,WAAW,CAAC,MAAM,aAAa,WAAW,QAAQ,CAAC,MAAM,SAAS,MAAM,IAAI;AAC1E,cAAM,eAAe;AACrB,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AACA,aAAS,iBAAiB,WAAW,aAAa;AAElD,WAAO,MAAM;AACX,eAAS,oBAAoB,WAAW,aAAa;AACrD,UAAI,YAAY;AACd,aAAK,MAAM,WAAW;AACtB,aAAK,MAAM,eAAe;AAAA,MAC5B;AACA,yBAAmB,MAAM;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,eAAe,UAAU,CAAC;AAChD;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/drawer/Drawer.tsx","../src/drawer/utils.ts"],"sourcesContent":["\"use client\";\n\nimport React, { useId, useRef } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { XIcon } from \"lucide-react\";\nimport { cn } from \"@mari-ui/core\";\nimport { Skeleton, SkeletonBlock } from \"../skeleton\";\nimport { ContentSkeleton } from \"../lib/ContentSkeleton\";\nimport { useScrollable } from \"../lib/useScrollable\";\nimport { touchTargetSquareClass } from \"../lib/sizeClasses\";\nimport { findAutofocus, firstFocusable, useModalBehavior, usePresence, useRefocusAfterSkeleton } from \"../lib/overlay\";\nimport type { DrawerProps } from \"./types\";\nimport { getPanelClass, getTranslateClass, isSide } from \"./utils\";\n\nexport type { DrawerProps };\n\nconst EXIT_MS = 300;\n\n/**\n * Açılışta odak sırası: `[data-autofocus]` → gövdedeki ilk alan → Kapat →\n * panel. Başlıktaki `extra` aksiyonlarına ASLA ilk odak verilmez — Faz 13.6\n * incelemesinde yükleniyor durumunda açılan düzenleme çekmecesinde ilk odak\n * \"Sil\" düğmesine gidiyordu (Enter'a basan kullanıcı kaydı silebilirdi).\n */\nfunction getDrawerInitialFocus(panel: HTMLElement): HTMLElement | null {\n const body = panel.querySelector<HTMLElement>(\"[data-drawer-body]\");\n return findAutofocus(panel) ?? (body && firstFocusable(body)) ?? panel.querySelector<HTMLElement>(\"[data-drawer-close]\");\n}\n\n/*\n * Ölçülecek içerik yoksa (başlık/alt çubuk da veriden geliyor ya da\n * yerleşimsiz ortam) gösterilen genel yer tutucular.\n */\nconst TITLE_PLACEHOLDER = (\n <div className=\"flex flex-col gap-2 py-1\">\n <SkeletonBlock active width=\"45%\" height=\"1rem\" radius=\"sm\" />\n </div>\n);\n\n/** Alt çubuğun genel iskeleti: en yaygın düzen sağa yaslı İptal / Kaydet. */\nconst FOOTER_PLACEHOLDER = (\n <div className=\"flex h-full items-center justify-end gap-2\">\n <SkeletonBlock active width=\"4.5rem\" height=\"2rem\" />\n <SkeletonBlock active width=\"4.5rem\" height=\"2rem\" />\n </div>\n);\n\n/** Özel `width`/`height` — yine de ekranı taşmasın. */\nfunction getCustomSizeStyle(side: boolean, custom: boolean, width?: number | string, height?: number | string): React.CSSProperties | undefined {\n if (!custom) return undefined;\n return side ? { width, maxWidth: \"calc(100vw - 3rem)\" } : { height, maxHeight: \"90dvh\" };\n}\n\n/**\n * Faz 13.6 — yapı ant.design Drawer'ından (başlık 16/24px dolgu + 16px/600,\n * gövde 24px, alt çubuk), görünüm kendi token'larımızdan; overlay davranışı\n * `lib/overlay.ts`'te NavDrawer ile ortak.\n *\n * Eski sürümdeki sorunlar:\n * - `role=\"dialog\"`/`aria-modal`/erişilebilir ad yoktu; odak içeri\n * taşınmıyor, Tab sayfaya kaçıyor, Escape kapatmıyordu.\n * - Kapalıyken DOM'da kalıyordu (sadece opacity) — içindeki düğmeler Tab ile\n * odaklanabiliyordu. Artık kapanış animasyonundan sonra unmount.\n * - Sayfa kaydırması kilitlenmiyordu; portal yoktu (overflow/transform'lu bir\n * atanın içinde kırpılabiliyordu).\n * - Başlık ortalıydı; yan çekmece mobilde ekranı taşıyordu (`w-96` sabit).\n * - `loading` düz \"Yükleniyor...\" metniydi.\n *\n * Faz 15.6 — `skeleton` artık yalnız gövdeyi değil\n * başlık/açıklama/extra/alt çubuğu da iskelete çevirir; Kapat düğmesi canlı\n * kalır. Her bölge `ContentSkeleton` ile içeriğin kendi şeklinde (satır satır\n * metin, alan alan form, düğme düğme alt çubuk) iskelete döner; gerçek içerik\n * görünmez olarak yerinde kalır → yükseklik zıplamaz.\n * Görünmez kopyalar `aria-hidden` bölgede — odak tuzağı onları atlar.\n */\nexport function Drawer({\n open,\n onClose,\n position = \"right\",\n size = \"md\",\n width,\n height,\n title,\n description,\n extra,\n footer,\n children,\n showCloseButton = true,\n closeButtonPosition = \"right\",\n skeleton = false,\n mask = true,\n maskClosable = true,\n keyboard = true,\n \"aria-label\": ariaLabel,\n className,\n bodyClassName,\n}: DrawerProps) {\n const panelRef = useRef<HTMLDivElement>(null);\n const titleId = useId();\n const descriptionId = useId();\n const present = usePresence(open, EXIT_MS);\n const bodyRef = useRef<HTMLDivElement>(null);\n const bodyScrollable = useScrollable(bodyRef, \"y\", [children, skeleton, present]);\n useModalBehavior(open, panelRef, onClose, { closeOnEscape: keyboard, getInitialFocus: getDrawerInitialFocus });\n\n // İskelet → içerik geldi: odak hâlâ Kapat'ta/panelde ise forma taşı.\n useRefocusAfterSkeleton(open, skeleton, panelRef, getDrawerInitialFocus, \"[data-drawer-close]\");\n\n if (!present || typeof document === \"undefined\") return null;\n\n const side = isSide(position);\n const customSize = side ? width !== undefined : height !== undefined;\n const sizeStyle = getCustomSizeStyle(side, customSize, width, height);\n const hasHeader = Boolean(title || extra || showCloseButton);\n\n const closeButton = showCloseButton && (\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Kapat\"\n data-drawer-close\n className={cn(\n \"relative inline-flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-mari-muted transition-colors\",\n \"hover:bg-mari-surface-alt hover:text-mari-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-mari-ring\",\n touchTargetSquareClass.md,\n closeButtonPosition === \"left\" ? \"-ml-1.5\" : \"-mr-1.5\"\n )}\n >\n <XIcon size={18} aria-hidden />\n </button>\n );\n\n return createPortal(\n <div className={cn(\"fixed inset-0 z-mari-drawer\", !open && \"pointer-events-none\")}>\n {mask && (\n <div\n aria-hidden\n onClick={maskClosable ? onClose : undefined}\n className={cn(\n \"absolute inset-0 bg-mari-scrim transition-opacity duration-300 motion-reduce:transition-none starting:opacity-0\",\n open ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n )}\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n aria-label={title ? undefined : ariaLabel}\n aria-describedby={description ? descriptionId : undefined}\n aria-busy={skeleton || undefined}\n tabIndex={-1}\n style={sizeStyle}\n className={cn(getPanelClass(position, size, customSize), getTranslateClass(position, open), className)}\n >\n {position === \"bottom\" && (\n <div aria-hidden className=\"flex justify-center pt-2.5\">\n <span className=\"h-1 w-10 rounded-full bg-mari-border\" />\n </div>\n )}\n\n {hasHeader && (\n <div className={cn(\"flex shrink-0 items-start gap-3 border-b border-mari-border px-4 py-4 sm:px-6\", position === \"bottom\" && \"pt-2\")}>\n {closeButtonPosition === \"left\" && closeButton}\n <ContentSkeleton on={skeleton} fallback={TITLE_PLACEHOLDER} className=\"min-w-0 flex-1 self-center\">\n <div className=\"min-w-0 flex-1 self-center\">\n {title && (\n <h2 id={titleId} className=\"truncate text-base font-semibold leading-6 text-mari-foreground\">\n {title}\n </h2>\n )}\n {description && (\n <p id={descriptionId} className=\"mt-0.5 text-sm text-mari-muted\">\n {description}\n </p>\n )}\n </div>\n </ContentSkeleton>\n {extra && (\n <ContentSkeleton on={skeleton} fallback={null} className=\"shrink-0 self-center\">\n <div className=\"flex shrink-0 items-center gap-2 self-center\">{extra}</div>\n </ContentSkeleton>\n )}\n {closeButtonPosition === \"right\" && closeButton}\n </div>\n )}\n\n <div\n ref={bodyRef}\n data-drawer-body\n // Taşan ve içinde odaklanabilir öğe olmayan gövde de klavyeyle kaydırılabilsin (axe scrollable-region-focusable).\n tabIndex={bodyScrollable && !skeleton ? 0 : undefined}\n className={cn(\n \"min-h-0 flex-1 overflow-y-auto overscroll-contain p-4 sm:p-6\",\n \"focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-mari-ring\",\n bodyClassName\n )}\n >\n <ContentSkeleton on={skeleton} fallback={<Skeleton active paragraph={{ rows: 6 }} />}>\n {children}\n </ContentSkeleton>\n </div>\n\n {footer && (\n <div className=\"shrink-0 border-t border-mari-border px-4 py-3 sm:px-6\">\n <ContentSkeleton on={skeleton} fallback={FOOTER_PLACEHOLDER}>\n {footer}\n </ContentSkeleton>\n </div>\n )}\n </div>\n </div>,\n document.body\n );\n}\n","import { cn } from \"@mari-ui/core\";\nimport type { DrawerPosition, DrawerSize } from \"./types\";\n\n/**\n * Yan çekmece genişliği / üst-alt yüksekliği. Yan çekmece dar ekranda\n * `100vw - 3rem`i aşmaz — solda örtüden bir şerit kalır, dokunarak\n * kapatılabilir ve kullanıcı hâlâ sayfada olduğunu görür.\n */\nconst SIDE_WIDTH: Record<DrawerSize, string> = {\n sm: \"w-[min(20rem,calc(100vw-3rem))]\",\n md: \"w-[min(25rem,calc(100vw-3rem))]\",\n lg: \"w-[min(40rem,calc(100vw-3rem))]\",\n};\nconst EDGE_HEIGHT: Record<DrawerSize, string> = {\n sm: \"h-[min(16rem,85dvh)]\",\n md: \"h-[min(28rem,85dvh)]\",\n lg: \"h-[min(40rem,90dvh)]\",\n};\n\nexport const isSide = (position: DrawerPosition) => position === \"left\" || position === \"right\";\n\nexport function getPanelClass(position: DrawerPosition, size: DrawerSize, custom: boolean): string {\n const side = isSide(position);\n return cn(\n \"absolute flex flex-col bg-mari-surface text-mari-foreground shadow-mari-xl outline-none\",\n \"transition-transform duration-300 ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:transition-none\",\n position === \"right\" && \"inset-y-0 right-0 border-l border-mari-border\",\n position === \"left\" && \"inset-y-0 left-0 border-r border-mari-border\",\n position === \"top\" && \"inset-x-0 top-0 rounded-b-xl border-b border-mari-border\",\n // Alt çekmece = mobil \"bottom sheet\": yuvarlak üst köşeler + tutamaç.\n position === \"bottom\" && \"inset-x-0 bottom-0 rounded-t-xl border-t border-mari-border pb-[env(safe-area-inset-bottom)]\",\n !custom && (side ? SIDE_WIDTH[size] : EDGE_HEIGHT[size])\n );\n}\n\n/**\n * Açıkken yerinde; `starting:` (@starting-style) ilk boyamada kapalı\n * konumdan başlatır → mount anında kayarak girer. Kapanışta panel\n * `usePresence` süresi boyunca DOM'da kalıp dışarı kayar.\n */\nconst OPEN: Record<DrawerPosition, string> = {\n right: \"translate-x-0 starting:translate-x-full\",\n left: \"translate-x-0 starting:-translate-x-full\",\n top: \"translate-y-0 starting:-translate-y-full\",\n bottom: \"translate-y-0 starting:translate-y-full\",\n};\nconst CLOSED: Record<DrawerPosition, string> = {\n right: \"translate-x-full\",\n left: \"-translate-x-full\",\n top: \"-translate-y-full\",\n bottom: \"translate-y-full\",\n};\n\nexport function getTranslateClass(position: DrawerPosition, open: boolean): string {\n return open ? OPEN[position] : CLOSED[position];\n}\n"],"mappings":"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","names":["cn","cn"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/fieldContext.ts"],"sourcesContent":["\"use client\";\n\nimport type React from \"react\";\nimport { createContext, useContext, useEffect } from \"react\";\nimport type { ColorRole } from \"@mari-ui/core\";\n\n/**\n * Faz 16.1 — `Field`in içindeki kontrole geçirdiği bağlantılar. `lib`te\n * duruyor (field/ klasöründe değil) çünkü her kontrol bunu import eder;\n * tsup ortak parçaya (chunk) koyar, tek bir context örneği olur.\n */\nexport interface FieldContextValue {\n /** Kontrolün id'si — `<label htmlFor>` buna bağlı. */\n controlId: string;\n labelId: string;\n /** İpucu ve/veya hata metninin id'leri (boşlukla ayrılmış); yoksa `undefined`. */\n describedBy: string | undefined;\n invalid: boolean;\n required: boolean;\n disabled: boolean;\n /** Grup kontrolleri (RadioGroup, Segmented, OtpInput) çağırır: etiket `<label for>` değil grubun adı olur. */\n markGroup: () => void;\n /** Kontrol kendi `id`sini verdiyse etiketin `htmlFor`u ona dönsün. */\n setControlId: (id: string | undefined) => void;\n /** Field iskelette: içindeki kontrol de iskelet çizer (tek prop kuralı). */\n skeleton: boolean;\n}\n\nexport const FieldContext = createContext<FieldContextValue | null>(null);\n\nconst joinIds = (...ids: Array<string | undefined>) => ids.filter(Boolean).join(\" \") || undefined;\n\nexport interface FieldControlProps {\n id?: string;\n \"aria-describedby\"?: string;\n \"aria-invalid\"?: Exclude<React.AriaAttributes[\"aria-invalid\"], undefined>;\n required?: boolean;\n disabled?: boolean;\n color?: ColorRole;\n skeleton?: boolean;\n}\n\n/**\n * Tek bir alanı olan kontroller (Input, Select, InputNumber…) için. Field\n * içinde değilse verilen prop'ları olduğu gibi döner. İçindeyse eksikleri\n * Field'dan tamamlar — kontrole AÇIKÇA verilen prop her zaman kazanır;\n * `aria-describedby` ise birleştirilir (ikisi de okunsun).\n */\nexport function useFieldControl<P extends FieldControlProps>(props: P): P & FieldControlProps {\n const field = useContext(FieldContext);\n const setControlId = field?.setControlId;\n const ownId = props.id;\n useEffect(() => {\n if (!setControlId || ownId === undefined) return;\n setControlId(ownId);\n return () => setControlId(undefined);\n }, [setControlId, ownId]);\n if (!field) return props;\n return {\n ...props,\n id: props.id ?? field.controlId,\n \"aria-describedby\": joinIds(props[\"aria-describedby\"], field.describedBy),\n \"aria-invalid\": props[\"aria-invalid\"] ?? (field.invalid || undefined),\n required: props.required ?? (field.required || undefined),\n disabled: props.disabled ?? (field.disabled || undefined),\n color: props.color ?? (field.invalid ? \"error\" : undefined),\n skeleton: props.skeleton ?? (field.skeleton || undefined),\n };\n}\n\n/**\n * Grup kontrolleri (RadioGroup, Segmented, OtpInput, Transfer) için: kontrolün\n * kendi `skeleton`u verilmediyse Field'ınki geçerli.\n */\nexport function useFieldSkeleton(own: boolean | undefined): boolean {\n const field = useContext(FieldContext);\n return own ?? field?.skeleton ?? false;\n}\n\nexport interface FieldGroupProps {\n \"aria-labelledby\"?: string;\n \"aria-label\"?: string;\n \"aria-describedby\"?: string;\n disabled?: boolean;\n}\n\n/**\n * Grup kontrolleri için: Field'ın etiketi grubun adı olur (`aria-labelledby`)\n * — grup tek bir odaklanabilir alan olmadığından `<label htmlFor>` bağlanamaz.\n * Kontrol kendi `aria-label`/`aria-labelledby`sini verdiyse o kazanır.\n */\nexport function useFieldGroup<P extends FieldGroupProps>(props: P, enabled = true): P & FieldGroupProps & { \"aria-invalid\"?: true; \"aria-required\"?: true } {\n const field = useContext(FieldContext);\n const markGroup = enabled ? field?.markGroup : undefined;\n useEffect(() => markGroup?.(), [markGroup]);\n if (!field || !enabled) return props;\n const named = props[\"aria-labelledby\"] !== undefined || props[\"aria-label\"] !== undefined;\n return {\n ...props,\n \"aria-labelledby\": named ? props[\"aria-labelledby\"] : field.labelId,\n \"aria-describedby\": joinIds(props[\"aria-describedby\"], field.describedBy),\n disabled: props.disabled ?? (field.disabled || undefined),\n \"aria-invalid\": field.invalid ? true : undefined,\n \"aria-required\": field.required ? true : undefined,\n };\n}\n"],"mappings":";AAGA,SAAS,eAAe,YAAY,iBAAiB;AAyB9C,IAAM,eAAe,cAAwC,IAAI;AAExE,IAAM,UAAU,IAAI,QAAmC,IAAI,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK;AAkBjF,SAAS,gBAA6C,OAAiC;AAC5F,QAAM,QAAQ,WAAW,YAAY;AACrC,QAAM,eAAe,OAAO;AAC5B,QAAM,QAAQ,MAAM;AACpB,YAAU,MAAM;AACd,QAAI,CAAC,gBAAgB,UAAU,OAAW;AAC1C,iBAAa,KAAK;AAClB,WAAO,MAAM,aAAa,MAAS;AAAA,EACrC,GAAG,CAAC,cAAc,KAAK,CAAC;AACxB,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,MAAM,MAAM,MAAM;AAAA,IACtB,oBAAoB,QAAQ,MAAM,kBAAkB,GAAG,MAAM,WAAW;AAAA,IACxE,gBAAgB,MAAM,cAAc,MAAM,MAAM,WAAW;AAAA,IAC3D,UAAU,MAAM,aAAa,MAAM,YAAY;AAAA,IAC/C,UAAU,MAAM,aAAa,MAAM,YAAY;AAAA,IAC/C,OAAO,MAAM,UAAU,MAAM,UAAU,UAAU;AAAA,IACjD,UAAU,MAAM,aAAa,MAAM,YAAY;AAAA,EACjD;AACF;AAMO,SAAS,iBAAiB,KAAmC;AAClE,QAAM,QAAQ,WAAW,YAAY;AACrC,SAAO,OAAO,OAAO,YAAY;AACnC;AAcO,SAAS,cAAyC,OAAU,UAAU,MAA+E;AAC1J,QAAM,QAAQ,WAAW,YAAY;AACrC,QAAM,YAAY,UAAU,OAAO,YAAY;AAC/C,YAAU,MAAM,YAAY,GAAG,CAAC,SAAS,CAAC;AAC1C,MAAI,CAAC,SAAS,CAAC,QAAS,QAAO;AAC/B,QAAM,QAAQ,MAAM,iBAAiB,MAAM,UAAa,MAAM,YAAY,MAAM;AAChF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,mBAAmB,QAAQ,MAAM,iBAAiB,IAAI,MAAM;AAAA,IAC5D,oBAAoB,QAAQ,MAAM,kBAAkB,GAAG,MAAM,WAAW;AAAA,IACxE,UAAU,MAAM,aAAa,MAAM,YAAY;AAAA,IAC/C,gBAAgB,MAAM,UAAU,OAAO;AAAA,IACvC,iBAAiB,MAAM,WAAW,OAAO;AAAA,EAC3C;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/empty/Empty.tsx"],"sourcesContent":["import React from \"react\";\nimport { InboxIcon } from \"lucide-react\";\nimport { cn } from \"@mari-ui/core\";\nimport { Button } from \"../button\";\nimport { skeletonBoxProps, type SkeletonableProps } from \"../lib/skeleton\";\n\nexport interface EmptyProps extends SkeletonableProps {\n title: string;\n description?: React.ReactNode;\n /** Tek birincil eylem. `onClick` (ya da `href`) olmadan buton çizilmez. */\n buttonText?: string;\n onClick?: () => void;\n /** Butonu bağlantı olarak çizer (başka sayfaya götüren eylem). */\n href?: string;\n icon?: React.ReactNode;\n buttonIcon?: React.ReactNode;\n /** Birden çok ya da özel eylem (ör. birincil + ikincil buton). Verilirse `buttonText` yok sayılır. */\n actions?: React.ReactNode;\n /** `md` (varsayılan): sayfa/bölüm. `sm`: kart, tablo, liste içi — daha az boşluk, küçük ikon. */\n size?: \"sm\" | \"md\";\n /**\n * Başlığın etiketi. Varsayılan `p`: boş durum bir belge BÖLÜMÜ değildir —\n * eskiden sabit `<h2>`'ydi, kart/tablo içinde başlık hiyerarşisini bozuyordu.\n * Sayfanın ana içeriği boşsa uygun bir başlık seviyesi verin.\n */\n titleAs?: \"p\" | \"h2\" | \"h3\" | \"h4\";\n className?: string;\n}\n\nconst SIZE = {\n sm: { root: \"py-8 px-4 gap-1.5\", icon: \"size-10 [&_svg]:size-5\", title: \"text-sm\", description: \"text-xs\", actionGap: \"mt-3\" },\n md: { root: \"py-16 px-4 gap-2\", icon: \"size-14 [&_svg]:size-7\", title: \"text-lg\", description: \"text-sm\", actionGap: \"mt-4\" },\n} as const;\n\n/**\n * Faz 15: varsayılan ikon `FileWarning` idi — boş durum bir HATA değil\n * (`InboxIcon`). İkon yumuşak bir daire içinde; başlık `h2` yerine `p`\n * (`titleAs`); `onClick` olmadan `buttonText` verilince işe yaramaz, devre dışı\n * bir buton çiziliyordu — artık buton yalnızca bir eylem varsa çıkar.\n */\n// Hook yok, browser API yok — saf sunum, \"use client\" gerekmiyor.\nexport function Empty({\n title,\n description,\n buttonText,\n onClick,\n href,\n icon,\n buttonIcon,\n actions,\n size = \"md\",\n titleAs: TitleTag = \"p\",\n className,\n skeleton = false,\n}: Readonly<EmptyProps>) {\n const s = SIZE[size];\n\n if (skeleton) {\n return (\n <div aria-hidden className={cn(\"flex flex-col items-center justify-center text-center\", s.root, className)}>\n <span {...skeletonBoxProps(cn(\"rounded-full\", s.icon))} />\n <span {...skeletonBoxProps(cn(\"mt-1 h-4 w-40 rounded-sm\"))} />\n {description && <span {...skeletonBoxProps(\"h-3 w-56 max-w-full rounded-sm\")} />}\n </div>\n );\n }\n\n const hasButton = Boolean(buttonText && (onClick || href));\n\n return (\n <div className={cn(\"flex flex-col items-center justify-center text-center\", s.root, className)}>\n <div aria-hidden className={cn(\"mb-1 flex items-center justify-center rounded-full bg-mari-surface-alt text-mari-muted\", s.icon)}>\n {icon ?? <InboxIcon />}\n </div>\n <TitleTag className={cn(\"font-semibold text-balance text-mari-foreground\", s.title)}>{title}</TitleTag>\n {description && <p className={cn(\"max-w-md text-pretty text-mari-muted\", s.description)}>{description}</p>}\n {actions ? (\n <div className={cn(\"flex flex-wrap items-center justify-center gap-2\", s.actionGap)}>{actions}</div>\n ) : (\n hasButton && (\n <div className={s.actionGap}>\n <Button color=\"primary\" size={size === \"sm\" ? \"sm\" : \"md\"} onClick={onClick} href={href} icon={buttonIcon}>\n {buttonText}\n </Button>\n </div>\n )\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;AACA,SAAS,iBAAiB;AAC1B,SAAS,UAAU;AAyDb,SACE,KADF;AA9BN,IAAM,OAAO;AAAA,EACX,IAAI,EAAE,MAAM,qBAAqB,MAAM,0BAA0B,OAAO,WAAW,aAAa,WAAW,WAAW,OAAO;AAAA,EAC7H,IAAI,EAAE,MAAM,oBAAoB,MAAM,0BAA0B,OAAO,WAAW,aAAa,WAAW,WAAW,OAAO;AAC9H;AASO,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,SAAS,WAAW;AAAA,EACpB;AAAA,EACA,WAAW;AACb,GAAyB;AACvB,QAAM,IAAI,KAAK,IAAI;AAEnB,MAAI,UAAU;AACZ,WACE,qBAAC,SAAI,eAAW,MAAC,WAAW,GAAG,yDAAyD,EAAE,MAAM,SAAS,GACvG;AAAA,0BAAC,UAAM,GAAG,iBAAiB,GAAG,gBAAgB,EAAE,IAAI,CAAC,GAAG;AAAA,MACxD,oBAAC,UAAM,GAAG,iBAAiB,GAAG,0BAA0B,CAAC,GAAG;AAAA,MAC3D,eAAe,oBAAC,UAAM,GAAG,iBAAiB,gCAAgC,GAAG;AAAA,OAChF;AAAA,EAEJ;AAEA,QAAM,YAAY,QAAQ,eAAe,WAAW,KAAK;AAEzD,SACE,qBAAC,SAAI,WAAW,GAAG,yDAAyD,EAAE,MAAM,SAAS,GAC3F;AAAA,wBAAC,SAAI,eAAW,MAAC,WAAW,GAAG,0FAA0F,EAAE,IAAI,GAC5H,kBAAQ,oBAAC,aAAU,GACtB;AAAA,IACA,oBAAC,YAAS,WAAW,GAAG,mDAAmD,EAAE,KAAK,GAAI,iBAAM;AAAA,IAC3F,eAAe,oBAAC,OAAE,WAAW,GAAG,wCAAwC,EAAE,WAAW,GAAI,uBAAY;AAAA,IACrG,UACC,oBAAC,SAAI,WAAW,GAAG,oDAAoD,EAAE,SAAS,GAAI,mBAAQ,IAE9F,aACE,oBAAC,SAAI,WAAW,EAAE,WAChB,8BAAC,UAAO,OAAM,WAAU,MAAM,SAAS,OAAO,OAAO,MAAM,SAAkB,MAAY,MAAM,YAC5F,sBACH,GACF;AAAA,KAGN;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/segmented/Segmented.tsx"],"sourcesContent":["\"use client\";\n\nimport React, { useId, useLayoutEffect, useRef, useState } from \"react\";\nimport { cn, useControllableState, type Size } from \"@mari-ui/core\";\nimport { useFieldGroup, useFieldSkeleton } from \"../lib/fieldContext\";\nimport { skeletonBoxProps } from \"../lib/skeleton\";\nimport { touchTargetClass } from \"../lib/sizeClasses\";\nimport type { SegmentedOption, SegmentedProps, SegmentedValue } from \"./types\";\n\nexport type { SegmentedProps };\n\n/** Kapsayıcı 2px dolgulu; dilim yüksekliği + 4px = Input/Select yüksekliği (24/32/40). */\nconst SEGMENT_SIZE: Record<Size, string> = {\n sm: \"h-5 px-2 text-xs gap-1\",\n md: \"h-7 px-3 text-sm gap-1.5\",\n lg: \"h-9 px-4 text-base gap-2\",\n};\n\nconst normalize = (option: SegmentedValue | SegmentedOption): SegmentedOption =>\n typeof option === \"object\" ? option : { value: option, label: String(option) };\n\n/**\n * Seçili dilimin altında kayan zemin (\"thumb\"). Konumu DOM'dan ölçülür ve\n * boyut değişince (pencere, `block`, yazı tipi yüklenmesi) yeniden ölçülür.\n * Ölçülene kadar (SSR, ilk kare) seçili dilim zemini kendisi çizer — boş görünmez.\n */\nfunction useThumb(containerRef: React.RefObject<HTMLDivElement | null>, selectedIndex: number) {\n const [rect, setRect] = useState<{ left: number; width: number } | null>(null);\n useLayoutEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n const measure = () => {\n const segment = container.querySelectorAll<HTMLElement>(\"[data-segment]\")[selectedIndex];\n setRect(segment ? { left: segment.offsetLeft, width: segment.offsetWidth } : null);\n };\n measure();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(measure);\n observer.observe(container);\n return () => observer.disconnect();\n }, [containerRef, selectedIndex]);\n return rect;\n}\n\n/**\n * Faz 16.1 — ant.design Segmented'ın yapısı, Tabs `pills`in görünümü (aynı\n * zemin, aynı kayan beyaz dilim). Tabs'ten ayrı çünkü anlamı farklı: Tabs bir\n * PANEL değiştirir (`tablist`), Segmented bir DEĞER seçer — form kontrolü.\n *\n * Erişilebilirlik: gerçek `<input type=\"radio\">`lar + `role=\"radiogroup\"`.\n * Ok tuşları seçimi taşır, Tab gruba tek durakla girer, `name` ile native\n * forma katılır, disabled seçenek atlanır — hepsi tarayıcının kendisinden.\n * Yalnız ikonlu seçenekte `aria-label` verin.\n */\nexport function Segmented({\n options,\n value,\n defaultValue,\n onChange,\n block = false,\n size = \"md\",\n disabled: ownDisabled = false,\n name,\n \"aria-label\": ownAriaLabel,\n \"aria-labelledby\": ownAriaLabelledBy,\n className,\n skeleton: ownSkeleton,\n}: Readonly<SegmentedProps>) {\n // Field içindeyse etiketi grubun adı olur; ipucu/hata, zorunluluk ve devre dışı oradan.\n const field = useFieldGroup({ \"aria-label\": ownAriaLabel, \"aria-labelledby\": ownAriaLabelledBy, disabled: ownDisabled });\n const skeleton = useFieldSkeleton(ownSkeleton);\n const { \"aria-label\": ariaLabel, \"aria-labelledby\": ariaLabelledBy } = field;\n const disabled = !!field.disabled;\n const items = options.map(normalize);\n const fallbackName = useId();\n const groupName = name ?? fallbackName;\n const [current, setCurrent] = useControllableState<SegmentedValue | undefined>({\n value,\n defaultValue: defaultValue ?? items.find((o) => !o.disabled)?.value,\n onChange: onChange as ((v: SegmentedValue | undefined) => void) | undefined,\n });\n const containerRef = useRef<HTMLDivElement>(null);\n const selectedIndex = items.findIndex((o) => o.value === current);\n const thumb = useThumb(containerRef, selectedIndex);\n\n const containerClass = cn(\"relative isolate inline-flex max-w-full rounded-lg bg-mari-surface-alt p-0.5\", block && \"flex w-full\");\n\n const segments = items.map((option, index) => {\n const selected = index === selectedIndex;\n const optionDisabled = disabled || option.disabled;\n return (\n <label\n key={String(option.value)}\n data-segment=\"\"\n className={cn(\n \"relative flex min-w-0 cursor-pointer items-center justify-center rounded-md font-medium transition-colors duration-150\",\n SEGMENT_SIZE[size],\n touchTargetClass[size],\n block && \"flex-1\",\n selected ? \"text-mari-foreground\" : \"text-mari-muted hover:text-mari-foreground\",\n // Kayan zemin ölçülene kadar seçili dilim kendi zeminini çizer.\n selected && !thumb && \"bg-mari-surface shadow-mari-sm ring-1 ring-mari-border/60\",\n optionDisabled && \"cursor-not-allowed opacity-50 hover:text-mari-muted\",\n // Odak halkası dilimin kendisinde (radyo görünmez).\n \"has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-1 has-[:focus-visible]:outline-mari-ring\"\n )}\n >\n <input\n type=\"radio\"\n name={groupName}\n value={String(option.value)}\n checked={selected}\n disabled={optionDisabled}\n aria-label={option[\"aria-label\"]}\n onChange={() => setCurrent(option.value)}\n className=\"sr-only\"\n />\n {option.icon && (\n <span aria-hidden className=\"flex shrink-0 items-center [&>svg]:size-4\">\n {option.icon}\n </span>\n )}\n {option.label !== undefined && <span className=\"truncate\">{option.label}</span>}\n </label>\n );\n });\n\n if (skeleton) {\n // Gerçek dilimler görünmez olarak yerinde: iskelet ile yüklü hal birebir aynı genişlikte.\n return (\n <div {...skeletonBoxProps(cn(containerClass, \"rounded-lg\", className))}>\n <div className=\"invisible flex w-full\">{segments}</div>\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n role=\"radiogroup\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={field[\"aria-describedby\"]}\n aria-invalid={field[\"aria-invalid\"]}\n aria-required={field[\"aria-required\"]}\n aria-disabled={disabled || undefined}\n className={cn(containerClass, className)}\n >\n {thumb && selectedIndex >= 0 && (\n <span\n aria-hidden\n className=\"absolute inset-y-0.5 -z-10 rounded-md bg-mari-surface shadow-mari-sm ring-1 ring-mari-border/60 transition-[left,width] duration-200 ease-out motion-reduce:transition-none\"\n style={{ left: thumb.left, width: thumb.width }}\n />\n )}\n {segments}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/input-number/InputNumber.tsx","../src/input-number/utils.ts"],"sourcesContent":["\"use client\";\n\nimport React, { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { ChevronDownIcon, ChevronUpIcon, MinusIcon, PlusIcon } from \"lucide-react\";\nimport { cn, useControllableState } from \"@mari-ui/core\";\nimport { FIELD_BASE_CLASS, FIELD_DISABLED_CLASS, FIELD_MOBILE_TEXT_CLASS, getShapeClasses, getVariantClasses } from \"../input/utils\";\nimport { useFieldControl } from \"../lib/fieldContext\";\nimport { skeletonBoxProps } from \"../lib/skeleton\";\nimport { sizeClass, touchTargetClass } from \"../lib/sizeClasses\";\nimport type { InputNumberProps } from \"./types\";\nimport { clamp, formatForEditing, formatNumber, isAllowedInput, parseNumber, roundTo, stepValue, type NumberFormatConfig } from \"./utils\";\n\nexport type { InputNumberProps };\n\nconst HOLD_DELAY_MS = 400;\nconst HOLD_INTERVAL_MS = 70;\n\n/** Basılı tutunca adım tekrarlanır (400ms bekle, sonra 70ms'de bir). */\nfunction useHoldRepeat(action: (direction: 1 | -1) => void) {\n const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const actionRef = useRef(action);\n actionRef.current = action;\n const stop = () => clearTimeout(timer.current);\n useEffect(() => stop, []);\n const start = (direction: 1 | -1) => {\n stop();\n actionRef.current(direction);\n const repeat = () => {\n actionRef.current(direction);\n timer.current = setTimeout(repeat, HOLD_INTERVAL_MS);\n };\n timer.current = setTimeout(repeat, HOLD_DELAY_MS);\n };\n return { start, stop };\n}\n\n/**\n * Düğme sütunu boyuta göre ölçeklenir. `sm` kutunun iç yüksekliği 22px: iki\n * düğme + 1px ayraç 12px ikonla en az 25px istiyordu → düğmeler kutudan\n * taşıp alt ok kenarlığın üstüne biniyordu (kullanıcı bulgusu). İkon ve\n * genişlik boyutla birlikte küçülür; `min-h-0` düğmelerin paylaşımlı\n * yüksekliğe inmesine izin verir.\n */\nconst STEPPER_WIDTH: Record<NonNullable<InputNumberProps[\"size\"]>, string> = { sm: \"w-5\", md: \"w-6\", lg: \"w-7\" };\nconst STEPPER_ICON: Record<NonNullable<InputNumberProps[\"size\"]>, number> = { sm: 10, md: 12, lg: 14 };\n\nconst textOf = (node: React.ReactNode) => (typeof node === \"string\" || typeof node === \"number\" ? String(node) : \"\");\n\ninterface StepperProps {\n onStart: (direction: 1 | -1) => void;\n onStop: () => void;\n canIncrement: boolean;\n canDecrement: boolean;\n incrementLabel: string;\n decrementLabel: string;\n size: NonNullable<InputNumberProps[\"size\"]>;\n}\n\n/**\n * Fareyle: ant.design gibi sağda üst üste ▲/▼. Dokunmatikte (pointer-coarse)\n * yan yana −/+ — üst üste 16px'lik iki düğme parmakla vurulamaz; yatayda\n * her biri tam yükseklik + görünmez 44px hedef. Düğmeler Tab sırasında\n * değil (klavyede ↑/↓ zaten var, ant.design de böyle); `onPointerDown`\n * `preventDefault` ile odağı alandan almaz.\n */\nfunction Stepper({ onStart, onStop, canIncrement, canDecrement, incrementLabel, decrementLabel, size }: Readonly<StepperProps>) {\n const button = (direction: 1 | -1, enabled: boolean, label: string, fine: React.ReactNode, coarse: React.ReactNode) => (\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={label}\n disabled={!enabled}\n onPointerDown={(e) => {\n e.preventDefault();\n if (enabled) onStart(direction);\n }}\n onPointerUp={onStop}\n onPointerLeave={onStop}\n onPointerCancel={onStop}\n className={cn(\n \"relative flex min-h-0 flex-1 cursor-pointer items-center justify-center text-mari-muted transition-colors hover:bg-mari-surface-alt hover:text-mari-foreground disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent\",\n \"pointer-coarse:w-8 pointer-coarse:flex-none\",\n touchTargetClass[size]\n )}\n >\n <span className=\"pointer-coarse:hidden\">{fine}</span>\n <span className=\"hidden pointer-coarse:inline\">{coarse}</span>\n </button>\n );\n return (\n // DOM sırası [azalt, artır]: masaüstünde col-reverse ile artır üstte, dokunmatikte satırda azalt solda.\n <div\n className={cn(\n \"flex shrink-0 flex-col-reverse self-stretch overflow-hidden border-l border-mari-input [border-bottom-right-radius:inherit] [border-top-right-radius:inherit] pointer-coarse:w-auto pointer-coarse:flex-row [&>button+button]:border-b [&>button+button]:border-mari-input pointer-coarse:[&>button+button]:border-b-0 pointer-coarse:[&>button+button]:border-l\",\n STEPPER_WIDTH[size]\n )}\n >\n {button(-1, canDecrement, decrementLabel, <ChevronDownIcon size={STEPPER_ICON[size]} aria-hidden />, <MinusIcon size={16} aria-hidden />)}\n {button(1, canIncrement, incrementLabel, <ChevronUpIcon size={STEPPER_ICON[size]} aria-hidden />, <PlusIcon size={16} aria-hidden />)}\n </div>\n );\n}\n\n/**\n * Faz 16.1 — yapı ant.design InputNumber'dan; görünüm Input'la birebir.\n *\n * Metin alanı + `role=\"spinbutton\"`: odak dışında biçimli (\"1.234,56 ₺\"),\n * odakta düzenlemeye uygun (\"1234,56\") gösterir. Türkçe ondalık virgül,\n * alışkanlıkla yazılan \"12.5\" de anlaşılır (bkz. `parseNumber`). Harf hiç\n * girmez. min/max yazarken engellenmez (kullanıcı \"1\" yazıp \"15\"e giderken\n * min=10 araya girmesin) — alandan çıkınca/Enter'da sınıra çekilir.\n *\n * Klavye: ↑/↓ adım (Shift ×10), PageUp/PageDown ×10, Home/End min/max, Enter\n * onaylar. `aria-valuenow/min/max` + `aria-valuetext` (önek/sonekle, ör. \"1.234,50 ₺\").\n */\nexport const InputNumber = forwardRef<HTMLInputElement, InputNumberProps>(function InputNumber(outerProps, ref) {\n // Field içindeyse id / aria-describedby / hata / required / disabled oradan tamamlanır.\n return <InputNumberInner {...useFieldControl(outerProps)} forwardedRef={ref} />;\n});\n\nfunction InputNumberInner(\n {\n forwardedRef: ref,\n value,\n defaultValue = null,\n onChange,\n min,\n max,\n step = 1,\n precision,\n grouping = true,\n locale = \"tr-TR\",\n prefix,\n suffix,\n controls = true,\n incrementLabel = \"Artır\",\n decrementLabel = \"Azalt\",\n placeholder,\n disabled = false,\n readOnly = false,\n size = \"md\",\n variant = \"outline\",\n shape = \"default\",\n color,\n id,\n name,\n required,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n onBlur,\n onFocus,\n onPressEnter,\n className,\n skeleton = false,\n }: InputNumberProps & { forwardedRef: React.ForwardedRef<HTMLInputElement> }\n) {\n const config: NumberFormatConfig = { locale, precision, grouping };\n const [current, setCurrent] = useControllableState<number | null>({ value, defaultValue });\n const [focused, setFocused] = useState(false);\n const [text, setText] = useState(\"\");\n const innerRef = useRef<HTMLInputElement | null>(null);\n const interactive = !disabled && !readOnly;\n\n // En güncel değer — basılı tutarken adımlar render'lar arasında art arda gelebilir;\n // render kapanışındaki `current` eski kalır ve her adım aynı değerden hesaplanırdı.\n const latest = useRef(current);\n latest.current = current;\n\n const emit = (next: number | null) => {\n if (next === latest.current) return;\n latest.current = next;\n setCurrent(next);\n onChange?.(next);\n };\n\n /** Alandan çıkınca/Enter: metni sayıya çevir, yuvarla, sınıra çek; anlamsızsa son geçerli değere dön. */\n const normalize = (): number | null => {\n const parsed = parseNumber(text, locale);\n let next: number | null = current;\n if (parsed === null) next = null;\n else if (parsed !== undefined) next = clamp(roundTo(parsed, precision), min, max);\n emit(next);\n return next;\n };\n\n const applyStep = (direction: 1 | -1, multiplier = 1) => {\n if (!interactive) return;\n // Odaktaysa henüz onaylanmamış yazılan metin de hesaba katılır (yazıp ↑'a basınca oradan devam).\n const typed = focused ? parseNumber(text, locale) : undefined;\n const base = typed === undefined || typed === null ? latest.current : typed;\n const next = stepValue(base, direction, step * multiplier, min, max, precision);\n emit(next);\n if (focused) setText(formatForEditing(next, config));\n };\n const hold = useHoldRepeat((direction) => applyStep(direction));\n\n if (skeleton) {\n return <div {...skeletonBoxProps(cn(\"flex w-full items-center\", sizeClass[size], getShapeClasses(shape, variant), className))} />;\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n const steps: Record<string, [1 | -1, number]> = { ArrowUp: [1, e.shiftKey ? 10 : 1], ArrowDown: [-1, e.shiftKey ? 10 : 1], PageUp: [1, 10], PageDown: [-1, 10] };\n const stepKey = steps[e.key];\n if (stepKey) {\n e.preventDefault();\n applyStep(...stepKey);\n } else if ((e.key === \"Home\" && min !== undefined) || (e.key === \"End\" && max !== undefined)) {\n e.preventDefault();\n if (!interactive) return;\n const edge = e.key === \"Home\" ? min! : max!;\n emit(edge);\n setText(formatForEditing(edge, config));\n } else if (e.key === \"Enter\") {\n setText(formatForEditing(normalize(), config));\n onPressEnter?.(e);\n }\n };\n\n const formatted = formatNumber(current, config);\n const valueText = formatted ? [textOf(prefix), formatted, textOf(suffix)].filter(Boolean).join(\" \") : undefined;\n const canIncrement = interactive && (max === undefined || current === null || current < max);\n const canDecrement = interactive && (min === undefined || current === null || current > min);\n const adornment = \"flex shrink-0 items-center text-mari-muted\";\n\n return (\n // Kutunun boş alanına tıklamak alanı odaklar (Input'taki kısayol); klavye doğrudan alana gelir.\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n onMouseDown={(e) => {\n if (disabled || innerRef.current?.contains(e.target as Node) || (e.target as HTMLElement).closest(\"button\")) return;\n e.preventDefault();\n innerRef.current?.focus();\n }}\n className={cn(\n \"group relative flex w-full cursor-text items-center gap-2\",\n sizeClass[size],\n getShapeClasses(shape, variant),\n controls && \"py-0 pr-0\",\n // Dokunmatikte −/+ yan yana 64px yer kaplar: dar bir genişlik (w-24) rakamlara yer bırakmıyordu.\n controls && \"pointer-coarse:min-w-32\",\n touchTargetClass[size],\n FIELD_BASE_CLASS,\n getVariantClasses(variant, color),\n disabled && FIELD_DISABLED_CLASS,\n className\n )}\n >\n {prefix && <span className={adornment}>{prefix}</span>}\n <input\n ref={(el) => {\n innerRef.current = el;\n if (typeof ref === \"function\") ref(el);\n else if (ref) ref.current = el;\n }}\n id={id}\n name={name}\n type=\"text\"\n role=\"spinbutton\"\n inputMode={precision === 0 && (min === undefined || min >= 0) ? \"numeric\" : \"decimal\"}\n autoComplete=\"off\"\n required={required}\n disabled={disabled}\n readOnly={readOnly}\n placeholder={placeholder}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={color === \"error\" || undefined}\n aria-valuenow={current ?? undefined}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuetext={valueText}\n value={focused ? text : formatted}\n onFocus={(e) => {\n setFocused(true);\n setText(formatForEditing(current, config));\n onFocus?.(e);\n }}\n onBlur={(e) => {\n normalize();\n setFocused(false);\n onBlur?.(e);\n }}\n onChange={(e) => {\n const next = e.target.value;\n if (!isAllowedInput(next, locale)) return;\n setText(next);\n const parsed = parseNumber(next, locale);\n if (parsed !== undefined) emit(parsed);\n }}\n onKeyDown={handleKeyDown}\n className={cn(\"w-full min-w-0 flex-1 bg-transparent tabular-nums placeholder:text-mari-muted focus:outline-none disabled:cursor-not-allowed\", FIELD_MOBILE_TEXT_CLASS)}\n />\n {suffix && <span className={cn(adornment, controls && \"pr-1\")}>{suffix}</span>}\n {controls && (\n <Stepper\n onStart={hold.start}\n onStop={hold.stop}\n canIncrement={canIncrement}\n canDecrement={canDecrement}\n incrementLabel={incrementLabel}\n decrementLabel={decrementLabel}\n size={size}\n />\n )}\n </div>\n );\n}\n","/**\n * Faz 16.1 — InputNumber'ın saf sayı mantığı (DOM'suz, ayrıca test edilir).\n *\n * Neden `type=\"number\"` değil: tarayıcı Türkçe ondalık virgülü ve binlik\n * ayıracını (1.234,56) göstermez/kabul etmez, min/max'ı yazarken sınırlamaz,\n * bazı tarayıcılarda harf yazılabilir ve değer boşken `\"\"` ile \"geçersiz\"i\n * ayırt ettirmez. Burada metin alanı + kendi ayrıştırma/biçimlendirmemiz var.\n */\n\nexport interface NumberFormatConfig {\n locale: string;\n /** Ondalık basamak sayısı (sabit). Verilmezse değerin kendi basamakları (en fazla 20). */\n precision?: number;\n /** Binlik ayıracı. Varsayılan: `true`. */\n grouping: boolean;\n}\n\n/** Yerelin ondalık ve binlik karakterleri (tr-TR: \",\" ve \".\"). */\nexport function getSeparators(locale: string): { decimal: string; group: string } {\n const parts = new Intl.NumberFormat(locale).formatToParts(1234567.5);\n return {\n decimal: parts.find((p) => p.type === \"decimal\")?.value ?? \".\",\n group: parts.find((p) => p.type === \"group\")?.value ?? \",\",\n };\n}\n\n/** Kayan nokta artıklarını temizleyerek yuvarlar (0.1 + 0.2 → 0.3). */\nexport function roundTo(value: number, precision: number | undefined): number {\n if (precision === undefined) return Number.parseFloat(value.toPrecision(15));\n const factor = 10 ** precision;\n return Math.round((value + Number.EPSILON) * factor) / factor;\n}\n\nexport function clamp(value: number, min: number | undefined, max: number | undefined): number {\n if (min !== undefined && value < min) return min;\n if (max !== undefined && value > max) return max;\n return value;\n}\n\n/** Ekranda gösterilen biçim (odak dışı): \"1.234,56\". */\nexport function formatNumber(value: number | null, { locale, precision, grouping }: NumberFormatConfig): string {\n if (value === null || Number.isNaN(value)) return \"\";\n return new Intl.NumberFormat(locale, {\n useGrouping: grouping,\n minimumFractionDigits: precision ?? 0,\n maximumFractionDigits: precision ?? 20,\n }).format(value);\n}\n\n/** Düzenlerken gösterilen biçim (odakta): binlik ayıracı yok, yerelin ondalığı — \"1234,56\". */\nexport function formatForEditing(value: number | null, config: NumberFormatConfig): string {\n return formatNumber(value, { ...config, grouping: false });\n}\n\n/**\n * Kullanıcı metnini sayıya çevirir; boş → `null`, anlamsız → `undefined`.\n *\n * Türkçede \".\" binlik, \",\" ondalıktır — ama kullanıcı alışkanlıkla \"12.5\"\n * de yazar. Kural: metinde yerelin ondalığı (\",\") VARSA \".\" binlik sayılıp\n * atılır. Yoksa \".\" yalnız GEÇERLİ binlik gruplaması gibi duruyorsa\n * (\"1.234\", \"1.234.567\") binlik; aksi halde (\"12.5\", \"3.14\") ondalık kabul\n * edilir.\n */\nexport function parseNumber(text: string, locale: string): number | null | undefined {\n const { decimal, group } = getSeparators(locale);\n let s = text.replace(/[\\s\\u00a0\\u202f]/g, \"\");\n if (s === \"\" || s === \"-\" || s === \"+\") return null;\n\n if (decimal !== \".\" && s.includes(decimal)) {\n s = s.split(group).join(\"\").replace(decimal, \".\");\n } else if (decimal !== \".\" && group === \".\" && s.includes(\".\")) {\n const looksGrouped = /^[-+]?\\d{1,3}(\\.\\d{3})+$/.test(s);\n if (looksGrouped) s = s.split(\".\").join(\"\");\n } else if (decimal === \".\") {\n s = s.split(group).join(\"\");\n }\n\n // Doğrusal kontrol (geri izlemeli regex yerine): işaret + rakamlar + en fazla bir nokta, en az bir rakam.\n const body = s.replace(/^[-+]/, \"\");\n if (!/^[\\d.]+$/.test(body) || body.split(\".\").length > 2 || !/\\d/.test(body)) return undefined;\n const value = Number(s);\n return Number.isFinite(value) ? value : undefined;\n}\n\n/** Yazarken izin verilen karakterler (rakam, işaret, ayraçlar) — harf vb. hiç girmesin. */\nexport function isAllowedInput(text: string, locale: string): boolean {\n const { decimal, group } = getSeparators(locale);\n const escape = (c: string) => c.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return new RegExp(`^[-+]?[\\\\d${escape(decimal)}${escape(group)}.\\\\s]*$`).test(text);\n}\n\n/** `step` adımı sonrası değer: boş alanda min'den (yoksa 0'dan) başlar, sınırlar ve yuvarlar. */\nexport function stepValue(current: number | null, direction: 1 | -1, step: number, min: number | undefined, max: number | undefined, precision: number | undefined): number {\n const base = current ?? (direction === 1 ? (min ?? 0) - step : (max ?? 0) + step);\n // Adımın kendi ondalık basamağı kadar yuvarla ki 0.1 adımlar 0.30000000000000004 üretmesin.\n const stepDecimals = (String(step).split(\".\")[1] ?? \"\").length;\n const next = roundTo(base + direction * step, precision ?? Math.max(stepDecimals, decimals(base)));\n return clamp(next, min, max);\n}\n\nfunction decimals(value: number): number {\n return (String(value).split(\".\")[1] ?? \"\").length;\n}\n"],"mappings":"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","names":["InputNumber"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/skeleton/Skeleton.tsx","../src/skeleton/utils.ts","../src/skeleton/SkeletonButton.tsx","../src/skeleton/SkeletonInput.tsx"],"sourcesContent":["import React from \"react\";\nimport { cn } from \"@mari-ui/core\";\nimport type { SkeletonAvatarProps, SkeletonBlockProps, SkeletonParagraphProps, SkeletonProps, SkeletonTitleProps } from \"./types\";\nimport { getAvatarShapeClasses, getAvatarSizeStyle, getLineClass, skeletonFill, widthToStyle } from \"./utils\";\n\nexport type { SkeletonProps };\n\n/** İç içe ternary yerine ayrık fonksiyon (Faz 8, SonarJS `no-nested-conditional`). */\nfunction resolveParagraphWidths(width: SkeletonParagraphProps[\"width\"], rows: number): (string | number | undefined)[] {\n if (Array.isArray(width)) return width;\n if (width !== undefined) return [...Array(rows - 1).fill(undefined), width];\n return [];\n}\n\n/** İç içe ternary yerine ayrık fonksiyon (Faz 8, SonarJS `no-nested-conditional`). */\nfunction resolveFallbackWidthClass(explicitWidth: string | number | undefined, isLastRow: boolean): string | undefined {\n if (explicitWidth !== undefined) return undefined;\n return isLastRow ? \"w-3/5\" : \"w-full\";\n}\n\n// Hook yok, browser API yok — saf sunum, \"use client\" gerekmiyor.\nexport function Skeleton({\n active = false,\n label,\n avatar = false,\n loading,\n paragraph = true,\n round = false,\n title = true,\n className,\n children,\n}: Readonly<SkeletonProps>) {\n if (loading === false) return <>{children}</>;\n\n const avatarProps: SkeletonAvatarProps = typeof avatar === \"boolean\" ? {} : avatar;\n const titleProps: SkeletonTitleProps = typeof title === \"boolean\" ? {} : title;\n const paragraphProps: SkeletonParagraphProps = typeof paragraph === \"boolean\" ? {} : paragraph;\n\n const rows = paragraphProps.rows ?? 3;\n const paragraphWidths = resolveParagraphWidths(paragraphProps.width, rows);\n\n const avatarSize = avatarProps.size ?? \"md\";\n\n return (\n // Faz 13.6: eskiden `animate-pulse` `active`ten bağımsız HER ZAMAN vardı.\n <div\n className={className}\n {...(label ? { role: \"status\", \"aria-label\": label, \"aria-busy\": true } : { \"aria-hidden\": true })}\n >\n <div className=\"flex gap-4\">\n {avatar && (\n <div\n className={cn(getAvatarShapeClasses(avatarProps.shape ?? \"circle\", avatarSize), skeletonFill(avatarProps.active ?? active))}\n style={getAvatarSizeStyle(avatarSize)}\n />\n )}\n <div className=\"min-w-0 flex-1\">\n {title && (\n <div\n className={getLineClass(round, cn(\"h-4\", titleProps.width === undefined && \"w-2/5\"), active)}\n style={widthToStyle(titleProps.width)}\n />\n )}\n {paragraph && (\n <div className={cn(\"space-y-2.5\", title && \"mt-4\")}>\n {Array.from({ length: rows }).map((_, i) => {\n const explicitWidth = paragraphWidths[i];\n const fallbackWidthClass = resolveFallbackWidthClass(explicitWidth, i === rows - 1);\n return (\n <div\n key={i}\n className={getLineClass(round, cn(\"h-3\", fallbackWidthClass), active)}\n style={widthToStyle(explicitWidth)}\n />\n );\n })}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n\n/**\n * Serbest şekilli iskelet parçası — kendi yerleşiminizi (kart ızgarası, tablo\n * satırı) gerçek bileşenin ölçüleriyle kurmak için. Görsel; `aria-hidden`.\n */\nexport function SkeletonBlock({ width, height = \"1rem\", radius = \"md\", active = false, className }: Readonly<SkeletonBlockProps>) {\n const radiusClass = { none: \"rounded-none\", sm: \"rounded-sm\", md: \"rounded-md\", lg: \"rounded-lg\", xl: \"rounded-xl\", full: \"rounded-full\" }[radius];\n return (\n <div\n aria-hidden\n className={cn(\"shrink-0\", skeletonFill(active), radiusClass, width === undefined && \"w-full\", className)}\n style={{ width: typeof width === \"number\" ? `${width}px` : width, height: typeof height === \"number\" ? `${height}px` : height }}\n />\n );\n}\n","import type React from \"react\";\nimport { cn, type Size } from \"@mari-ui/core\";\nimport type { SkeletonButtonShape } from \"./types\";\nimport { skeletonFill } from \"../lib/skeleton\";\n\nexport { getShapeClasses as getAvatarShapeClasses, getSizeStyle as getAvatarSizeStyle } from \"../avatar/utils\";\n\n/**\n * Faz 15.6 — iskelet parçalarının geometrisi GERÇEK bileşenlerden gelir ki\n * yüklenince zıplamasın. Eskiden kendi tabloları vardı ve kaymıştı:\n * - Avatar iskeleti 32/48/64px, varsayılanı yuvarlatılmış kareydi; Avatar\n * 24/32/40px ve varsayılanı daire → artık `avatar/utils`'in kendisi.\n * - Button/Input `sm` iskeleti `rounded-md`, gerçeği `rounded-sm` (lib\n * `sizeClass`).\n * - `SkeletonButton shape=\"circle\"` 80×32 bir hap çiziyordu; Button'ın\n * `circle`'ı kare-daire.\n *\n * Sabit enum olmayan (tüketici verisi) genişlikler class değil inline stil —\n * Tailwind derleme zamanında olası her değeri üretemez.\n */\n\n/** lib `sizeClass` ile aynı yükseklik + radius (Button, Input). */\nconst CONTROL_BOX_CLASS: Record<Size, string> = {\n sm: \"h-6 rounded-sm\",\n md: \"h-8 rounded-md\",\n lg: \"h-10 rounded-md\",\n};\n\nexport const INPUT_SIZE_CLASS: Record<Size, string> = {\n sm: cn(CONTROL_BOX_CLASS.sm, \"w-full\"),\n md: cn(CONTROL_BOX_CLASS.md, \"w-full\"),\n lg: cn(CONTROL_BOX_CLASS.lg, \"w-full\"),\n};\n\nconst BUTTON_WIDTH_CLASS: Record<Size, string> = { sm: \"w-16\", md: \"w-20\", lg: \"w-24\" };\n/** Button `circle` = kare-daire: genişlik = yükseklik. */\nconst CIRCLE_SIZE_CLASS: Record<Size, string> = { sm: \"size-6\", md: \"size-8\", lg: \"size-10\" };\n\n/** Button'ın `getShapeClasses`'ıyla aynı şekiller (`round` = eski ad, `pill`). */\nexport function getButtonSkeletonClass(size: Size, shape: SkeletonButtonShape, block: boolean): string {\n if (shape === \"circle\") return cn(CIRCLE_SIZE_CLASS[size], \"rounded-full\");\n return cn(\n CONTROL_BOX_CLASS[size],\n block ? \"w-full\" : BUTTON_WIDTH_CLASS[size],\n (shape === \"pill\" || shape === \"round\") && \"rounded-full\",\n shape === \"square\" && \"rounded-none\"\n );\n}\n\nexport function widthToStyle(width: number | string | undefined): React.CSSProperties | undefined {\n if (width === undefined) return undefined;\n return { width: typeof width === \"number\" ? `${width}px` : width };\n}\n\nexport { skeletonFill };\n\nexport function getLineClass(round: boolean | undefined, extra?: string, active?: boolean): string {\n return cn(skeletonFill(active), round ? \"rounded-full\" : \"rounded-md\", extra);\n}\n","import React from \"react\";\nimport { cn, type Size } from \"@mari-ui/core\";\nimport type { SkeletonButtonShape } from \"./types\";\nimport { getButtonSkeletonClass, skeletonFill } from \"./utils\";\n\nexport interface SkeletonButtonProps {\n active?: boolean;\n block?: boolean;\n /** Button'ın `shape`'iyle aynı: `default` / `pill` / `circle` / `square` (`round` = `pill`'in eski adı). */\n shape?: SkeletonButtonShape;\n size?: Size;\n className?: string;\n}\n\n// Hook yok, browser API yok — saf sunum, \"use client\" gerekmiyor.\nexport function SkeletonButton({ active = false, block = false, shape = \"default\", size = \"md\", className }: Readonly<SkeletonButtonProps>) {\n return <div aria-hidden className={cn(skeletonFill(active), getButtonSkeletonClass(size, shape, block), className)} />;\n}\n","import React from \"react\";\nimport { cn, type Size } from \"@mari-ui/core\";\nimport { INPUT_SIZE_CLASS, skeletonFill } from \"./utils\";\n\nexport interface SkeletonInputProps {\n active?: boolean;\n size?: Size;\n className?: string;\n}\n\n// Hook yok, browser API yok — saf sunum, \"use client\" gerekmiyor.\nexport function SkeletonInput({ active = false, size = \"md\", className }: Readonly<SkeletonInputProps>) {\n return (\n <div aria-hidden className={cn(skeletonFill(active), INPUT_SIZE_CLASS[size], className)} />\n );\n}\n"],"mappings":"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","names":["cn","cn","cn","jsx","cn","cn","jsx","cn"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/floating.ts"],"sourcesContent":["import type { Placement } from \"@mari-ui/core\";\n\n/**\n * Yüzen paneller (Dropdown, Tooltip) için ortak konumlandırma — Faz 15'te\n * `dropdown/utils.ts`'ten taşındı; Tooltip'in kendi 4-yönlü, kıstırmasız\n * hesabının yerini aldı (mobilde ekrandan taşıyordu).\n */\nexport type Side = \"top\" | \"bottom\" | \"left\" | \"right\";\ntype Align = \"start\" | \"center\" | \"end\";\n\n/** 12 değerli `Placement`i ana yön + hizaya ayırır (`bottom-end` → `{ side: \"bottom\", align: \"end\" }`). */\nexport function parsePlacement(placement: Placement): { side: Side; align: Align } {\n const [side, align] = placement.split(\"-\") as [Side, Align | undefined];\n return { side, align: align ?? \"center\" };\n}\n\nconst OPPOSITE_SIDE: Record<Side, Side> = { top: \"bottom\", bottom: \"top\", left: \"right\", right: \"left\" };\n\nexport interface Box {\n top: number;\n left: number;\n width: number;\n height: number;\n}\n\nexport interface ArrowOptions {\n /** Okun ORTASININ panelin hizalandığı kenardan uzaklığı (ant.design: 12px kenar boşluğu + 8px yarım genişlik). */\n inset: number;\n /** `true`: panel, okun ortası TETİKLEYİCİNİN ortasına gelecek şekilde kayar (ant.design `arrow.pointAtCenter`). */\n pointAtCenter: boolean;\n}\n\nfunction getArrowCenter(align: Align, size: number, inset: number, towardsTrigger: number | undefined): number {\n if (towardsTrigger !== undefined) return towardsTrigger;\n if (align === \"start\") return inset;\n if (align === \"end\") return size - inset;\n return size / 2;\n}\n\n/**\n * Panelin sol-üst köşesinin (viewport koordinatlarında) nereye gelmesi\n * gerektiğini hesaplar: tercih edilen yönde sığmıyor ama karşı yönde\n * sığıyorsa yönü çevirir (flip), sonra iki eksende de viewport içinde\n * kelepçeler. `side` (flip sonrası gerçek yön) ve `arrowOffset` (okun ortasının\n * panelin kenarı boyunca konumu) da döner. Saf fonksiyon — DOM'a dokunmaz.\n */\nexport function computePanelPosition(\n anchor: Box,\n panel: { width: number; height: number },\n placement: Placement,\n viewport: { width: number; height: number },\n gap: number,\n edge: number,\n arrow?: ArrowOptions\n): { top: number; left: number; side: Side; arrowOffset: number } {\n const { side: preferred, align } = parsePlacement(placement);\n\n const mainStart = (side: Side): number => {\n switch (side) {\n case \"top\":\n return anchor.top - gap - panel.height;\n case \"bottom\":\n return anchor.top + anchor.height + gap;\n case \"left\":\n return anchor.left - gap - panel.width;\n default:\n return anchor.left + anchor.width + gap;\n }\n };\n\n const fits = (side: Side): boolean => {\n const start = mainStart(side);\n const size = side === \"top\" || side === \"bottom\" ? panel.height : panel.width;\n const limit = side === \"top\" || side === \"bottom\" ? viewport.height : viewport.width;\n return start >= edge && start + size <= limit - edge;\n };\n\n // Sıra: tercih → karşı yön → dik yönler. Dar ekranda yatay iki yön de\n // sığmıyorsa (mobilde geniş bir balon) üst/alta geçilir — eskiden tercih\n // edilen yönde kalıp kıstırılıyor ve TETİKLEYİCİNİN ÜSTÜNÜ KAPATIYORDU.\n const perpendicular: Side[] = preferred === \"top\" || preferred === \"bottom\" ? [\"right\", \"left\"] : [\"top\", \"bottom\"];\n const side = [preferred, OPPOSITE_SIDE[preferred], ...perpendicular].find(fits) ?? preferred;\n const vertical = side === \"top\" || side === \"bottom\";\n const inset = arrow?.inset ?? 0;\n\n // Çapraz eksen: panelin `size`ı, tetikleyicinin `start`/`length`i.\n const cross = vertical\n ? { start: anchor.left, length: anchor.width, size: panel.width }\n : { start: anchor.top, length: anchor.height, size: panel.height };\n const center = cross.start + cross.length / 2;\n\n let origin: number;\n if (align === \"center\") origin = center - cross.size / 2;\n else if (arrow?.pointAtCenter) origin = align === \"start\" ? center - inset : center + inset - cross.size;\n else origin = align === \"start\" ? cross.start : cross.start + cross.length - cross.size;\n\n const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), Math.max(min, max));\n // Çapraz eksen: önce ekran içine kıstır, SONRA tetikleyiciye bağlılığı\n // zorla — panel her koşulda tetikleyicinin ortasını (ok payıyla) kapsamalı.\n // Eskiden yalnızca ekrana kıstırılıyordu: tetikleyici ekranın alt/üst\n // kenarına yaklaşınca panel kayıp tetikleyiciden kopuyor, komşu satırın\n // balonuna biniyordu (kaydırırken, kullanıcı bulgusu). Kenara yakınken panel\n // ekrandan biraz taşar ama asla tetikleyicisinden ayrılmaz.\n const attach = (value: number) => clamp(value, center - cross.size + inset, center - inset);\n const crossPos = attach(clamp(origin, edge, (vertical ? viewport.width - panel.width : viewport.height - panel.height) - edge));\n const top = vertical ? clamp(mainStart(side), edge, viewport.height - panel.height - edge) : crossPos;\n const left = vertical ? crossPos : clamp(mainStart(side), edge, viewport.width - panel.width - edge);\n\n // Ok: varsayılan olarak hizalanan kenardan sabit `inset` içeride (ant.design);\n // `pointAtCenter` ise tetikleyicinin ortasında. Köşeye taşmasın diye kelepçelenir.\n const finalOrigin = vertical ? left : top;\n const arrowOffset = clamp(getArrowCenter(align, cross.size, inset, arrow?.pointAtCenter ? center - finalOrigin : undefined), inset, cross.size - inset);\n\n return { top, left, side, arrowOffset };\n}\n\n"],"mappings":";AAWO,SAAS,eAAe,WAAoD;AACjF,QAAM,CAAC,MAAM,KAAK,IAAI,UAAU,MAAM,GAAG;AACzC,SAAO,EAAE,MAAM,OAAO,SAAS,SAAS;AAC1C;AAEA,IAAM,gBAAoC,EAAE,KAAK,UAAU,QAAQ,OAAO,MAAM,SAAS,OAAO,OAAO;AAgBvG,SAAS,eAAe,OAAc,MAAc,OAAe,gBAA4C;AAC7G,MAAI,mBAAmB,OAAW,QAAO;AACzC,MAAI,UAAU,QAAS,QAAO;AAC9B,MAAI,UAAU,MAAO,QAAO,OAAO;AACnC,SAAO,OAAO;AAChB;AASO,SAAS,qBACd,QACA,OACA,WACA,UACA,KACA,MACA,OACgE;AAChE,QAAM,EAAE,MAAM,WAAW,MAAM,IAAI,eAAe,SAAS;AAE3D,QAAM,YAAY,CAACA,UAAuB;AACxC,YAAQA,OAAM;AAAA,MACZ,KAAK;AACH,eAAO,OAAO,MAAM,MAAM,MAAM;AAAA,MAClC,KAAK;AACH,eAAO,OAAO,MAAM,OAAO,SAAS;AAAA,MACtC,KAAK;AACH,eAAO,OAAO,OAAO,MAAM,MAAM;AAAA,MACnC;AACE,eAAO,OAAO,OAAO,OAAO,QAAQ;AAAA,IACxC;AAAA,EACF;AAEA,QAAM,OAAO,CAACA,UAAwB;AACpC,UAAM,QAAQ,UAAUA,KAAI;AAC5B,UAAM,OAAOA,UAAS,SAASA,UAAS,WAAW,MAAM,SAAS,MAAM;AACxE,UAAM,QAAQA,UAAS,SAASA,UAAS,WAAW,SAAS,SAAS,SAAS;AAC/E,WAAO,SAAS,QAAQ,QAAQ,QAAQ,QAAQ;AAAA,EAClD;AAKA,QAAM,gBAAwB,cAAc,SAAS,cAAc,WAAW,CAAC,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ;AAClH,QAAM,OAAO,CAAC,WAAW,cAAc,SAAS,GAAG,GAAG,aAAa,EAAE,KAAK,IAAI,KAAK;AACnF,QAAM,WAAW,SAAS,SAAS,SAAS;AAC5C,QAAM,QAAQ,OAAO,SAAS;AAG9B,QAAM,QAAQ,WACV,EAAE,OAAO,OAAO,MAAM,QAAQ,OAAO,OAAO,MAAM,MAAM,MAAM,IAC9D,EAAE,OAAO,OAAO,KAAK,QAAQ,OAAO,QAAQ,MAAM,MAAM,OAAO;AACnE,QAAM,SAAS,MAAM,QAAQ,MAAM,SAAS;AAE5C,MAAI;AACJ,MAAI,UAAU,SAAU,UAAS,SAAS,MAAM,OAAO;AAAA,WAC9C,OAAO,cAAe,UAAS,UAAU,UAAU,SAAS,QAAQ,SAAS,QAAQ,MAAM;AAAA,MAC/F,UAAS,UAAU,UAAU,MAAM,QAAQ,MAAM,QAAQ,MAAM,SAAS,MAAM;AAEnF,QAAM,QAAQ,CAAC,OAAe,KAAa,QAAgB,KAAK,IAAI,KAAK,IAAI,OAAO,GAAG,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC;AAO5G,QAAM,SAAS,CAAC,UAAkB,MAAM,OAAO,SAAS,MAAM,OAAO,OAAO,SAAS,KAAK;AAC1F,QAAM,WAAW,OAAO,MAAM,QAAQ,OAAO,WAAW,SAAS,QAAQ,MAAM,QAAQ,SAAS,SAAS,MAAM,UAAU,IAAI,CAAC;AAC9H,QAAM,MAAM,WAAW,MAAM,UAAU,IAAI,GAAG,MAAM,SAAS,SAAS,MAAM,SAAS,IAAI,IAAI;AAC7F,QAAM,OAAO,WAAW,WAAW,MAAM,UAAU,IAAI,GAAG,MAAM,SAAS,QAAQ,MAAM,QAAQ,IAAI;AAInG,QAAM,cAAc,WAAW,OAAO;AACtC,QAAM,cAAc,MAAM,eAAe,OAAO,MAAM,MAAM,OAAO,OAAO,gBAAgB,SAAS,cAAc,MAAS,GAAG,OAAO,MAAM,OAAO,KAAK;AAEtJ,SAAO,EAAE,KAAK,MAAM,MAAM,YAAY;AACxC;","names":["side"]}
|