@sth87/shadcn-design-system 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +487 -0
- package/dist/cjs/_virtual/_commonjsHelpers.cjs +2 -0
- package/dist/cjs/_virtual/_commonjsHelpers.cjs.map +1 -0
- package/dist/cjs/_virtual/index.cjs +2 -0
- package/dist/cjs/_virtual/index.cjs.map +1 -0
- package/dist/cjs/_virtual/index2.cjs +2 -0
- package/dist/cjs/_virtual/index2.cjs.map +1 -0
- package/dist/cjs/components/Accordion/Accordion.cjs +2 -0
- package/dist/cjs/components/Accordion/Accordion.cjs.map +1 -0
- package/dist/cjs/components/Avatar/Avatar.cjs +2 -0
- package/dist/cjs/components/Avatar/Avatar.cjs.map +1 -0
- package/dist/cjs/components/Badge/Badge.cjs +2 -0
- package/dist/cjs/components/Badge/Badge.cjs.map +1 -0
- package/dist/cjs/components/Breadcrumb/Breadcrumb.cjs +2 -0
- package/dist/cjs/components/Breadcrumb/Breadcrumb.cjs.map +1 -0
- package/dist/cjs/components/Button/Button.cjs +2 -0
- package/dist/cjs/components/Button/Button.cjs.map +1 -0
- package/dist/cjs/components/Button/ButtonGroup.cjs +2 -0
- package/dist/cjs/components/Button/ButtonGroup.cjs.map +1 -0
- package/dist/cjs/components/Calendar/Calendar.cjs +2 -0
- package/dist/cjs/components/Calendar/Calendar.cjs.map +1 -0
- package/dist/cjs/components/Carousel/Carousel.cjs +2 -0
- package/dist/cjs/components/Carousel/Carousel.cjs.map +1 -0
- package/dist/cjs/components/Checkbox/Checkbox.cjs +2 -0
- package/dist/cjs/components/Checkbox/Checkbox.cjs.map +1 -0
- package/dist/cjs/components/Collapsible/Collapsible.cjs +2 -0
- package/dist/cjs/components/Collapsible/Collapsible.cjs.map +1 -0
- package/dist/cjs/components/Command/Command.cjs +2 -0
- package/dist/cjs/components/Command/Command.cjs.map +1 -0
- package/dist/cjs/components/Command/index.cjs +2 -0
- package/dist/cjs/components/Command/index.cjs.map +1 -0
- package/dist/cjs/components/ContextMenu/ContextMenu.cjs +2 -0
- package/dist/cjs/components/ContextMenu/ContextMenu.cjs.map +1 -0
- package/dist/cjs/components/ContextMenu/index.cjs +2 -0
- package/dist/cjs/components/ContextMenu/index.cjs.map +1 -0
- package/dist/cjs/components/Cropper/Cropper.cjs +2 -0
- package/dist/cjs/components/Cropper/Cropper.cjs.map +1 -0
- package/dist/cjs/components/Cropper/CropperTool.cjs +2 -0
- package/dist/cjs/components/Cropper/CropperTool.cjs.map +1 -0
- package/dist/cjs/components/Cropper/utils.cjs +2 -0
- package/dist/cjs/components/Cropper/utils.cjs.map +1 -0
- package/dist/cjs/components/DatePicker/DatePicker.cjs +2 -0
- package/dist/cjs/components/DatePicker/DatePicker.cjs.map +1 -0
- package/dist/cjs/components/DatePicker/RangePicker.cjs +2 -0
- package/dist/cjs/components/DatePicker/RangePicker.cjs.map +1 -0
- package/dist/cjs/components/DatePicker/TimePicker.cjs +2 -0
- package/dist/cjs/components/DatePicker/TimePicker.cjs.map +1 -0
- package/dist/cjs/components/Dialog/Dialog.cjs +2 -0
- package/dist/cjs/components/Dialog/Dialog.cjs.map +1 -0
- package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs +2 -0
- package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs.map +1 -0
- package/dist/cjs/components/DropdownMenu/index.cjs +2 -0
- package/dist/cjs/components/DropdownMenu/index.cjs.map +1 -0
- package/dist/cjs/components/FloatLabel.cjs +2 -0
- package/dist/cjs/components/FloatLabel.cjs.map +1 -0
- package/dist/cjs/components/Glass/Glass.cjs +2 -0
- package/dist/cjs/components/Glass/Glass.cjs.map +1 -0
- package/dist/cjs/components/ImageViewer/ImageViewer.cjs +2 -0
- package/dist/cjs/components/ImageViewer/ImageViewer.cjs.map +1 -0
- package/dist/cjs/components/ImageViewer/ImageViewer.css +1 -0
- package/dist/cjs/components/Input/Input.cjs +2 -0
- package/dist/cjs/components/Input/Input.cjs.map +1 -0
- package/dist/cjs/components/InputOTP/InputOTP.cjs +2 -0
- package/dist/cjs/components/InputOTP/InputOTP.cjs.map +1 -0
- package/dist/cjs/components/Interactive/CursorFollow.cjs +2 -0
- package/dist/cjs/components/Interactive/CursorFollow.cjs.map +1 -0
- package/dist/cjs/components/Marquee/Marquee.cjs +2 -0
- package/dist/cjs/components/Marquee/Marquee.cjs.map +1 -0
- package/dist/cjs/components/Marquee/MarqueeWrapper.cjs +2 -0
- package/dist/cjs/components/Marquee/MarqueeWrapper.cjs.map +1 -0
- package/dist/cjs/components/Marquee/index.cjs +2 -0
- package/dist/cjs/components/Marquee/index.cjs.map +1 -0
- package/dist/cjs/components/Masonry/Masonry.cjs +2 -0
- package/dist/cjs/components/Masonry/Masonry.cjs.map +1 -0
- package/dist/cjs/components/Masonry/MasonryWrapper.cjs +2 -0
- package/dist/cjs/components/Masonry/MasonryWrapper.cjs.map +1 -0
- package/dist/cjs/components/Pagination/Pagination.cjs +2 -0
- package/dist/cjs/components/Pagination/Pagination.cjs.map +1 -0
- package/dist/cjs/components/Pagination/index.cjs +2 -0
- package/dist/cjs/components/Pagination/index.cjs.map +1 -0
- package/dist/cjs/components/Popover/Popover.cjs +2 -0
- package/dist/cjs/components/Popover/Popover.cjs.map +1 -0
- package/dist/cjs/components/Popover/index.cjs +2 -0
- package/dist/cjs/components/Popover/index.cjs.map +1 -0
- package/dist/cjs/components/QrCode/QrCode.cjs +2 -0
- package/dist/cjs/components/QrCode/QrCode.cjs.map +1 -0
- package/dist/cjs/components/QrCode/index.cjs +2 -0
- package/dist/cjs/components/QrCode/index.cjs.map +1 -0
- package/dist/cjs/components/Radio/Radio.cjs +2 -0
- package/dist/cjs/components/Radio/Radio.cjs.map +1 -0
- package/dist/cjs/components/Rate/Rate.cjs +2 -0
- package/dist/cjs/components/Rate/Rate.cjs.map +1 -0
- package/dist/cjs/components/Resizable/Resizable.cjs +2 -0
- package/dist/cjs/components/Resizable/Resizable.cjs.map +1 -0
- package/dist/cjs/components/ScrollArea/ScrollArea.cjs +2 -0
- package/dist/cjs/components/ScrollArea/ScrollArea.cjs.map +1 -0
- package/dist/cjs/components/Select/Select.cjs +2 -0
- package/dist/cjs/components/Select/Select.cjs.map +1 -0
- package/dist/cjs/components/Separator/Separator.cjs +2 -0
- package/dist/cjs/components/Separator/Separator.cjs.map +1 -0
- package/dist/cjs/components/Sheet/Sheet.cjs +6 -0
- package/dist/cjs/components/Sheet/Sheet.cjs.map +1 -0
- package/dist/cjs/components/Sidebar/Sidebar.cjs +2 -0
- package/dist/cjs/components/Sidebar/Sidebar.cjs.map +1 -0
- package/dist/cjs/components/Skeleton/Skeleton.cjs +2 -0
- package/dist/cjs/components/Skeleton/Skeleton.cjs.map +1 -0
- package/dist/cjs/components/Slider/Slider.cjs +2 -0
- package/dist/cjs/components/Slider/Slider.cjs.map +1 -0
- package/dist/cjs/components/Stepper/Stepper.cjs +2 -0
- package/dist/cjs/components/Stepper/Stepper.cjs.map +1 -0
- package/dist/cjs/components/Stepper/StepperWrapper.cjs +2 -0
- package/dist/cjs/components/Stepper/StepperWrapper.cjs.map +1 -0
- package/dist/cjs/components/Stepper/index.cjs +2 -0
- package/dist/cjs/components/Stepper/index.cjs.map +1 -0
- package/dist/cjs/components/Switch/Switch.cjs +2 -0
- package/dist/cjs/components/Switch/Switch.cjs.map +1 -0
- package/dist/cjs/components/Table/TableFilter/data-table-date-filter.cjs +2 -0
- package/dist/cjs/components/Table/TableFilter/data-table-date-filter.cjs.map +1 -0
- package/dist/cjs/components/Table/TableFilter/data-table-filter-popover.cjs +2 -0
- package/dist/cjs/components/Table/TableFilter/data-table-filter-popover.cjs.map +1 -0
- package/dist/cjs/components/Table/TableFilter/data-table-slider-filter.cjs +2 -0
- package/dist/cjs/components/Table/TableFilter/data-table-slider-filter.cjs.map +1 -0
- package/dist/cjs/components/Table/data-table-column-header.cjs +2 -0
- package/dist/cjs/components/Table/data-table-column-header.cjs.map +1 -0
- package/dist/cjs/components/Table/data-table-pagination.cjs +2 -0
- package/dist/cjs/components/Table/data-table-pagination.cjs.map +1 -0
- package/dist/cjs/components/Table/data-table.cjs +2 -0
- package/dist/cjs/components/Table/data-table.cjs.map +1 -0
- package/dist/cjs/components/Tabs/Tabs.cjs +2 -0
- package/dist/cjs/components/Tabs/Tabs.cjs.map +1 -0
- package/dist/cjs/components/Tabs/classes.cjs +2 -0
- package/dist/cjs/components/Tabs/classes.cjs.map +1 -0
- package/dist/cjs/components/Textarea/Textarea.cjs +2 -0
- package/dist/cjs/components/Textarea/Textarea.cjs.map +1 -0
- package/dist/cjs/components/TimeGridView.cjs +2 -0
- package/dist/cjs/components/TimeGridView.cjs.map +1 -0
- package/dist/cjs/components/Toast/Toast.cjs +2 -0
- package/dist/cjs/components/Toast/Toast.cjs.map +1 -0
- package/dist/cjs/components/Toggle/Toggle.cjs +2 -0
- package/dist/cjs/components/Toggle/Toggle.cjs.map +1 -0
- package/dist/cjs/components/Tooltip/Tooltip.cjs +2 -0
- package/dist/cjs/components/Tooltip/Tooltip.cjs.map +1 -0
- package/dist/cjs/components/Tour/Tour.cjs +2 -0
- package/dist/cjs/components/Tour/Tour.cjs.map +1 -0
- package/dist/cjs/components/Tour/TourWrapper.cjs +2 -0
- package/dist/cjs/components/Tour/TourWrapper.cjs.map +1 -0
- package/dist/cjs/components/Tour/index.cjs +2 -0
- package/dist/cjs/components/Tour/index.cjs.map +1 -0
- package/dist/cjs/components/Upload/Upload.cjs +4 -0
- package/dist/cjs/components/Upload/Upload.cjs.map +1 -0
- package/dist/cjs/components/WheelColumn.cjs +2 -0
- package/dist/cjs/components/WheelColumn.cjs.map +1 -0
- package/dist/cjs/constants/common.cjs +2 -0
- package/dist/cjs/constants/common.cjs.map +1 -0
- package/dist/cjs/favicon.ico +0 -0
- package/dist/cjs/hooks/use-callback-ref.cjs +2 -0
- package/dist/cjs/hooks/use-callback-ref.cjs.map +1 -0
- package/dist/cjs/hooks/use-debounced-callback.cjs +2 -0
- package/dist/cjs/hooks/use-debounced-callback.cjs.map +1 -0
- package/dist/cjs/hooks/use-debounced-value.cjs +2 -0
- package/dist/cjs/hooks/use-debounced-value.cjs.map +1 -0
- package/dist/cjs/hooks/use-event-listener.cjs +2 -0
- package/dist/cjs/hooks/use-event-listener.cjs.map +1 -0
- package/dist/cjs/hooks/use-intersection-observer.cjs +2 -0
- package/dist/cjs/hooks/use-intersection-observer.cjs.map +1 -0
- package/dist/cjs/hooks/use-isomorphic-layout-effect.cjs +2 -0
- package/dist/cjs/hooks/use-isomorphic-layout-effect.cjs.map +1 -0
- package/dist/cjs/hooks/use-media-query.cjs +2 -0
- package/dist/cjs/hooks/use-media-query.cjs.map +1 -0
- package/dist/cjs/hooks/use-on-click-outside.cjs +2 -0
- package/dist/cjs/hooks/use-on-click-outside.cjs.map +1 -0
- package/dist/cjs/hooks/use-script.cjs +2 -0
- package/dist/cjs/hooks/use-script.cjs.map +1 -0
- package/dist/cjs/hooks/use-scroll-lock.cjs +2 -0
- package/dist/cjs/hooks/use-scroll-lock.cjs.map +1 -0
- package/dist/cjs/image.png +0 -0
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/BlurText.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/BlurText.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/CircularText.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/CircularText.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/FlipWords.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/FlipWords.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/GradientText.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/GradientText.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/RollingText.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/RollingText.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/RotatingText.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/RotatingText.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/ShimmeringText.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/ShimmeringText.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/SplittingText.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/SplittingText.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/TextGenerateEffect.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/TextGenerateEffect.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/TextHoverEffect.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/TextHoverEffect.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/TextPressureEffect.cjs +22 -0
- package/dist/cjs/lib/TextAnimation/TextPressureEffect.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/TypingText.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/TypingText.cjs.map +1 -0
- package/dist/cjs/lib/TextAnimation/WritingText.cjs +2 -0
- package/dist/cjs/lib/TextAnimation/WritingText.cjs.map +1 -0
- package/dist/cjs/node_modules/.pnpm/react-viewer@3.2.2/node_modules/react-viewer/dist/index.cjs +253 -0
- package/dist/cjs/node_modules/.pnpm/react-viewer@3.2.2/node_modules/react-viewer/dist/index.cjs.map +1 -0
- package/dist/cjs/node_modules/.pnpm/viewerjs@1.11.7/node_modules/viewerjs/dist/viewer.css +1 -0
- package/dist/cjs/styles/animation.css +1 -0
- package/dist/cjs/styles/index.css +1 -0
- package/dist/cjs/styles/theme.css +1 -0
- package/dist/cjs/utils/animations.cjs +2 -0
- package/dist/cjs/utils/animations.cjs.map +1 -0
- package/dist/cjs/utils/css.cjs +2 -0
- package/dist/cjs/utils/css.cjs.map +1 -0
- package/dist/cjs/utils/data-table.cjs +2 -0
- package/dist/cjs/utils/data-table.cjs.map +1 -0
- package/dist/cjs/utils/datetime.cjs +2 -0
- package/dist/cjs/utils/datetime.cjs.map +1 -0
- package/dist/cjs/vite.svg +1 -0
- package/dist/cjs/wave.png +0 -0
- package/dist/esm/_virtual/_commonjsHelpers.js +7 -0
- package/dist/esm/_virtual/_commonjsHelpers.js.map +1 -0
- package/dist/esm/_virtual/index.js +8 -0
- package/dist/esm/_virtual/index.js.map +1 -0
- package/dist/esm/_virtual/index2.js +5 -0
- package/dist/esm/_virtual/index2.js.map +1 -0
- package/dist/esm/components/Accordion/Accordion.js +190 -0
- package/dist/esm/components/Accordion/Accordion.js.map +1 -0
- package/dist/esm/components/Avatar/Avatar.js +93 -0
- package/dist/esm/components/Avatar/Avatar.js.map +1 -0
- package/dist/esm/components/Badge/Badge.js +35 -0
- package/dist/esm/components/Badge/Badge.js.map +1 -0
- package/dist/esm/components/Breadcrumb/Breadcrumb.js +102 -0
- package/dist/esm/components/Breadcrumb/Breadcrumb.js.map +1 -0
- package/dist/esm/components/Button/Button.js +53 -0
- package/dist/esm/components/Button/Button.js.map +1 -0
- package/dist/esm/components/Button/ButtonGroup.js +53 -0
- package/dist/esm/components/Button/ButtonGroup.js.map +1 -0
- package/dist/esm/components/Calendar/Calendar.js +40 -0
- package/dist/esm/components/Calendar/Calendar.js.map +1 -0
- package/dist/esm/components/Carousel/Carousel.js +510 -0
- package/dist/esm/components/Carousel/Carousel.js.map +1 -0
- package/dist/esm/components/Checkbox/Checkbox.js +79 -0
- package/dist/esm/components/Checkbox/Checkbox.js.map +1 -0
- package/dist/esm/components/Collapsible/Collapsible.js +107 -0
- package/dist/esm/components/Collapsible/Collapsible.js.map +1 -0
- package/dist/esm/components/Command/Command.js +113 -0
- package/dist/esm/components/Command/Command.js.map +1 -0
- package/dist/esm/components/Command/index.js +16 -0
- package/dist/esm/components/Command/index.js.map +1 -0
- package/dist/esm/components/ContextMenu/ContextMenu.js +131 -0
- package/dist/esm/components/ContextMenu/ContextMenu.js.map +1 -0
- package/dist/esm/components/ContextMenu/index.js +24 -0
- package/dist/esm/components/ContextMenu/index.js.map +1 -0
- package/dist/esm/components/Cropper/Cropper.js +1014 -0
- package/dist/esm/components/Cropper/Cropper.js.map +1 -0
- package/dist/esm/components/Cropper/CropperTool.js +157 -0
- package/dist/esm/components/Cropper/CropperTool.js.map +1 -0
- package/dist/esm/components/Cropper/utils.js +108 -0
- package/dist/esm/components/Cropper/utils.js.map +1 -0
- package/dist/esm/components/DatePicker/DatePicker.js +263 -0
- package/dist/esm/components/DatePicker/DatePicker.js.map +1 -0
- package/dist/esm/components/DatePicker/RangePicker.js +456 -0
- package/dist/esm/components/DatePicker/RangePicker.js.map +1 -0
- package/dist/esm/components/DatePicker/TimePicker.js +444 -0
- package/dist/esm/components/DatePicker/TimePicker.js.map +1 -0
- package/dist/esm/components/Dialog/Dialog.js +223 -0
- package/dist/esm/components/Dialog/Dialog.js.map +1 -0
- package/dist/esm/components/DropdownMenu/DropdownMenu.js +196 -0
- package/dist/esm/components/DropdownMenu/DropdownMenu.js.map +1 -0
- package/dist/esm/components/DropdownMenu/index.js +24 -0
- package/dist/esm/components/DropdownMenu/index.js.map +1 -0
- package/dist/esm/components/FloatLabel.js +59 -0
- package/dist/esm/components/FloatLabel.js.map +1 -0
- package/dist/esm/components/Glass/Glass.js +93 -0
- package/dist/esm/components/Glass/Glass.js.map +1 -0
- package/dist/esm/components/ImageViewer/ImageViewer.css +1 -0
- package/dist/esm/components/ImageViewer/ImageViewer.js +273 -0
- package/dist/esm/components/ImageViewer/ImageViewer.js.map +1 -0
- package/dist/esm/components/Input/Input.js +267 -0
- package/dist/esm/components/Input/Input.js.map +1 -0
- package/dist/esm/components/InputOTP/InputOTP.js +70 -0
- package/dist/esm/components/InputOTP/InputOTP.js.map +1 -0
- package/dist/esm/components/Interactive/CursorFollow.js +257 -0
- package/dist/esm/components/Interactive/CursorFollow.js.map +1 -0
- package/dist/esm/components/Marquee/Marquee.js +419 -0
- package/dist/esm/components/Marquee/Marquee.js.map +1 -0
- package/dist/esm/components/Marquee/MarqueeWrapper.js +25 -0
- package/dist/esm/components/Marquee/MarqueeWrapper.js.map +1 -0
- package/dist/esm/components/Marquee/index.js +15 -0
- package/dist/esm/components/Marquee/index.js.map +1 -0
- package/dist/esm/components/Masonry/Masonry.js +840 -0
- package/dist/esm/components/Masonry/Masonry.js.map +1 -0
- package/dist/esm/components/Masonry/MasonryWrapper.js +19 -0
- package/dist/esm/components/Masonry/MasonryWrapper.js.map +1 -0
- package/dist/esm/components/Pagination/Pagination.js +209 -0
- package/dist/esm/components/Pagination/Pagination.js.map +1 -0
- package/dist/esm/components/Pagination/index.js +14 -0
- package/dist/esm/components/Pagination/index.js.map +1 -0
- package/dist/esm/components/Popover/Popover.js +51 -0
- package/dist/esm/components/Popover/Popover.js.map +1 -0
- package/dist/esm/components/Popover/index.js +9 -0
- package/dist/esm/components/Popover/index.js.map +1 -0
- package/dist/esm/components/QrCode/QrCode.js +300 -0
- package/dist/esm/components/QrCode/QrCode.js.map +1 -0
- package/dist/esm/components/QrCode/index.js +16 -0
- package/dist/esm/components/QrCode/index.js.map +1 -0
- package/dist/esm/components/Radio/Radio.js +74 -0
- package/dist/esm/components/Radio/Radio.js.map +1 -0
- package/dist/esm/components/Rate/Rate.js +191 -0
- package/dist/esm/components/Rate/Rate.js.map +1 -0
- package/dist/esm/components/Resizable/Resizable.js +89 -0
- package/dist/esm/components/Resizable/Resizable.js.map +1 -0
- package/dist/esm/components/ScrollArea/ScrollArea.js +45 -0
- package/dist/esm/components/ScrollArea/ScrollArea.js.map +1 -0
- package/dist/esm/components/Select/Select.js +199 -0
- package/dist/esm/components/Select/Select.js.map +1 -0
- package/dist/esm/components/Separator/Separator.js +7 -0
- package/dist/esm/components/Separator/Separator.js.map +1 -0
- package/dist/esm/components/Sheet/Sheet.js +141 -0
- package/dist/esm/components/Sheet/Sheet.js.map +1 -0
- package/dist/esm/components/Sidebar/Sidebar.js +30 -0
- package/dist/esm/components/Sidebar/Sidebar.js.map +1 -0
- package/dist/esm/components/Skeleton/Skeleton.js +12 -0
- package/dist/esm/components/Skeleton/Skeleton.js.map +1 -0
- package/dist/esm/components/Slider/Slider.js +420 -0
- package/dist/esm/components/Slider/Slider.js.map +1 -0
- package/dist/esm/components/Stepper/Stepper.js +886 -0
- package/dist/esm/components/Stepper/Stepper.js.map +1 -0
- package/dist/esm/components/Stepper/StepperWrapper.js +80 -0
- package/dist/esm/components/Stepper/StepperWrapper.js.map +1 -0
- package/dist/esm/components/Stepper/index.js +21 -0
- package/dist/esm/components/Stepper/index.js.map +1 -0
- package/dist/esm/components/Switch/Switch.js +126 -0
- package/dist/esm/components/Switch/Switch.js.map +1 -0
- package/dist/esm/components/Table/TableFilter/data-table-date-filter.js +126 -0
- package/dist/esm/components/Table/TableFilter/data-table-date-filter.js.map +1 -0
- package/dist/esm/components/Table/TableFilter/data-table-filter-popover.js +138 -0
- package/dist/esm/components/Table/TableFilter/data-table-filter-popover.js.map +1 -0
- package/dist/esm/components/Table/TableFilter/data-table-slider-filter.js +164 -0
- package/dist/esm/components/Table/TableFilter/data-table-slider-filter.js.map +1 -0
- package/dist/esm/components/Table/data-table-column-header.js +82 -0
- package/dist/esm/components/Table/data-table-column-header.js.map +1 -0
- package/dist/esm/components/Table/data-table-pagination.js +73 -0
- package/dist/esm/components/Table/data-table-pagination.js.map +1 -0
- package/dist/esm/components/Table/data-table.js +94 -0
- package/dist/esm/components/Table/data-table.js.map +1 -0
- package/dist/esm/components/Tabs/Tabs.js +540 -0
- package/dist/esm/components/Tabs/Tabs.js.map +1 -0
- package/dist/esm/components/Tabs/classes.js +345 -0
- package/dist/esm/components/Tabs/classes.js.map +1 -0
- package/dist/esm/components/Textarea/Textarea.js +132 -0
- package/dist/esm/components/Textarea/Textarea.js.map +1 -0
- package/dist/esm/components/TimeGridView.js +101 -0
- package/dist/esm/components/TimeGridView.js.map +1 -0
- package/dist/esm/components/Toast/Toast.js +80 -0
- package/dist/esm/components/Toast/Toast.js.map +1 -0
- package/dist/esm/components/Toggle/Toggle.js +23 -0
- package/dist/esm/components/Toggle/Toggle.js.map +1 -0
- package/dist/esm/components/Tooltip/Tooltip.js +120 -0
- package/dist/esm/components/Tooltip/Tooltip.js.map +1 -0
- package/dist/esm/components/Tour/Tour.js +948 -0
- package/dist/esm/components/Tour/Tour.js.map +1 -0
- package/dist/esm/components/Tour/TourWrapper.js +67 -0
- package/dist/esm/components/Tour/TourWrapper.js.map +1 -0
- package/dist/esm/components/Tour/index.js +38 -0
- package/dist/esm/components/Tour/index.js.map +1 -0
- package/dist/esm/components/Upload/Upload.js +948 -0
- package/dist/esm/components/Upload/Upload.js.map +1 -0
- package/dist/esm/components/WheelColumn.js +127 -0
- package/dist/esm/components/WheelColumn.js.map +1 -0
- package/dist/esm/constants/common.js +5 -0
- package/dist/esm/constants/common.js.map +1 -0
- package/dist/esm/favicon.ico +0 -0
- package/dist/esm/hooks/use-callback-ref.js +14 -0
- package/dist/esm/hooks/use-callback-ref.js.map +1 -0
- package/dist/esm/hooks/use-debounced-callback.js +21 -0
- package/dist/esm/hooks/use-debounced-callback.js.map +1 -0
- package/dist/esm/hooks/use-debounced-value.js +12 -0
- package/dist/esm/hooks/use-debounced-value.js.map +1 -0
- package/dist/esm/hooks/use-event-listener.js +21 -0
- package/dist/esm/hooks/use-event-listener.js.map +1 -0
- package/dist/esm/hooks/use-intersection-observer.js +56 -0
- package/dist/esm/hooks/use-intersection-observer.js.map +1 -0
- package/dist/esm/hooks/use-isomorphic-layout-effect.js +6 -0
- package/dist/esm/hooks/use-isomorphic-layout-effect.js.map +1 -0
- package/dist/esm/hooks/use-media-query.js +22 -0
- package/dist/esm/hooks/use-media-query.js.map +1 -0
- package/dist/esm/hooks/use-on-click-outside.js +18 -0
- package/dist/esm/hooks/use-on-click-outside.js.map +1 -0
- package/dist/esm/hooks/use-script.js +46 -0
- package/dist/esm/hooks/use-script.js.map +1 -0
- package/dist/esm/hooks/use-scroll-lock.js +27 -0
- package/dist/esm/hooks/use-scroll-lock.js.map +1 -0
- package/dist/esm/image.png +0 -0
- package/dist/esm/index.js +223 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/TextAnimation/BlurText.js +84 -0
- package/dist/esm/lib/TextAnimation/BlurText.js.map +1 -0
- package/dist/esm/lib/TextAnimation/CircularText.js +96 -0
- package/dist/esm/lib/TextAnimation/CircularText.js.map +1 -0
- package/dist/esm/lib/TextAnimation/FlipWords.js +103 -0
- package/dist/esm/lib/TextAnimation/FlipWords.js.map +1 -0
- package/dist/esm/lib/TextAnimation/GradientText.js +54 -0
- package/dist/esm/lib/TextAnimation/GradientText.js.map +1 -0
- package/dist/esm/lib/TextAnimation/RollingText.js +70 -0
- package/dist/esm/lib/TextAnimation/RollingText.js.map +1 -0
- package/dist/esm/lib/TextAnimation/RotatingText.js +38 -0
- package/dist/esm/lib/TextAnimation/RotatingText.js.map +1 -0
- package/dist/esm/lib/TextAnimation/ShimmeringText.js +64 -0
- package/dist/esm/lib/TextAnimation/ShimmeringText.js.map +1 -0
- package/dist/esm/lib/TextAnimation/SplittingText.js +86 -0
- package/dist/esm/lib/TextAnimation/SplittingText.js.map +1 -0
- package/dist/esm/lib/TextAnimation/TextGenerateEffect.js +59 -0
- package/dist/esm/lib/TextAnimation/TextGenerateEffect.js.map +1 -0
- package/dist/esm/lib/TextAnimation/TextHoverEffect.js +128 -0
- package/dist/esm/lib/TextAnimation/TextHoverEffect.js.map +1 -0
- package/dist/esm/lib/TextAnimation/TextPressureEffect.js +135 -0
- package/dist/esm/lib/TextAnimation/TextPressureEffect.js.map +1 -0
- package/dist/esm/lib/TextAnimation/TypingText.js +118 -0
- package/dist/esm/lib/TextAnimation/TypingText.js.map +1 -0
- package/dist/esm/lib/TextAnimation/WritingText.js +45 -0
- package/dist/esm/lib/TextAnimation/WritingText.js.map +1 -0
- package/dist/esm/node_modules/.pnpm/react-viewer@3.2.2/node_modules/react-viewer/dist/index.js +865 -0
- package/dist/esm/node_modules/.pnpm/react-viewer@3.2.2/node_modules/react-viewer/dist/index.js.map +1 -0
- package/dist/esm/node_modules/.pnpm/viewerjs@1.11.7/node_modules/viewerjs/dist/viewer.css +1 -0
- package/dist/esm/styles/animation.css +1 -0
- package/dist/esm/styles/index.css +1 -0
- package/dist/esm/styles/theme.css +1 -0
- package/dist/esm/utils/animations.js +189 -0
- package/dist/esm/utils/animations.js.map +1 -0
- package/dist/esm/utils/css.js +25 -0
- package/dist/esm/utils/css.js.map +1 -0
- package/dist/esm/utils/data-table.js +20 -0
- package/dist/esm/utils/data-table.js.map +1 -0
- package/dist/esm/utils/datetime.js +17 -0
- package/dist/esm/utils/datetime.js.map +1 -0
- package/dist/esm/vite.svg +1 -0
- package/dist/esm/wave.png +0 -0
- package/dist/types/components/Accordion/Accordion.d.ts +49 -0
- package/dist/types/components/Accordion/Accordion.d.ts.map +1 -0
- package/dist/types/components/Accordion/index.d.ts +3 -0
- package/dist/types/components/Accordion/index.d.ts.map +1 -0
- package/dist/types/components/Avatar/Avatar.d.ts +18 -0
- package/dist/types/components/Avatar/Avatar.d.ts.map +1 -0
- package/dist/types/components/Avatar/index.d.ts +3 -0
- package/dist/types/components/Avatar/index.d.ts.map +1 -0
- package/dist/types/components/Badge/Badge.d.ts +10 -0
- package/dist/types/components/Badge/Badge.d.ts.map +1 -0
- package/dist/types/components/Badge/index.d.ts +2 -0
- package/dist/types/components/Badge/index.d.ts.map +1 -0
- package/dist/types/components/Breadcrumb/Breadcrumb.d.ts +23 -0
- package/dist/types/components/Breadcrumb/Breadcrumb.d.ts.map +1 -0
- package/dist/types/components/Breadcrumb/index.d.ts +2 -0
- package/dist/types/components/Breadcrumb/index.d.ts.map +1 -0
- package/dist/types/components/Button/Button.d.ts +10 -0
- package/dist/types/components/Button/Button.d.ts.map +1 -0
- package/dist/types/components/Button/ButtonGroup.d.ts +16 -0
- package/dist/types/components/Button/ButtonGroup.d.ts.map +1 -0
- package/dist/types/components/Button/index.d.ts +5 -0
- package/dist/types/components/Button/index.d.ts.map +1 -0
- package/dist/types/components/Calendar/Calendar.d.ts +15 -0
- package/dist/types/components/Calendar/Calendar.d.ts.map +1 -0
- package/dist/types/components/Calendar/index.d.ts +3 -0
- package/dist/types/components/Calendar/index.d.ts.map +1 -0
- package/dist/types/components/Carousel/Carousel.d.ts +79 -0
- package/dist/types/components/Carousel/Carousel.d.ts.map +1 -0
- package/dist/types/components/Carousel/index.d.ts +4 -0
- package/dist/types/components/Carousel/index.d.ts.map +1 -0
- package/dist/types/components/Checkbox/Checkbox.d.ts +15 -0
- package/dist/types/components/Checkbox/Checkbox.d.ts.map +1 -0
- package/dist/types/components/Checkbox/index.d.ts +2 -0
- package/dist/types/components/Checkbox/index.d.ts.map +1 -0
- package/dist/types/components/Collapsible/Collapsible.d.ts +17 -0
- package/dist/types/components/Collapsible/Collapsible.d.ts.map +1 -0
- package/dist/types/components/Collapsible/index.d.ts +2 -0
- package/dist/types/components/Collapsible/index.d.ts.map +1 -0
- package/dist/types/components/Command/Command.d.ts +39 -0
- package/dist/types/components/Command/Command.d.ts.map +1 -0
- package/dist/types/components/Command/index.d.ts +15 -0
- package/dist/types/components/Command/index.d.ts.map +1 -0
- package/dist/types/components/ContextMenu/ContextMenu.d.ts +64 -0
- package/dist/types/components/ContextMenu/ContextMenu.d.ts.map +1 -0
- package/dist/types/components/ContextMenu/index.d.ts +23 -0
- package/dist/types/components/ContextMenu/index.d.ts.map +1 -0
- package/dist/types/components/Cropper/Cropper.d.ts +86 -0
- package/dist/types/components/Cropper/Cropper.d.ts.map +1 -0
- package/dist/types/components/Cropper/CropperTool.d.ts +149 -0
- package/dist/types/components/Cropper/CropperTool.d.ts.map +1 -0
- package/dist/types/components/Cropper/index.d.ts +4 -0
- package/dist/types/components/Cropper/index.d.ts.map +1 -0
- package/dist/types/components/Cropper/utils.d.ts +130 -0
- package/dist/types/components/Cropper/utils.d.ts.map +1 -0
- package/dist/types/components/DatePicker/DatePicker.d.ts +56 -0
- package/dist/types/components/DatePicker/DatePicker.d.ts.map +1 -0
- package/dist/types/components/DatePicker/RangePicker.d.ts +42 -0
- package/dist/types/components/DatePicker/RangePicker.d.ts.map +1 -0
- package/dist/types/components/DatePicker/TimePicker.d.ts +43 -0
- package/dist/types/components/DatePicker/TimePicker.d.ts.map +1 -0
- package/dist/types/components/DatePicker/index.d.ts +7 -0
- package/dist/types/components/DatePicker/index.d.ts.map +1 -0
- package/dist/types/components/Dialog/Dialog.d.ts +45 -0
- package/dist/types/components/Dialog/Dialog.d.ts.map +1 -0
- package/dist/types/components/Dialog/index.d.ts +2 -0
- package/dist/types/components/Dialog/index.d.ts.map +1 -0
- package/dist/types/components/DropdownMenu/DropdownMenu.d.ts +65 -0
- package/dist/types/components/DropdownMenu/DropdownMenu.d.ts.map +1 -0
- package/dist/types/components/DropdownMenu/index.d.ts +22 -0
- package/dist/types/components/DropdownMenu/index.d.ts.map +1 -0
- package/dist/types/components/FloatLabel.d.ts +8 -0
- package/dist/types/components/FloatLabel.d.ts.map +1 -0
- package/dist/types/components/Glass/Glass.d.ts +10 -0
- package/dist/types/components/Glass/Glass.d.ts.map +1 -0
- package/dist/types/components/Glass/index.d.ts +2 -0
- package/dist/types/components/Glass/index.d.ts.map +1 -0
- package/dist/types/components/ImageViewer/ImageViewer.d.ts +58 -0
- package/dist/types/components/ImageViewer/ImageViewer.d.ts.map +1 -0
- package/dist/types/components/ImageViewer/index.d.ts +4 -0
- package/dist/types/components/ImageViewer/index.d.ts.map +1 -0
- package/dist/types/components/Input/Input.d.ts +27 -0
- package/dist/types/components/Input/Input.d.ts.map +1 -0
- package/dist/types/components/Input/index.d.ts +2 -0
- package/dist/types/components/Input/index.d.ts.map +1 -0
- package/dist/types/components/InputOTP/InputOTP.d.ts +20 -0
- package/dist/types/components/InputOTP/InputOTP.d.ts.map +1 -0
- package/dist/types/components/InputOTP/index.d.ts +2 -0
- package/dist/types/components/InputOTP/index.d.ts.map +1 -0
- package/dist/types/components/Interactive/3DCard.d.ts +28 -0
- package/dist/types/components/Interactive/3DCard.d.ts.map +1 -0
- package/dist/types/components/Interactive/3DMarquee.d.ts +20 -0
- package/dist/types/components/Interactive/3DMarquee.d.ts.map +1 -0
- package/dist/types/components/Interactive/CursorFollow.d.ts +75 -0
- package/dist/types/components/Interactive/CursorFollow.d.ts.map +1 -0
- package/dist/types/components/Interactive/index.cursor.d.ts +7 -0
- package/dist/types/components/Interactive/index.cursor.d.ts.map +1 -0
- package/dist/types/components/Interactive/index.d.ts +2 -0
- package/dist/types/components/Interactive/index.d.ts.map +1 -0
- package/dist/types/components/Label/Label.d.ts +3 -0
- package/dist/types/components/Label/Label.d.ts.map +1 -0
- package/dist/types/components/Label/index.d.ts +2 -0
- package/dist/types/components/Label/index.d.ts.map +1 -0
- package/dist/types/components/Marquee/Marquee.d.ts +31 -0
- package/dist/types/components/Marquee/Marquee.d.ts.map +1 -0
- package/dist/types/components/Marquee/MarqueeWrapper.d.ts +10 -0
- package/dist/types/components/Marquee/MarqueeWrapper.d.ts.map +1 -0
- package/dist/types/components/Marquee/index.d.ts +13 -0
- package/dist/types/components/Marquee/index.d.ts.map +1 -0
- package/dist/types/components/Masonry/Masonry.d.ts +41 -0
- package/dist/types/components/Masonry/Masonry.d.ts.map +1 -0
- package/dist/types/components/Masonry/MasonryWrapper.d.ts +29 -0
- package/dist/types/components/Masonry/MasonryWrapper.d.ts.map +1 -0
- package/dist/types/components/Masonry/index.d.ts +5 -0
- package/dist/types/components/Masonry/index.d.ts.map +1 -0
- package/dist/types/components/Pagination/Pagination.d.ts +24 -0
- package/dist/types/components/Pagination/Pagination.d.ts.map +1 -0
- package/dist/types/components/Pagination/index.d.ts +11 -0
- package/dist/types/components/Pagination/index.d.ts.map +1 -0
- package/dist/types/components/Popover/Popover.d.ts +22 -0
- package/dist/types/components/Popover/Popover.d.ts.map +1 -0
- package/dist/types/components/Popover/index.d.ts +5 -0
- package/dist/types/components/Popover/index.d.ts.map +1 -0
- package/dist/types/components/QrCode/QrCode.d.ts +51 -0
- package/dist/types/components/QrCode/QrCode.d.ts.map +1 -0
- package/dist/types/components/QrCode/index.d.ts +13 -0
- package/dist/types/components/QrCode/index.d.ts.map +1 -0
- package/dist/types/components/Radio/Radio.d.ts +35 -0
- package/dist/types/components/Radio/Radio.d.ts.map +1 -0
- package/dist/types/components/Radio/index.d.ts +2 -0
- package/dist/types/components/Radio/index.d.ts.map +1 -0
- package/dist/types/components/Rate/Rate.d.ts +26 -0
- package/dist/types/components/Rate/Rate.d.ts.map +1 -0
- package/dist/types/components/Rate/index.d.ts +3 -0
- package/dist/types/components/Rate/index.d.ts.map +1 -0
- package/dist/types/components/Resizable/Resizable.d.ts +71 -0
- package/dist/types/components/Resizable/Resizable.d.ts.map +1 -0
- package/dist/types/components/Resizable/index.d.ts +4 -0
- package/dist/types/components/Resizable/index.d.ts.map +1 -0
- package/dist/types/components/ScrollArea/ScrollArea.d.ts +19 -0
- package/dist/types/components/ScrollArea/ScrollArea.d.ts.map +1 -0
- package/dist/types/components/ScrollArea/index.d.ts +2 -0
- package/dist/types/components/ScrollArea/index.d.ts.map +1 -0
- package/dist/types/components/Select/Select.d.ts +33 -0
- package/dist/types/components/Select/Select.d.ts.map +1 -0
- package/dist/types/components/Select/index.d.ts +2 -0
- package/dist/types/components/Select/index.d.ts.map +1 -0
- package/dist/types/components/Separator/Separator.d.ts +5 -0
- package/dist/types/components/Separator/Separator.d.ts.map +1 -0
- package/dist/types/components/Separator/index.d.ts +2 -0
- package/dist/types/components/Separator/index.d.ts.map +1 -0
- package/dist/types/components/Sheet/Sheet.d.ts +36 -0
- package/dist/types/components/Sheet/Sheet.d.ts.map +1 -0
- package/dist/types/components/Sheet/index.d.ts +2 -0
- package/dist/types/components/Sheet/index.d.ts.map +1 -0
- package/dist/types/components/Sidebar/Sidebar.d.ts +50 -0
- package/dist/types/components/Sidebar/Sidebar.d.ts.map +1 -0
- package/dist/types/components/Sidebar/index.d.ts +4 -0
- package/dist/types/components/Sidebar/index.d.ts.map +1 -0
- package/dist/types/components/Skeleton/Skeleton.d.ts +6 -0
- package/dist/types/components/Skeleton/Skeleton.d.ts.map +1 -0
- package/dist/types/components/Skeleton/index.d.ts +2 -0
- package/dist/types/components/Skeleton/index.d.ts.map +1 -0
- package/dist/types/components/Slider/Slider.d.ts +25 -0
- package/dist/types/components/Slider/Slider.d.ts.map +1 -0
- package/dist/types/components/Slider/index.d.ts +2 -0
- package/dist/types/components/Slider/index.d.ts.map +1 -0
- package/dist/types/components/Stepper/Stepper.d.ts +86 -0
- package/dist/types/components/Stepper/Stepper.d.ts.map +1 -0
- package/dist/types/components/Stepper/StepperWrapper.d.ts +25 -0
- package/dist/types/components/Stepper/StepperWrapper.d.ts.map +1 -0
- package/dist/types/components/Stepper/index.d.ts +18 -0
- package/dist/types/components/Stepper/index.d.ts.map +1 -0
- package/dist/types/components/Switch/Switch.d.ts +14 -0
- package/dist/types/components/Switch/Switch.d.ts.map +1 -0
- package/dist/types/components/Switch/index.d.ts +2 -0
- package/dist/types/components/Switch/index.d.ts.map +1 -0
- package/dist/types/components/Table/TableFilter/data-table-date-filter.d.ts +9 -0
- package/dist/types/components/Table/TableFilter/data-table-date-filter.d.ts.map +1 -0
- package/dist/types/components/Table/TableFilter/data-table-filter-popover.d.ts +11 -0
- package/dist/types/components/Table/TableFilter/data-table-filter-popover.d.ts.map +1 -0
- package/dist/types/components/Table/TableFilter/data-table-slider-filter.d.ts +8 -0
- package/dist/types/components/Table/TableFilter/data-table-slider-filter.d.ts.map +1 -0
- package/dist/types/components/Table/TableWrapper.d.ts +2 -0
- package/dist/types/components/Table/TableWrapper.d.ts.map +1 -0
- package/dist/types/components/Table/data-table-column-header.d.ts +9 -0
- package/dist/types/components/Table/data-table-column-header.d.ts.map +1 -0
- package/dist/types/components/Table/data-table-pagination.d.ts +12 -0
- package/dist/types/components/Table/data-table-pagination.d.ts.map +1 -0
- package/dist/types/components/Table/data-table-toolbar.d.ts +10 -0
- package/dist/types/components/Table/data-table-toolbar.d.ts.map +1 -0
- package/dist/types/components/Table/data-table-view-options.d.ts +9 -0
- package/dist/types/components/Table/data-table-view-options.d.ts.map +1 -0
- package/dist/types/components/Table/data-table.d.ts +18 -0
- package/dist/types/components/Table/data-table.d.ts.map +1 -0
- package/dist/types/components/Table/index.d.ts +2 -0
- package/dist/types/components/Table/index.d.ts.map +1 -0
- package/dist/types/components/Table/select-column.d.ts +5 -0
- package/dist/types/components/Table/select-column.d.ts.map +1 -0
- package/dist/types/components/Tabs/Tabs.d.ts +22 -0
- package/dist/types/components/Tabs/Tabs.d.ts.map +1 -0
- package/dist/types/components/Tabs/classes.d.ts +29 -0
- package/dist/types/components/Tabs/classes.d.ts.map +1 -0
- package/dist/types/components/Tabs/index.d.ts +4 -0
- package/dist/types/components/Tabs/index.d.ts.map +1 -0
- package/dist/types/components/Tabs/types.d.ts +15 -0
- package/dist/types/components/Tabs/types.d.ts.map +1 -0
- package/dist/types/components/Textarea/Textarea.d.ts +17 -0
- package/dist/types/components/Textarea/Textarea.d.ts.map +1 -0
- package/dist/types/components/Textarea/index.d.ts +2 -0
- package/dist/types/components/Textarea/index.d.ts.map +1 -0
- package/dist/types/components/Theme/ThemeShowcase.d.ts +3 -0
- package/dist/types/components/Theme/ThemeShowcase.d.ts.map +1 -0
- package/dist/types/components/TimeGridView.d.ts +15 -0
- package/dist/types/components/TimeGridView.d.ts.map +1 -0
- package/dist/types/components/Toast/Toast.d.ts +12 -0
- package/dist/types/components/Toast/Toast.d.ts.map +1 -0
- package/dist/types/components/Toast/index.d.ts +3 -0
- package/dist/types/components/Toast/index.d.ts.map +1 -0
- package/dist/types/components/Toggle/Toggle.d.ts +10 -0
- package/dist/types/components/Toggle/Toggle.d.ts.map +1 -0
- package/dist/types/components/Toggle/index.d.ts +2 -0
- package/dist/types/components/Toggle/index.d.ts.map +1 -0
- package/dist/types/components/Tooltip/Tooltip.d.ts +19 -0
- package/dist/types/components/Tooltip/Tooltip.d.ts.map +1 -0
- package/dist/types/components/Tooltip/index.d.ts +3 -0
- package/dist/types/components/Tooltip/index.d.ts.map +1 -0
- package/dist/types/components/Tour/Tour.d.ts +105 -0
- package/dist/types/components/Tour/Tour.d.ts.map +1 -0
- package/dist/types/components/Tour/TourWrapper.d.ts +46 -0
- package/dist/types/components/Tour/TourWrapper.d.ts.map +1 -0
- package/dist/types/components/Tour/index.d.ts +36 -0
- package/dist/types/components/Tour/index.d.ts.map +1 -0
- package/dist/types/components/TreeSelect/TreeSelect.d.ts +2 -0
- package/dist/types/components/TreeSelect/TreeSelect.d.ts.map +1 -0
- package/dist/types/components/TreeSelect/index.d.ts +2 -0
- package/dist/types/components/TreeSelect/index.d.ts.map +1 -0
- package/dist/types/components/Upload/Upload.d.ts +69 -0
- package/dist/types/components/Upload/Upload.d.ts.map +1 -0
- package/dist/types/components/Upload/index.d.ts +2 -0
- package/dist/types/components/Upload/index.d.ts.map +1 -0
- package/dist/types/components/WheelColumn.d.ts +15 -0
- package/dist/types/components/WheelColumn.d.ts.map +1 -0
- package/dist/types/config/data-table.d.ts +125 -0
- package/dist/types/config/data-table.d.ts.map +1 -0
- package/dist/types/constants/common.d.ts +4 -0
- package/dist/types/constants/common.d.ts.map +1 -0
- package/dist/types/constants/theme.d.ts +13 -0
- package/dist/types/constants/theme.d.ts.map +1 -0
- package/dist/types/hooks/index.d.ts +10 -0
- package/dist/types/hooks/index.d.ts.map +1 -0
- package/dist/types/hooks/use-callback-ref.d.ts +10 -0
- package/dist/types/hooks/use-callback-ref.d.ts.map +1 -0
- package/dist/types/hooks/use-data-table.d.ts +26 -0
- package/dist/types/hooks/use-data-table.d.ts.map +1 -0
- package/dist/types/hooks/use-debounced-callback.d.ts +2 -0
- package/dist/types/hooks/use-debounced-callback.d.ts.map +1 -0
- package/dist/types/hooks/use-debounced-value.d.ts +9 -0
- package/dist/types/hooks/use-debounced-value.d.ts.map +1 -0
- package/dist/types/hooks/use-event-listener.d.ts +7 -0
- package/dist/types/hooks/use-event-listener.d.ts.map +1 -0
- package/dist/types/hooks/use-intersection-observer.d.ts +20 -0
- package/dist/types/hooks/use-intersection-observer.d.ts.map +1 -0
- package/dist/types/hooks/use-isomorphic-layout-effect.d.ts +3 -0
- package/dist/types/hooks/use-isomorphic-layout-effect.d.ts.map +1 -0
- package/dist/types/hooks/use-media-query.d.ts +7 -0
- package/dist/types/hooks/use-media-query.d.ts.map +1 -0
- package/dist/types/hooks/use-mouse-position.d.ts +14 -0
- package/dist/types/hooks/use-mouse-position.d.ts.map +1 -0
- package/dist/types/hooks/use-on-click-outside.d.ts +5 -0
- package/dist/types/hooks/use-on-click-outside.d.ts.map +1 -0
- package/dist/types/hooks/use-script.d.ts +9 -0
- package/dist/types/hooks/use-script.d.ts.map +1 -0
- package/dist/types/hooks/use-scroll-lock.d.ts +13 -0
- package/dist/types/hooks/use-scroll-lock.d.ts.map +1 -0
- package/dist/types/index.d.ts +72 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/BlurText.d.ts +18 -0
- package/dist/types/lib/TextAnimation/BlurText.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/CircularText.d.ts +10 -0
- package/dist/types/lib/TextAnimation/CircularText.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/FlipWords.d.ts +10 -0
- package/dist/types/lib/TextAnimation/FlipWords.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/GradientText.d.ts +11 -0
- package/dist/types/lib/TextAnimation/GradientText.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/RollingText.d.ts +12 -0
- package/dist/types/lib/TextAnimation/RollingText.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/RotatingText.d.ts +11 -0
- package/dist/types/lib/TextAnimation/RotatingText.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/ShimmeringText.d.ts +12 -0
- package/dist/types/lib/TextAnimation/ShimmeringText.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/SplittingText.d.ts +26 -0
- package/dist/types/lib/TextAnimation/SplittingText.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/TextGenerateEffect.d.ts +10 -0
- package/dist/types/lib/TextAnimation/TextGenerateEffect.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/TextHoverEffect.d.ts +6 -0
- package/dist/types/lib/TextAnimation/TextHoverEffect.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/TextPressureEffect.d.ts +20 -0
- package/dist/types/lib/TextAnimation/TextPressureEffect.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/TypingText.d.ts +27 -0
- package/dist/types/lib/TextAnimation/TypingText.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/WritingText.d.ts +13 -0
- package/dist/types/lib/TextAnimation/WritingText.d.ts.map +1 -0
- package/dist/types/lib/TextAnimation/index.d.ts +16 -0
- package/dist/types/lib/TextAnimation/index.d.ts.map +1 -0
- package/dist/types/types/data-table.d.ts +44 -0
- package/dist/types/types/data-table.d.ts.map +1 -0
- package/dist/types/types/theme.d.ts +11 -0
- package/dist/types/types/theme.d.ts.map +1 -0
- package/dist/types/types/variables.d.ts +6 -0
- package/dist/types/types/variables.d.ts.map +1 -0
- package/dist/types/utils/animations.d.ts +47 -0
- package/dist/types/utils/animations.d.ts.map +1 -0
- package/dist/types/utils/css.d.ts +4 -0
- package/dist/types/utils/css.d.ts.map +1 -0
- package/dist/types/utils/data-table.d.ts +13 -0
- package/dist/types/utils/data-table.d.ts.map +1 -0
- package/dist/types/utils/datetime.d.ts +2 -0
- package/dist/types/utils/datetime.d.ts.map +1 -0
- package/dist/types/utils/parsers.d.ts +38 -0
- package/dist/types/utils/parsers.d.ts.map +1 -0
- package/package.json +968 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Cropper.cjs","sources":["../../../../src/components/Cropper/Cropper.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn, Slot, useComposedRefs } from \"@dsui/ui/index\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nconst ROOT_NAME = \"Cropper\";\nconst CONTENT_NAME = \"CropperContent\";\nconst IMAGE_NAME = \"CropperImage\";\nconst VIDEO_NAME = \"CropperVideo\";\nconst AREA_NAME = \"CropperArea\";\n\ninterface Point {\n x: number;\n y: number;\n}\n\ninterface GestureEvent extends UIEvent {\n rotation: number;\n scale: number;\n clientX: number;\n clientY: number;\n}\n\ninterface Size {\n width: number;\n height: number;\n}\n\ninterface Area {\n width: number;\n height: number;\n x: number;\n y: number;\n}\n\ninterface MediaSize {\n width: number;\n height: number;\n naturalWidth: number;\n naturalHeight: number;\n}\n\ntype Shape = \"rectangle\" | \"circle\";\ntype ObjectFit = \"contain\" | \"cover\" | \"horizontal-cover\" | \"vertical-cover\";\n\ninterface DivProps extends React.ComponentProps<\"div\"> {\n asChild?: boolean;\n}\n\nconst MAX_CACHE_SIZE = 200;\nconst DPR = typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1;\n\nconst rotationSizeCache = new Map<string, Size>();\nconst cropSizeCache = new Map<string, Size>();\nconst croppedAreaCache = new Map<\n string,\n { croppedAreaPercentages: Area; croppedAreaPixels: Area }\n>();\nconst onPositionClampCache = new Map<string, Point>();\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction quantize(n: number, step = 2 / DPR): number {\n return Math.round(n / step) * step;\n}\n\nfunction quantizePosition(n: number, step = 4 / DPR): number {\n return Math.round(n / step) * step;\n}\n\nfunction quantizeZoom(n: number, step = 0.01): number {\n return Math.round(n / step) * step;\n}\n\nfunction quantizeRotation(n: number, step = 1.0): number {\n return Math.round(n / step) * step;\n}\n\nfunction snapToDevicePixel(n: number): number {\n return Math.round(n * DPR) / DPR;\n}\n\nfunction lruGet<K, V>(map: Map<K, V>, key: K): V | undefined {\n const v = map.get(key);\n if (v !== undefined) {\n map.delete(key);\n map.set(key, v);\n }\n return v;\n}\n\nfunction lruSet<K, V>(\n map: Map<K, V>,\n key: K,\n val: V,\n max = MAX_CACHE_SIZE,\n): void {\n if (map.has(key)) {\n map.delete(key);\n }\n map.set(key, val);\n if (map.size > max) {\n const firstKey = map.keys().next().value;\n if (firstKey !== undefined) {\n map.delete(firstKey);\n }\n }\n}\n\nfunction getDistanceBetweenPoints(pointA: Point, pointB: Point): number {\n return Math.sqrt((pointA.y - pointB.y) ** 2 + (pointA.x - pointB.x) ** 2);\n}\n\nfunction getCenter(a: Point, b: Point): Point {\n return {\n x: (b.x + a.x) * 0.5,\n y: (b.y + a.y) * 0.5,\n };\n}\n\nfunction getRotationBetweenPoints(pointA: Point, pointB: Point): number {\n return (Math.atan2(pointB.y - pointA.y, pointB.x - pointA.x) * 180) / Math.PI;\n}\n\nfunction getRadianAngle(degreeValue: number): number {\n return (degreeValue * Math.PI) / 180;\n}\n\nfunction rotateSize(width: number, height: number, rotation: number): Size {\n const cacheKey = `${quantize(width)}-${quantize(height)}-${quantizeRotation(rotation)}`;\n\n const cached = lruGet(rotationSizeCache, cacheKey);\n if (cached) {\n return cached;\n }\n const rotRad = getRadianAngle(rotation);\n const cosRot = Math.cos(rotRad);\n const sinRot = Math.sin(rotRad);\n\n const result: Size = {\n width: Math.abs(cosRot * width) + Math.abs(sinRot * height),\n height: Math.abs(sinRot * width) + Math.abs(cosRot * height),\n };\n\n lruSet(rotationSizeCache, cacheKey, result, MAX_CACHE_SIZE);\n return result;\n}\n\nfunction getCropSize(\n mediaWidth: number,\n mediaHeight: number,\n contentWidth: number,\n contentHeight: number,\n aspect: number,\n rotation = 0,\n): Size {\n const cacheKey = `${quantize(mediaWidth, 8)}-${quantize(mediaHeight, 8)}-${quantize(contentWidth, 8)}-${quantize(contentHeight, 8)}-${quantize(aspect, 0.01)}-${quantizeRotation(rotation)}`;\n\n const cached = lruGet(cropSizeCache, cacheKey);\n if (cached) {\n return cached;\n }\n const { width, height } = rotateSize(mediaWidth, mediaHeight, rotation);\n const fittingWidth = Math.min(width, contentWidth);\n const fittingHeight = Math.min(height, contentHeight);\n\n const result: Size =\n fittingWidth > fittingHeight * aspect\n ? {\n width: fittingHeight * aspect,\n height: fittingHeight,\n }\n : {\n width: fittingWidth,\n height: fittingWidth / aspect,\n };\n\n lruSet(cropSizeCache, cacheKey, result, MAX_CACHE_SIZE);\n return result;\n}\n\nfunction onPositionClamp(\n position: Point,\n mediaSize: Size,\n cropSize: Size,\n zoom: number,\n rotation = 0,\n): Point {\n const quantizedX = quantizePosition(position.x);\n const quantizedY = quantizePosition(position.y);\n\n const cacheKey = `${quantizedX}-${quantizedY}-${quantize(mediaSize.width)}-${quantize(mediaSize.height)}-${quantize(cropSize.width)}-${quantize(cropSize.height)}-${quantizeZoom(zoom)}-${quantizeRotation(rotation)}`;\n\n const cached = lruGet(onPositionClampCache, cacheKey);\n if (cached) {\n return cached;\n }\n const { width, height } = rotateSize(\n mediaSize.width,\n mediaSize.height,\n rotation,\n );\n\n const maxPositionX = width * zoom * 0.5 - cropSize.width * 0.5;\n const maxPositionY = height * zoom * 0.5 - cropSize.height * 0.5;\n\n const result: Point = {\n x: clamp(position.x, -maxPositionX, maxPositionX),\n y: clamp(position.y, -maxPositionY, maxPositionY),\n };\n\n lruSet(onPositionClampCache, cacheKey, result, MAX_CACHE_SIZE);\n return result;\n}\n\nfunction getCroppedArea(\n crop: Point,\n mediaSize: MediaSize,\n cropSize: Size,\n aspect: number,\n zoom: number,\n rotation = 0,\n allowOverflow = false,\n): { croppedAreaPercentages: Area; croppedAreaPixels: Area } {\n const cacheKey = `${quantizePosition(crop.x)}-${quantizePosition(crop.y)}-${quantize(mediaSize.width)}-${quantize(mediaSize.height)}-${quantize(mediaSize.naturalWidth)}-${quantize(mediaSize.naturalHeight)}-${quantize(cropSize.width)}-${quantize(cropSize.height)}-${quantize(aspect, 0.01)}-${quantizeZoom(zoom)}-${quantizeRotation(rotation)}-${allowOverflow}`;\n\n const cached = lruGet(croppedAreaCache, cacheKey);\n\n if (cached) return cached;\n\n const onAreaLimit = !allowOverflow\n ? (max: number, value: number) => Math.min(max, Math.max(0, value))\n : (_max: number, value: number) => value;\n\n const mediaBBoxSize = rotateSize(mediaSize.width, mediaSize.height, rotation);\n const mediaNaturalBBoxSize = rotateSize(\n mediaSize.naturalWidth,\n mediaSize.naturalHeight,\n rotation,\n );\n\n const croppedAreaPercentages: Area = {\n x: onAreaLimit(\n 100,\n (((mediaBBoxSize.width - cropSize.width / zoom) / 2 - crop.x / zoom) /\n mediaBBoxSize.width) *\n 100,\n ),\n y: onAreaLimit(\n 100,\n (((mediaBBoxSize.height - cropSize.height / zoom) / 2 - crop.y / zoom) /\n mediaBBoxSize.height) *\n 100,\n ),\n width: onAreaLimit(\n 100,\n ((cropSize.width / mediaBBoxSize.width) * 100) / zoom,\n ),\n height: onAreaLimit(\n 100,\n ((cropSize.height / mediaBBoxSize.height) * 100) / zoom,\n ),\n };\n\n const widthInPixels = Math.round(\n onAreaLimit(\n mediaNaturalBBoxSize.width,\n (croppedAreaPercentages.width * mediaNaturalBBoxSize.width) / 100,\n ),\n );\n const heightInPixels = Math.round(\n onAreaLimit(\n mediaNaturalBBoxSize.height,\n (croppedAreaPercentages.height * mediaNaturalBBoxSize.height) / 100,\n ),\n );\n const isImageWiderThanHigh =\n mediaNaturalBBoxSize.width >= mediaNaturalBBoxSize.height * aspect;\n\n const sizePixels: Size = isImageWiderThanHigh\n ? {\n width: Math.round(heightInPixels * aspect),\n height: heightInPixels,\n }\n : {\n width: widthInPixels,\n height: Math.round(widthInPixels / aspect),\n };\n\n const croppedAreaPixels: Area = {\n ...sizePixels,\n x: Math.round(\n onAreaLimit(\n mediaNaturalBBoxSize.width - sizePixels.width,\n (croppedAreaPercentages.x * mediaNaturalBBoxSize.width) / 100,\n ),\n ),\n y: Math.round(\n onAreaLimit(\n mediaNaturalBBoxSize.height - sizePixels.height,\n (croppedAreaPercentages.y * mediaNaturalBBoxSize.height) / 100,\n ),\n ),\n };\n\n const result = { croppedAreaPercentages, croppedAreaPixels };\n\n lruSet(croppedAreaCache, cacheKey, result, MAX_CACHE_SIZE);\n return result;\n}\n\nfunction useLazyRef<T>(fn: () => T) {\n const ref = React.useRef<T | null>(null);\n\n if (ref.current === null) {\n ref.current = fn();\n }\n\n return ref as React.RefObject<T>;\n}\n\nconst useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? React.useLayoutEffect : React.useEffect;\n\ninterface StoreState {\n crop: Point;\n zoom: number;\n rotation: number;\n mediaSize: MediaSize | null;\n cropSize: Size | null;\n isDragging: boolean;\n isWheelZooming: boolean;\n}\n\ninterface Store {\n subscribe: (callback: () => void) => () => void;\n getState: () => StoreState;\n setState: <K extends keyof StoreState>(key: K, value: StoreState[K]) => void;\n notify: () => void;\n batch: (fn: () => void) => void;\n}\n\nfunction createStore(\n listenersRef: React.RefObject<Set<() => void>>,\n stateRef: React.RefObject<StoreState>,\n aspectRatio: number,\n allowOverflow: boolean,\n onCropChange?: (crop: Point) => void,\n onCropSizeChange?: (cropSize: Size) => void,\n onCropAreaChange?: (croppedArea: Area, croppedAreaPixels: Area) => void,\n onCropComplete?: (croppedArea: Area, croppedAreaPixels: Area) => void,\n onZoomChange?: (zoom: number) => void,\n onRotationChange?: (rotation: number) => void,\n onMediaLoaded?: (mediaSize: MediaSize) => void,\n onInteractionStart?: () => void,\n onInteractionEnd?: () => void,\n): Store {\n let isBatching = false;\n let raf: number | null = null;\n\n function notifyCropAreaChange() {\n if (raf != null) return;\n raf = requestAnimationFrame(() => {\n raf = null;\n const s = stateRef.current;\n if (s?.mediaSize && s.cropSize && onCropAreaChange) {\n const { croppedAreaPercentages, croppedAreaPixels } = getCroppedArea(\n s.crop,\n s.mediaSize,\n s.cropSize,\n aspectRatio,\n s.zoom,\n s.rotation,\n allowOverflow,\n );\n onCropAreaChange(croppedAreaPercentages, croppedAreaPixels);\n }\n });\n }\n\n const store: Store = {\n subscribe: (cb) => {\n if (listenersRef.current) {\n listenersRef.current.add(cb);\n return () => listenersRef.current?.delete(cb);\n }\n return () => {};\n },\n getState: () =>\n stateRef.current ?? {\n crop: { x: 0, y: 0 },\n zoom: 1,\n rotation: 0,\n mediaSize: null,\n cropSize: null,\n isDragging: false,\n isWheelZooming: false,\n },\n setState: (key, value) => {\n const state = stateRef.current;\n if (!state || Object.is(state[key], value)) return;\n\n state[key] = value;\n\n if (\n key === \"crop\" &&\n typeof value === \"object\" &&\n value &&\n \"x\" in value\n ) {\n onCropChange?.(value);\n } else if (key === \"zoom\" && typeof value === \"number\") {\n onZoomChange?.(value);\n } else if (key === \"rotation\" && typeof value === \"number\") {\n onRotationChange?.(value);\n } else if (\n key === \"cropSize\" &&\n typeof value === \"object\" &&\n value &&\n \"width\" in value\n ) {\n onCropSizeChange?.(value);\n } else if (\n key === \"mediaSize\" &&\n typeof value === \"object\" &&\n value &&\n \"naturalWidth\" in value\n ) {\n onMediaLoaded?.(value);\n } else if (key === \"isDragging\") {\n if (value) {\n onInteractionStart?.();\n } else {\n onInteractionEnd?.();\n const currentState = stateRef.current;\n if (\n currentState?.mediaSize &&\n currentState.cropSize &&\n onCropComplete\n ) {\n const { croppedAreaPercentages, croppedAreaPixels } =\n getCroppedArea(\n currentState.crop,\n currentState.mediaSize,\n currentState.cropSize,\n aspectRatio,\n currentState.zoom,\n currentState.rotation,\n allowOverflow,\n );\n onCropComplete(croppedAreaPercentages, croppedAreaPixels);\n }\n }\n }\n\n if (\n (key === \"crop\" ||\n key === \"zoom\" ||\n key === \"rotation\" ||\n key === \"mediaSize\" ||\n key === \"cropSize\") &&\n onCropAreaChange\n ) {\n notifyCropAreaChange();\n }\n\n if (!isBatching) {\n store.notify();\n }\n },\n notify: () => {\n if (listenersRef.current) {\n for (const cb of listenersRef.current) {\n cb();\n }\n }\n },\n batch: (fn: () => void) => {\n if (isBatching) {\n fn();\n return;\n }\n isBatching = true;\n try {\n fn();\n } finally {\n isBatching = false;\n store.notify();\n }\n },\n };\n\n return store;\n}\n\nconst StoreContext = React.createContext<Store | null>(null);\n\nfunction useStoreContext(consumerName: string) {\n const context = React.useContext(StoreContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${ROOT_NAME}\\``);\n }\n return context;\n}\n\nfunction useStore<T>(selector: (state: StoreState) => T): T {\n const store = useStoreContext(\"useStore\");\n\n const getSnapshot = React.useCallback(\n () => selector(store.getState()),\n [store, selector],\n );\n\n return React.useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);\n}\n\ntype RootElement = React.ComponentRef<typeof CropperRootImpl>;\n\ninterface CropperContextValue {\n aspectRatio: number;\n minZoom: number;\n maxZoom: number;\n zoomSpeed: number;\n keyboardStep: number;\n shape: Shape;\n objectFit: ObjectFit;\n rootRef: React.RefObject<RootElement | null>;\n allowOverflow: boolean;\n preventScrollZoom: boolean;\n withGrid: boolean;\n}\n\nconst CropperContext = React.createContext<CropperContextValue | null>(null);\n\nfunction useCropperContext(consumerName: string) {\n const context = React.useContext(CropperContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${ROOT_NAME}\\``);\n }\n return context;\n}\n\ninterface CropperRootProps extends DivProps {\n crop?: Point;\n zoom?: number;\n minZoom?: number;\n maxZoom?: number;\n zoomSpeed?: number;\n rotation?: number;\n keyboardStep?: number;\n aspectRatio?: number;\n shape?: Shape;\n objectFit?: ObjectFit;\n allowOverflow?: boolean;\n preventScrollZoom?: boolean;\n withGrid?: boolean;\n onCropChange?: (crop: Point) => void;\n onCropSizeChange?: (cropSize: Size) => void;\n onCropAreaChange?: (croppedArea: Area, croppedAreaPixels: Area) => void;\n onCropComplete?: (croppedArea: Area, croppedAreaPixels: Area) => void;\n onZoomChange?: (zoom: number) => void;\n onRotationChange?: (rotation: number) => void;\n onMediaLoaded?: (mediaSize: MediaSize) => void;\n onInteractionStart?: () => void;\n onInteractionEnd?: () => void;\n onWheelZoom?: (event: WheelEvent) => void;\n}\n\nfunction CropperRoot(props: CropperRootProps) {\n const {\n crop = { x: 0, y: 0 },\n zoom = 1,\n minZoom = 1,\n maxZoom = 3,\n zoomSpeed = 1,\n rotation = 0,\n keyboardStep = 1,\n aspectRatio = 4 / 3,\n shape = \"rectangle\",\n objectFit = \"contain\",\n allowOverflow = false,\n preventScrollZoom = false,\n withGrid = false,\n onCropChange,\n onCropSizeChange,\n onCropAreaChange,\n onCropComplete,\n onZoomChange,\n onRotationChange,\n onMediaLoaded,\n onInteractionStart,\n onInteractionEnd,\n className,\n ...rootProps\n } = props;\n\n const listenersRef = useLazyRef(() => new Set<() => void>());\n const stateRef = useLazyRef<StoreState>(() => ({\n crop,\n zoom,\n rotation,\n mediaSize: null,\n cropSize: null,\n isDragging: false,\n isWheelZooming: false,\n }));\n\n const rootRef = React.useRef<RootElement>(null);\n\n const store = React.useMemo(\n () =>\n createStore(\n listenersRef,\n stateRef,\n aspectRatio,\n allowOverflow,\n onCropChange,\n onCropSizeChange,\n onCropAreaChange,\n onCropComplete,\n onZoomChange,\n onRotationChange,\n onMediaLoaded,\n onInteractionStart,\n onInteractionEnd,\n ),\n [\n listenersRef,\n stateRef,\n aspectRatio,\n allowOverflow,\n onCropChange,\n onCropSizeChange,\n onCropAreaChange,\n onCropComplete,\n onZoomChange,\n onRotationChange,\n onMediaLoaded,\n onInteractionStart,\n onInteractionEnd,\n ],\n );\n\n useIsomorphicLayoutEffect(() => {\n const updates: Partial<StoreState> = {};\n let hasUpdates = false;\n let shouldRecompute = false;\n\n if (crop !== undefined) {\n const currentState = store.getState();\n if (!Object.is(currentState.crop, crop)) {\n updates.crop = crop;\n hasUpdates = true;\n }\n }\n\n if (zoom !== undefined) {\n const currentState = store.getState();\n if (currentState.zoom !== zoom) {\n updates.zoom = zoom;\n hasUpdates = true;\n shouldRecompute = true;\n }\n }\n\n if (rotation !== undefined) {\n const currentState = store.getState();\n if (currentState.rotation !== rotation) {\n updates.rotation = rotation;\n hasUpdates = true;\n shouldRecompute = true;\n }\n }\n\n if (hasUpdates) {\n store.batch(() => {\n Object.entries(updates).forEach(([key, value]) => {\n store.setState(key as keyof StoreState, value);\n });\n });\n\n if (shouldRecompute && rootRef.current) {\n requestAnimationFrame(() => {\n const currentState = store.getState();\n if (currentState.cropSize && currentState.mediaSize) {\n const newPosition = !allowOverflow\n ? onPositionClamp(\n currentState.crop,\n currentState.mediaSize,\n currentState.cropSize,\n currentState.zoom,\n currentState.rotation,\n )\n : currentState.crop;\n\n if (\n Math.abs(newPosition.x - currentState.crop.x) > 0.001 ||\n Math.abs(newPosition.y - currentState.crop.y) > 0.001\n ) {\n store.setState(\"crop\", newPosition);\n }\n }\n });\n }\n }\n }, [crop, zoom, rotation, store, allowOverflow]);\n\n const contextValue = React.useMemo<CropperContextValue>(\n () => ({\n minZoom,\n maxZoom,\n zoomSpeed,\n keyboardStep,\n aspectRatio,\n shape,\n objectFit,\n preventScrollZoom,\n allowOverflow,\n withGrid,\n rootRef,\n }),\n [\n minZoom,\n maxZoom,\n zoomSpeed,\n keyboardStep,\n aspectRatio,\n shape,\n objectFit,\n preventScrollZoom,\n allowOverflow,\n withGrid,\n ],\n );\n\n return (\n <StoreContext.Provider value={store}>\n <CropperContext.Provider value={contextValue}>\n <div\n data-slot=\"cropper-wrapper\"\n className={cn(\"relative size-full overflow-hidden\", className)}\n >\n <CropperRootImpl {...rootProps} />\n </div>\n </CropperContext.Provider>\n </StoreContext.Provider>\n );\n}\n\ninterface CropperRootImplProps extends CropperRootProps {\n onWheelZoom?: (event: WheelEvent) => void;\n}\n\nfunction CropperRootImpl(props: CropperRootImplProps) {\n const { className, asChild, ref, ...contentProps } = props;\n\n const context = useCropperContext(CONTENT_NAME);\n const store = useStoreContext(CONTENT_NAME);\n const crop = useStore((state) => state.crop);\n const zoom = useStore((state) => state.zoom);\n const rotation = useStore((state) => state.rotation);\n const mediaSize = useStore((state) => state.mediaSize);\n const cropSize = useStore((state) => state.cropSize);\n\n const composedRef = useComposedRefs(ref, context.rootRef);\n const dragStartPositionRef = React.useRef<Point>({ x: 0, y: 0 });\n const dragStartCropRef = React.useRef<Point>({ x: 0, y: 0 });\n const contentPositionRef = React.useRef<Point>({ x: 0, y: 0 });\n const lastPinchDistanceRef = React.useRef(0);\n const lastPinchRotationRef = React.useRef(0);\n const rafDragTimeoutRef = React.useRef<number | null>(null);\n const rafPinchTimeoutRef = React.useRef<number | null>(null);\n const wheelTimerRef = React.useRef<number | null>(null);\n const isTouchingRef = React.useRef(false);\n const gestureZoomStartRef = React.useRef(0);\n const gestureRotationStartRef = React.useRef(0);\n\n const onRefsCleanup = React.useCallback(() => {\n if (rafDragTimeoutRef.current) {\n cancelAnimationFrame(rafDragTimeoutRef.current);\n rafDragTimeoutRef.current = null;\n }\n if (rafPinchTimeoutRef.current) {\n cancelAnimationFrame(rafPinchTimeoutRef.current);\n rafPinchTimeoutRef.current = null;\n }\n if (wheelTimerRef.current) {\n clearTimeout(wheelTimerRef.current);\n wheelTimerRef.current = null;\n }\n isTouchingRef.current = false;\n }, []);\n\n const onCachesCleanup = React.useCallback(() => {\n if (onPositionClampCache.size > MAX_CACHE_SIZE * 1.5) {\n onPositionClampCache.clear();\n }\n if (croppedAreaCache.size > MAX_CACHE_SIZE * 1.5) {\n croppedAreaCache.clear();\n }\n }, []);\n\n const getMousePoint = React.useCallback(\n (event: MouseEvent | React.MouseEvent) => ({\n x: Number(event.clientX),\n y: Number(event.clientY),\n }),\n [],\n );\n\n const getTouchPoint = React.useCallback(\n (touch: Touch | React.Touch) => ({\n x: Number(touch.clientX),\n y: Number(touch.clientY),\n }),\n [],\n );\n\n const onContentPositionChange = React.useCallback(() => {\n if (context.rootRef?.current) {\n const bounds = context.rootRef.current.getBoundingClientRect();\n contentPositionRef.current = { x: bounds.left, y: bounds.top };\n }\n }, [context.rootRef]);\n\n const getPointOnContent = React.useCallback(\n ({ x, y }: Point, contentTopLeft: Point): Point => {\n if (!context.rootRef?.current) {\n return { x: 0, y: 0 };\n }\n const contentRect = context.rootRef.current.getBoundingClientRect();\n return {\n x: contentRect.width / 2 - (x - contentTopLeft.x),\n y: contentRect.height / 2 - (y - contentTopLeft.y),\n };\n },\n [context.rootRef],\n );\n\n const getPointOnMedia = React.useCallback(\n ({ x, y }: Point) => {\n return {\n x: (x + crop.x) / zoom,\n y: (y + crop.y) / zoom,\n };\n },\n [crop, zoom],\n );\n\n const recomputeCropPosition = React.useCallback(() => {\n if (!cropSize || !mediaSize) return;\n\n const newPosition = !context.allowOverflow\n ? onPositionClamp(crop, mediaSize, cropSize, zoom, rotation)\n : crop;\n\n if (\n Math.abs(newPosition.x - crop.x) > 0.001 ||\n Math.abs(newPosition.y - crop.y) > 0.001\n ) {\n store.setState(\"crop\", newPosition);\n }\n }, [cropSize, mediaSize, context.allowOverflow, crop, zoom, rotation, store]);\n\n const onZoomChange = React.useCallback(\n (newZoom: number, point: Point, shouldUpdatePosition = true) => {\n if (!cropSize || !mediaSize) return;\n\n const clampedZoom = clamp(newZoom, context.minZoom, context.maxZoom);\n\n store.batch(() => {\n if (shouldUpdatePosition) {\n const zoomPoint = getPointOnContent(\n point,\n contentPositionRef.current,\n );\n const zoomTarget = getPointOnMedia(zoomPoint);\n const requestedPosition = {\n x: zoomTarget.x * clampedZoom - zoomPoint.x,\n y: zoomTarget.y * clampedZoom - zoomPoint.y,\n };\n\n const newPosition = !context.allowOverflow\n ? onPositionClamp(\n requestedPosition,\n mediaSize,\n cropSize,\n clampedZoom,\n rotation,\n )\n : requestedPosition;\n\n store.setState(\"crop\", newPosition);\n }\n store.setState(\"zoom\", clampedZoom);\n });\n\n requestAnimationFrame(() => {\n recomputeCropPosition();\n });\n },\n [\n cropSize,\n mediaSize,\n context.minZoom,\n context.maxZoom,\n context.allowOverflow,\n getPointOnContent,\n getPointOnMedia,\n rotation,\n store,\n recomputeCropPosition,\n ],\n );\n\n const onDragStart = React.useCallback(\n ({ x, y }: Point) => {\n dragStartPositionRef.current = { x, y };\n dragStartCropRef.current = { ...crop };\n store.setState(\"isDragging\", true);\n },\n [crop, store],\n );\n\n const onDrag = React.useCallback(\n ({ x, y }: Point) => {\n if (rafDragTimeoutRef.current) {\n cancelAnimationFrame(rafDragTimeoutRef.current);\n }\n\n rafDragTimeoutRef.current = requestAnimationFrame(() => {\n if (!cropSize || !mediaSize) return;\n if (x === undefined || y === undefined) return;\n\n const offsetX = x - dragStartPositionRef.current.x;\n const offsetY = y - dragStartPositionRef.current.y;\n\n if (Math.abs(offsetX) < 2 && Math.abs(offsetY) < 2) {\n return;\n }\n\n const requestedPosition = {\n x: dragStartCropRef.current.x + offsetX,\n y: dragStartCropRef.current.y + offsetY,\n };\n\n const newPosition = !context.allowOverflow\n ? onPositionClamp(\n requestedPosition,\n mediaSize,\n cropSize,\n zoom,\n rotation,\n )\n : requestedPosition;\n\n const currentCrop = store.getState().crop;\n if (\n Math.abs(newPosition.x - currentCrop.x) > 1 ||\n Math.abs(newPosition.y - currentCrop.y) > 1\n ) {\n store.setState(\"crop\", newPosition);\n }\n });\n },\n [cropSize, mediaSize, context.allowOverflow, zoom, rotation, store],\n );\n\n const onMouseMove = React.useCallback(\n (event: MouseEvent) => onDrag(getMousePoint(event)),\n [getMousePoint, onDrag],\n );\n\n const onTouchMove = React.useCallback(\n (event: TouchEvent) => {\n event.preventDefault();\n if (event.touches.length === 2) {\n const [firstTouch, secondTouch] = event.touches ?? [];\n if (firstTouch && secondTouch) {\n const pointA = getTouchPoint(firstTouch);\n const pointB = getTouchPoint(secondTouch);\n const center = getCenter(pointA, pointB);\n onDrag(center);\n\n if (rafPinchTimeoutRef.current) {\n cancelAnimationFrame(rafPinchTimeoutRef.current);\n }\n\n rafPinchTimeoutRef.current = requestAnimationFrame(() => {\n const distance = getDistanceBetweenPoints(pointA, pointB);\n const distanceRatio = distance / lastPinchDistanceRef.current;\n\n if (Math.abs(distanceRatio - 1) > 0.01) {\n const newZoom = zoom * distanceRatio;\n onZoomChange(newZoom, center, false);\n lastPinchDistanceRef.current = distance;\n }\n\n const rotationAngle = getRotationBetweenPoints(pointA, pointB);\n const rotationDiff = rotationAngle - lastPinchRotationRef.current;\n\n if (Math.abs(rotationDiff) > 0.5) {\n const newRotation = rotation + rotationDiff;\n store.setState(\"rotation\", newRotation);\n lastPinchRotationRef.current = rotationAngle;\n }\n });\n }\n } else if (event.touches.length === 1) {\n const firstTouch = event.touches[0];\n if (firstTouch) {\n onDrag(getTouchPoint(firstTouch));\n }\n }\n },\n [getTouchPoint, onDrag, zoom, onZoomChange, rotation, store],\n );\n\n const onGestureChange = React.useCallback(\n (event: GestureEvent) => {\n event.preventDefault();\n if (isTouchingRef.current) {\n return;\n }\n\n const point = { x: Number(event.clientX), y: Number(event.clientY) };\n const newZoom = gestureZoomStartRef.current - 1 + event.scale;\n onZoomChange(newZoom, point, true);\n\n const newRotation = gestureRotationStartRef.current + event.rotation;\n store.setState(\"rotation\", newRotation);\n },\n [onZoomChange, store],\n );\n\n const onGestureEnd = React.useCallback(() => {\n document.removeEventListener(\n \"gesturechange\",\n onGestureChange as EventListener,\n );\n document.removeEventListener(\"gestureend\", onGestureEnd as EventListener);\n }, [onGestureChange]);\n\n const onGestureStart = React.useCallback(\n (event: GestureEvent) => {\n event.preventDefault();\n document.addEventListener(\n \"gesturechange\",\n onGestureChange as EventListener,\n );\n document.addEventListener(\"gestureend\", onGestureEnd as EventListener);\n gestureZoomStartRef.current = zoom;\n gestureRotationStartRef.current = rotation;\n },\n [zoom, rotation, onGestureChange, onGestureEnd],\n );\n\n const onSafariZoomPrevent = React.useCallback(\n (event: Event) => event.preventDefault(),\n [],\n );\n\n const onEventsCleanup = React.useCallback(() => {\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"touchmove\", onTouchMove);\n document.removeEventListener(\n \"gesturechange\",\n onGestureChange as EventListener,\n );\n document.removeEventListener(\"gestureend\", onGestureEnd as EventListener);\n }, [onMouseMove, onTouchMove, onGestureChange, onGestureEnd]);\n\n const onDragStopped = React.useCallback(() => {\n isTouchingRef.current = false;\n store.setState(\"isDragging\", false);\n onRefsCleanup();\n document.removeEventListener(\"mouseup\", onDragStopped);\n document.removeEventListener(\"touchend\", onDragStopped);\n onEventsCleanup();\n }, [store, onEventsCleanup, onRefsCleanup]);\n\n const getWheelDelta = React.useCallback((event: WheelEvent) => {\n let deltaX = event.deltaX;\n let deltaY = event.deltaY;\n let deltaZ = event.deltaZ;\n\n if (event.deltaMode === 1) {\n deltaX *= 16;\n deltaY *= 16;\n deltaZ *= 16;\n } else if (event.deltaMode === 2) {\n deltaX *= 400;\n deltaY *= 400;\n deltaZ *= 400;\n }\n\n return { deltaX, deltaY, deltaZ };\n }, []);\n\n const onWheelZoom = React.useCallback(\n (event: WheelEvent) => {\n contentProps.onWheelZoom?.(event);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n const point = getMousePoint(event);\n const { deltaY } = getWheelDelta(event);\n const newZoom = zoom - (deltaY * context.zoomSpeed) / 200;\n onZoomChange(newZoom, point, true);\n\n store.batch(() => {\n const currentState = store.getState();\n if (!currentState.isWheelZooming) {\n store.setState(\"isWheelZooming\", true);\n }\n if (!currentState.isDragging) {\n store.setState(\"isDragging\", true);\n }\n });\n\n if (wheelTimerRef.current) {\n clearTimeout(wheelTimerRef.current);\n }\n wheelTimerRef.current = window.setTimeout(() => {\n store.batch(() => {\n store.setState(\"isWheelZooming\", false);\n store.setState(\"isDragging\", false);\n });\n }, 250);\n },\n [\n contentProps.onWheelZoom,\n getMousePoint,\n zoom,\n context.zoomSpeed,\n onZoomChange,\n getWheelDelta,\n store,\n ],\n );\n\n const onKeyUp = React.useCallback(\n (event: React.KeyboardEvent<RootElement>) => {\n contentProps.onKeyUp?.(event);\n if (event.defaultPrevented) return;\n\n const arrowKeys = new Set([\n \"ArrowUp\",\n \"ArrowDown\",\n \"ArrowLeft\",\n \"ArrowRight\",\n ]);\n\n if (arrowKeys.has(event.key)) {\n event.preventDefault();\n store.setState(\"isDragging\", false);\n }\n },\n [contentProps.onKeyUp, store],\n );\n\n const onKeyDown = React.useCallback(\n (event: React.KeyboardEvent<RootElement>) => {\n contentProps.onKeyDown?.(event);\n if (event.defaultPrevented || !cropSize || !mediaSize) return;\n\n let step = context.keyboardStep;\n if (event.shiftKey) {\n step *= 0.2;\n }\n\n const keyCallbacks: Record<string, () => Point> = {\n ArrowUp: () => ({ ...crop, y: crop.y - step }),\n ArrowDown: () => ({ ...crop, y: crop.y + step }),\n ArrowLeft: () => ({ ...crop, x: crop.x - step }),\n ArrowRight: () => ({ ...crop, x: crop.x + step }),\n } as const;\n\n const callback = keyCallbacks[event.key];\n if (!callback) return;\n\n event.preventDefault();\n\n let newCrop = callback();\n\n if (!context.allowOverflow) {\n newCrop = onPositionClamp(newCrop, mediaSize, cropSize, zoom, rotation);\n }\n\n if (!event.repeat) {\n store.setState(\"isDragging\", true);\n }\n\n store.setState(\"crop\", newCrop);\n },\n [\n contentProps.onKeyDown,\n cropSize,\n mediaSize,\n context.keyboardStep,\n context.allowOverflow,\n crop,\n zoom,\n rotation,\n store,\n ],\n );\n\n const onMouseDown = React.useCallback(\n (event: React.MouseEvent<RootElement>) => {\n contentProps.onMouseDown?.(event);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onDragStopped);\n onContentPositionChange();\n onDragStart(getMousePoint(event));\n },\n [\n contentProps.onMouseDown,\n getMousePoint,\n onDragStart,\n onDragStopped,\n onMouseMove,\n onContentPositionChange,\n ],\n );\n\n const onTouchStart = React.useCallback(\n (event: React.TouchEvent<RootElement>) => {\n contentProps.onTouchStart?.(event);\n if (event.defaultPrevented) return;\n\n isTouchingRef.current = true;\n document.addEventListener(\"touchmove\", onTouchMove, { passive: false });\n document.addEventListener(\"touchend\", onDragStopped);\n onContentPositionChange();\n\n if (event.touches.length === 2) {\n const [firstTouch, secondTouch] = event.touches\n ? Array.from(event.touches)\n : [];\n if (firstTouch && secondTouch) {\n const pointA = getTouchPoint(firstTouch);\n const pointB = getTouchPoint(secondTouch);\n lastPinchDistanceRef.current = getDistanceBetweenPoints(\n pointA,\n pointB,\n );\n lastPinchRotationRef.current = getRotationBetweenPoints(\n pointA,\n pointB,\n );\n onDragStart(getCenter(pointA, pointB));\n }\n } else if (event.touches.length === 1) {\n const firstTouch = event.touches[0];\n if (firstTouch) {\n onDragStart(getTouchPoint(firstTouch));\n }\n }\n },\n [\n contentProps.onTouchStart,\n onDragStopped,\n onTouchMove,\n onContentPositionChange,\n getTouchPoint,\n onDragStart,\n ],\n );\n\n React.useEffect(() => {\n const content = context.rootRef?.current;\n if (!content) return;\n\n if (!context.preventScrollZoom) {\n content.addEventListener(\"wheel\", onWheelZoom, { passive: false });\n }\n\n content.addEventListener(\"gesturestart\", onSafariZoomPrevent);\n content.addEventListener(\"gesturestart\", onGestureStart as EventListener);\n\n return () => {\n if (!context.preventScrollZoom) {\n content.removeEventListener(\"wheel\", onWheelZoom);\n }\n content.removeEventListener(\"gesturestart\", onSafariZoomPrevent);\n content.removeEventListener(\n \"gesturestart\",\n onGestureStart as EventListener,\n );\n onRefsCleanup();\n };\n }, [\n context.rootRef,\n context.preventScrollZoom,\n onWheelZoom,\n onRefsCleanup,\n onSafariZoomPrevent,\n onGestureStart,\n ]);\n\n React.useEffect(() => {\n return () => {\n onRefsCleanup();\n onCachesCleanup();\n };\n }, [onRefsCleanup, onCachesCleanup]);\n\n const RootPrimitive = asChild ? Slot : \"div\";\n\n return (\n <RootPrimitive\n data-slot=\"cropper\"\n tabIndex={0}\n {...contentProps}\n ref={composedRef}\n className={cn(\n \"absolute inset-0 flex cursor-move touch-none select-none items-center justify-center overflow-hidden outline-none\",\n className,\n )}\n onKeyUp={onKeyUp}\n onKeyDown={onKeyDown}\n onMouseDown={onMouseDown}\n onTouchStart={onTouchStart}\n />\n );\n}\n\nconst cropperMediaVariants = cva(\"will-change-transform\", {\n variants: {\n objectFit: {\n contain: \"absolute inset-0 m-auto max-h-full max-w-full\",\n cover: \"h-auto w-full\",\n \"horizontal-cover\": \"h-auto w-full\",\n \"vertical-cover\": \"h-full w-auto\",\n },\n },\n defaultVariants: {\n objectFit: \"contain\",\n },\n});\n\ninterface UseMediaComputationProps<\n T extends HTMLImageElement | HTMLVideoElement,\n> {\n mediaRef: React.RefObject<T | null>;\n context: CropperContextValue;\n store: Store;\n rotation: number;\n getNaturalDimensions: (media: T) => Size;\n}\n\nfunction useMediaComputation<T extends HTMLImageElement | HTMLVideoElement>({\n mediaRef,\n context,\n store,\n rotation,\n getNaturalDimensions,\n}: UseMediaComputationProps<T>) {\n const computeSizes = React.useCallback(() => {\n const media = mediaRef.current;\n const content = context.rootRef?.current;\n if (!media || !content) return;\n\n const contentRect = content.getBoundingClientRect();\n const containerAspect = contentRect.width / contentRect.height;\n const { width: naturalWidth, height: naturalHeight } =\n getNaturalDimensions(media);\n const isScaledDown =\n media.offsetWidth < naturalWidth || media.offsetHeight < naturalHeight;\n const mediaAspect = naturalWidth / naturalHeight;\n\n let renderedMediaSize: Size;\n\n if (isScaledDown) {\n const objectFitCallbacks = {\n contain: () =>\n containerAspect > mediaAspect\n ? {\n width: contentRect.height * mediaAspect,\n height: contentRect.height,\n }\n : {\n width: contentRect.width,\n height: contentRect.width / mediaAspect,\n },\n \"horizontal-cover\": () => ({\n width: contentRect.width,\n height: contentRect.width / mediaAspect,\n }),\n \"vertical-cover\": () => ({\n width: contentRect.height * mediaAspect,\n height: contentRect.height,\n }),\n cover: () =>\n containerAspect < mediaAspect\n ? {\n width: contentRect.width,\n height: contentRect.width / mediaAspect,\n }\n : {\n width: contentRect.height * mediaAspect,\n height: contentRect.height,\n },\n } as const;\n\n const callback = objectFitCallbacks[context.objectFit];\n renderedMediaSize = callback\n ? callback()\n : containerAspect > mediaAspect\n ? {\n width: contentRect.height * mediaAspect,\n height: contentRect.height,\n }\n : {\n width: contentRect.width,\n height: contentRect.width / mediaAspect,\n };\n } else {\n renderedMediaSize = {\n width: media.offsetWidth,\n height: media.offsetHeight,\n };\n }\n\n const mediaSize: MediaSize = {\n ...renderedMediaSize,\n naturalWidth,\n naturalHeight,\n };\n\n store.setState(\"mediaSize\", mediaSize);\n\n const cropSize = getCropSize(\n mediaSize.width,\n mediaSize.height,\n contentRect.width,\n contentRect.height,\n context.aspectRatio,\n rotation,\n );\n\n store.setState(\"cropSize\", cropSize);\n\n requestAnimationFrame(() => {\n const currentState = store.getState();\n if (currentState.cropSize && currentState.mediaSize) {\n const newPosition = onPositionClamp(\n currentState.crop,\n currentState.mediaSize,\n currentState.cropSize,\n currentState.zoom,\n currentState.rotation,\n );\n\n if (\n Math.abs(newPosition.x - currentState.crop.x) > 0.001 ||\n Math.abs(newPosition.y - currentState.crop.y) > 0.001\n ) {\n store.setState(\"crop\", newPosition);\n }\n }\n });\n\n return { mediaSize, cropSize };\n }, [\n mediaRef,\n context.aspectRatio,\n context.rootRef,\n context.objectFit,\n store,\n rotation,\n getNaturalDimensions,\n ]);\n\n return { computeSizes };\n}\n\ninterface CropperImageProps\n extends\n React.ComponentProps<\"img\">,\n VariantProps<typeof cropperMediaVariants> {\n asChild?: boolean;\n snapPixels?: boolean;\n}\n\nfunction CropperImage(props: CropperImageProps) {\n const {\n className,\n style,\n asChild,\n ref,\n onLoad,\n objectFit,\n snapPixels = false,\n ...imageProps\n } = props;\n\n const context = useCropperContext(IMAGE_NAME);\n const store = useStoreContext(IMAGE_NAME);\n const crop = useStore((state) => state.crop);\n const zoom = useStore((state) => state.zoom);\n const rotation = useStore((state) => state.rotation);\n\n const imageRef = React.useRef<HTMLImageElement>(null);\n const composedRef = useComposedRefs(ref, imageRef);\n\n const getNaturalDimensions = React.useCallback(\n (image: HTMLImageElement) => ({\n width: image.naturalWidth,\n height: image.naturalHeight,\n }),\n [],\n );\n\n const { computeSizes } = useMediaComputation({\n mediaRef: imageRef,\n context,\n store,\n rotation,\n getNaturalDimensions,\n });\n\n const onMediaLoad = React.useCallback(() => {\n const image = imageRef.current;\n if (!image) return;\n\n computeSizes();\n\n onLoad?.(\n new Event(\"load\") as unknown as React.SyntheticEvent<HTMLImageElement>,\n );\n }, [computeSizes, onLoad]);\n\n React.useEffect(() => {\n const image = imageRef.current;\n if (image?.complete && image.naturalWidth > 0) {\n onMediaLoad();\n }\n }, [onMediaLoad]);\n\n React.useEffect(() => {\n const content = context.rootRef?.current;\n if (!content) return;\n\n if (typeof ResizeObserver !== \"undefined\") {\n let isFirstResize = true;\n const resizeObserver = new ResizeObserver(() => {\n if (isFirstResize) {\n isFirstResize = false;\n return;\n }\n\n const callback = () => {\n const image = imageRef.current;\n if (image?.complete && image.naturalWidth > 0) {\n computeSizes();\n }\n };\n\n if (\"requestIdleCallback\" in window) {\n requestIdleCallback(callback);\n } else {\n setTimeout(callback, 16);\n }\n });\n\n resizeObserver.observe(content);\n\n return () => {\n resizeObserver.disconnect();\n };\n } else {\n const onWindowResize = () => {\n const image = imageRef.current;\n if (image?.complete && image.naturalWidth > 0) {\n computeSizes();\n }\n };\n\n window.addEventListener(\"resize\", onWindowResize);\n return () => {\n window.removeEventListener(\"resize\", onWindowResize);\n };\n }\n }, [context.rootRef, computeSizes]);\n\n const ImagePrimitive = asChild ? Slot : \"img\";\n\n return (\n <ImagePrimitive\n data-slot=\"cropper-image\"\n {...imageProps}\n ref={composedRef}\n className={cn(\n cropperMediaVariants({\n objectFit: objectFit ?? context.objectFit,\n className,\n }),\n )}\n style={{\n transform: snapPixels\n ? `translate(${snapToDevicePixel(crop.x)}px, ${snapToDevicePixel(crop.y)}px) rotate(${rotation}deg) scale(${zoom})`\n : `translate(${crop.x}px, ${crop.y}px) rotate(${rotation}deg) scale(${zoom})`,\n ...style,\n }}\n onLoad={onMediaLoad}\n />\n );\n}\n\ninterface CropperVideoProps\n extends\n React.ComponentProps<\"video\">,\n VariantProps<typeof cropperMediaVariants> {\n asChild?: boolean;\n snapPixels?: boolean;\n}\n\nfunction CropperVideo(props: CropperVideoProps) {\n const {\n className,\n style,\n asChild,\n ref,\n onLoadedMetadata,\n objectFit,\n snapPixels = false,\n ...videoProps\n } = props;\n\n const context = useCropperContext(VIDEO_NAME);\n const store = useStoreContext(VIDEO_NAME);\n const crop = useStore((state) => state.crop);\n const zoom = useStore((state) => state.zoom);\n const rotation = useStore((state) => state.rotation);\n\n const videoRef = React.useRef<HTMLVideoElement>(null);\n const composedRef = useComposedRefs(ref, videoRef);\n\n const getNaturalDimensions = React.useCallback(\n (video: HTMLVideoElement) => ({\n width: video.videoWidth,\n height: video.videoHeight,\n }),\n [],\n );\n\n const { computeSizes } = useMediaComputation({\n mediaRef: videoRef,\n context,\n store,\n rotation,\n getNaturalDimensions,\n });\n\n const onMediaLoad = React.useCallback(() => {\n const video = videoRef.current;\n if (!video) return;\n\n computeSizes();\n\n onLoadedMetadata?.(\n new Event(\n \"loadedmetadata\",\n ) as unknown as React.SyntheticEvent<HTMLVideoElement>,\n );\n }, [computeSizes, onLoadedMetadata]);\n\n React.useEffect(() => {\n const content = context.rootRef?.current;\n if (!content) return;\n\n if (typeof ResizeObserver !== \"undefined\") {\n let isFirstResize = true;\n const resizeObserver = new ResizeObserver(() => {\n if (isFirstResize) {\n isFirstResize = false;\n return;\n }\n\n const callback = () => {\n const video = videoRef.current;\n if (video && video.videoWidth > 0 && video.videoHeight > 0) {\n computeSizes();\n }\n };\n\n if (\"requestIdleCallback\" in window) {\n requestIdleCallback(callback);\n } else {\n setTimeout(callback, 16);\n }\n });\n\n resizeObserver.observe(content);\n\n return () => {\n resizeObserver.disconnect();\n };\n } else {\n const onWindowResize = () => {\n const video = videoRef.current;\n if (video && video.videoWidth > 0 && video.videoHeight > 0) {\n computeSizes();\n }\n };\n\n window.addEventListener(\"resize\", onWindowResize);\n return () => {\n window.removeEventListener(\"resize\", onWindowResize);\n };\n }\n }, [context.rootRef, computeSizes]);\n\n const VideoPrimitive = asChild ? Slot : \"video\";\n\n return (\n <VideoPrimitive\n data-slot=\"cropper-video\"\n autoPlay\n playsInline\n loop\n muted\n controls={false}\n {...videoProps}\n ref={composedRef}\n className={cn(\n cropperMediaVariants({\n objectFit: objectFit ?? context.objectFit,\n className,\n }),\n )}\n style={{\n transform: snapPixels\n ? `translate(${snapToDevicePixel(crop.x)}px, ${snapToDevicePixel(crop.y)}px) rotate(${rotation}deg) scale(${zoom})`\n : `translate(${crop.x}px, ${crop.y}px) rotate(${rotation}deg) scale(${zoom})`,\n ...style,\n }}\n onLoadedMetadata={onMediaLoad}\n />\n );\n}\n\nconst cropperAreaVariants = cva(\n \"-translate-x-1/2 -translate-y-1/2 absolute top-1/2 left-1/2 box-border overflow-hidden border border-[2.5px] border-white/90 shadow-[0_0_0_9999em_rgba(0,0,0,0.5)]\",\n {\n variants: {\n shape: {\n rectangle: \"\",\n circle: \"rounded-full\",\n },\n withGrid: {\n true: \"before:absolute before:top-0 before:right-1/3 before:bottom-0 before:left-1/3 before:box-border before:border before:border-white/50 before:border-t-0 before:border-b-0 before:content-[''] after:absolute after:top-1/3 after:right-0 after:bottom-1/3 after:left-0 after:box-border after:border after:border-white/50 after:border-r-0 after:border-l-0 after:content-['']\",\n false: \"\",\n },\n },\n defaultVariants: {\n shape: \"rectangle\",\n withGrid: false,\n },\n },\n);\n\ninterface CropperAreaProps\n extends DivProps, VariantProps<typeof cropperAreaVariants> {\n snapPixels?: boolean;\n}\n\nfunction CropperArea(props: CropperAreaProps) {\n const {\n className,\n style,\n asChild,\n ref,\n snapPixels = false,\n shape,\n withGrid,\n ...areaProps\n } = props;\n\n const context = useCropperContext(AREA_NAME);\n const cropSize = useStore((state) => state.cropSize);\n\n if (!cropSize) return null;\n\n const AreaPrimitive = asChild ? Slot : \"div\";\n\n return (\n <AreaPrimitive\n data-slot=\"cropper-area\"\n {...areaProps}\n ref={ref}\n className={cn(\n cropperAreaVariants({\n shape: shape ?? context.shape,\n withGrid: withGrid ?? context.withGrid,\n className,\n }),\n )}\n style={{\n width: snapPixels ? Math.round(cropSize.width) : cropSize.width,\n height: snapPixels ? Math.round(cropSize.height) : cropSize.height,\n ...style,\n }}\n />\n );\n}\n\nexport {\n CropperRoot as Root,\n CropperImage as Image,\n CropperVideo as Video,\n CropperArea as Area,\n //\n CropperRoot as Cropper,\n CropperImage,\n CropperVideo,\n CropperArea,\n //\n useStore as useCropper,\n //\n type CropperRootProps as CropperProps,\n type Point as CropperPoint,\n type Size as CropperSize,\n type Area as CropperAreaData,\n type Shape as CropperShape,\n type ObjectFit as CropperObjectFit,\n};\n"],"names":["ROOT_NAME","CONTENT_NAME","IMAGE_NAME","VIDEO_NAME","AREA_NAME","MAX_CACHE_SIZE","DPR","rotationSizeCache","cropSizeCache","croppedAreaCache","onPositionClampCache","clamp","value","min","max","quantize","n","step","quantizePosition","quantizeZoom","quantizeRotation","snapToDevicePixel","lruGet","map","key","v","lruSet","val","firstKey","getDistanceBetweenPoints","pointA","pointB","getCenter","a","b","getRotationBetweenPoints","getRadianAngle","degreeValue","rotateSize","width","height","rotation","cacheKey","cached","rotRad","cosRot","sinRot","result","getCropSize","mediaWidth","mediaHeight","contentWidth","contentHeight","aspect","fittingWidth","fittingHeight","onPositionClamp","position","mediaSize","cropSize","zoom","quantizedX","quantizedY","maxPositionX","maxPositionY","getCroppedArea","crop","allowOverflow","onAreaLimit","_max","mediaBBoxSize","mediaNaturalBBoxSize","croppedAreaPercentages","widthInPixels","heightInPixels","sizePixels","croppedAreaPixels","useLazyRef","fn","ref","React","useIsomorphicLayoutEffect","createStore","listenersRef","stateRef","aspectRatio","onCropChange","onCropSizeChange","onCropAreaChange","onCropComplete","onZoomChange","onRotationChange","onMediaLoaded","onInteractionStart","onInteractionEnd","isBatching","raf","notifyCropAreaChange","s","store","cb","state","currentState","StoreContext","useStoreContext","consumerName","context","useStore","selector","getSnapshot","CropperContext","useCropperContext","CropperRoot","props","minZoom","maxZoom","zoomSpeed","keyboardStep","shape","objectFit","preventScrollZoom","withGrid","className","rootProps","rootRef","updates","hasUpdates","shouldRecompute","newPosition","contextValue","jsx","cn","CropperRootImpl","asChild","contentProps","composedRef","useComposedRefs","dragStartPositionRef","dragStartCropRef","contentPositionRef","lastPinchDistanceRef","lastPinchRotationRef","rafDragTimeoutRef","rafPinchTimeoutRef","wheelTimerRef","isTouchingRef","gestureZoomStartRef","gestureRotationStartRef","onRefsCleanup","onCachesCleanup","getMousePoint","event","getTouchPoint","touch","onContentPositionChange","bounds","getPointOnContent","x","y","contentTopLeft","contentRect","getPointOnMedia","recomputeCropPosition","newZoom","point","shouldUpdatePosition","clampedZoom","zoomPoint","zoomTarget","requestedPosition","onDragStart","onDrag","offsetX","offsetY","currentCrop","onMouseMove","onTouchMove","firstTouch","secondTouch","center","distance","distanceRatio","rotationAngle","rotationDiff","newRotation","onGestureChange","onGestureEnd","onGestureStart","onSafariZoomPrevent","onEventsCleanup","onDragStopped","getWheelDelta","deltaX","deltaY","deltaZ","onWheelZoom","onKeyUp","onKeyDown","callback","newCrop","onMouseDown","onTouchStart","content","RootPrimitive","Slot","cropperMediaVariants","cva","useMediaComputation","mediaRef","getNaturalDimensions","media","containerAspect","naturalWidth","naturalHeight","isScaledDown","mediaAspect","renderedMediaSize","CropperImage","style","onLoad","snapPixels","imageProps","imageRef","image","computeSizes","onMediaLoad","isFirstResize","resizeObserver","onWindowResize","ImagePrimitive","CropperVideo","onLoadedMetadata","videoProps","videoRef","video","VideoPrimitive","cropperAreaVariants","CropperArea","areaProps","AreaPrimitive"],"mappings":"yeAMMA,GAAY,UACZC,GAAe,iBACfC,GAAa,eACbC,GAAa,eACbC,GAAY,cAwCZC,EAAiB,IACjBC,GAAM,OAAO,OAAW,KAAc,OAAO,kBAAoB,EAEjEC,OAAwB,IACxBC,OAAoB,IACpBC,OAAuB,IAIvBC,OAA2B,IAEjC,SAASC,GAAMC,EAAeC,EAAaC,EAAqB,CAC9D,OAAO,KAAK,IAAI,KAAK,IAAIF,EAAOC,CAAG,EAAGC,CAAG,CAC3C,CAEA,SAASC,EAASC,EAAWC,EAAO,EAAIX,GAAa,CACnD,OAAO,KAAK,MAAMU,EAAIC,CAAI,EAAIA,CAChC,CAEA,SAASC,GAAiBF,EAAWC,EAAO,EAAIX,GAAa,CAC3D,OAAO,KAAK,MAAMU,EAAIC,CAAI,EAAIA,CAChC,CAEA,SAASE,GAAaH,EAAWC,EAAO,IAAc,CACpD,OAAO,KAAK,MAAMD,EAAIC,CAAI,EAAIA,CAChC,CAEA,SAASG,GAAiBJ,EAAWC,EAAO,EAAa,CACvD,OAAO,KAAK,MAAMD,EAAIC,CAAI,EAAIA,CAChC,CAEA,SAASI,GAAkBL,EAAmB,CAC5C,OAAO,KAAK,MAAMA,EAAIV,EAAG,EAAIA,EAC/B,CAEA,SAASgB,GAAaC,EAAgBC,EAAuB,CAC3D,MAAMC,EAAIF,EAAI,IAAIC,CAAG,EACrB,OAAIC,IAAM,SACRF,EAAI,OAAOC,CAAG,EACdD,EAAI,IAAIC,EAAKC,CAAC,GAETA,CACT,CAEA,SAASC,GACPH,EACAC,EACAG,EACAb,EAAMT,EACA,CAKN,GAJIkB,EAAI,IAAIC,CAAG,GACbD,EAAI,OAAOC,CAAG,EAEhBD,EAAI,IAAIC,EAAKG,CAAG,EACZJ,EAAI,KAAOT,EAAK,CAClB,MAAMc,EAAWL,EAAI,KAAA,EAAO,OAAO,MAC/BK,IAAa,QACfL,EAAI,OAAOK,CAAQ,CAEvB,CACF,CAEA,SAASC,GAAyBC,EAAeC,EAAuB,CACtE,OAAO,KAAK,MAAMD,EAAO,EAAIC,EAAO,IAAM,GAAKD,EAAO,EAAIC,EAAO,IAAM,CAAC,CAC1E,CAEA,SAASC,GAAUC,EAAUC,EAAiB,CAC5C,MAAO,CACL,GAAIA,EAAE,EAAID,EAAE,GAAK,GACjB,GAAIC,EAAE,EAAID,EAAE,GAAK,EAAA,CAErB,CAEA,SAASE,GAAyBL,EAAeC,EAAuB,CACtE,OAAQ,KAAK,MAAMA,EAAO,EAAID,EAAO,EAAGC,EAAO,EAAID,EAAO,CAAC,EAAI,IAAO,KAAK,EAC7E,CAEA,SAASM,GAAeC,EAA6B,CACnD,OAAQA,EAAc,KAAK,GAAM,GACnC,CAEA,SAASC,GAAWC,EAAeC,EAAgBC,EAAwB,CACzE,MAAMC,EAAW,GAAG3B,EAASwB,CAAK,CAAC,IAAIxB,EAASyB,CAAM,CAAC,IAAIpB,GAAiBqB,CAAQ,CAAC,GAE/EE,EAASrB,GAAOf,GAAmBmC,CAAQ,EACjD,GAAIC,EACF,OAAOA,EAET,MAAMC,EAASR,GAAeK,CAAQ,EAChCI,EAAS,KAAK,IAAID,CAAM,EACxBE,EAAS,KAAK,IAAIF,CAAM,EAExBG,EAAe,CACnB,MAAO,KAAK,IAAIF,EAASN,CAAK,EAAI,KAAK,IAAIO,EAASN,CAAM,EAC1D,OAAQ,KAAK,IAAIM,EAASP,CAAK,EAAI,KAAK,IAAIM,EAASL,CAAM,CAAA,EAG7D,OAAAd,GAAOnB,GAAmBmC,EAAUK,EAAQ1C,CAAc,EACnD0C,CACT,CAEA,SAASC,GACPC,EACAC,EACAC,EACAC,EACAC,EACAZ,EAAW,EACL,CACN,MAAMC,EAAW,GAAG3B,EAASkC,EAAY,CAAC,CAAC,IAAIlC,EAASmC,EAAa,CAAC,CAAC,IAAInC,EAASoC,EAAc,CAAC,CAAC,IAAIpC,EAASqC,EAAe,CAAC,CAAC,IAAIrC,EAASsC,EAAQ,GAAI,CAAC,IAAIjC,GAAiBqB,CAAQ,CAAC,GAEpLE,EAASrB,GAAOd,GAAekC,CAAQ,EAC7C,GAAIC,EACF,OAAOA,EAET,KAAM,CAAE,MAAAJ,EAAO,OAAAC,CAAA,EAAWF,GAAWW,EAAYC,EAAaT,CAAQ,EAChEa,EAAe,KAAK,IAAIf,EAAOY,CAAY,EAC3CI,EAAgB,KAAK,IAAIf,EAAQY,CAAa,EAE9CL,EACJO,EAAeC,EAAgBF,EAC3B,CACE,MAAOE,EAAgBF,EACvB,OAAQE,CAAA,EAEV,CACE,MAAOD,EACP,OAAQA,EAAeD,CAAA,EAG/B,OAAA3B,GAAOlB,GAAekC,EAAUK,EAAQ1C,CAAc,EAC/C0C,CACT,CAEA,SAASS,EACPC,EACAC,EACAC,EACAC,EACAnB,EAAW,EACJ,CACP,MAAMoB,EAAa3C,GAAiBuC,EAAS,CAAC,EACxCK,EAAa5C,GAAiBuC,EAAS,CAAC,EAExCf,EAAW,GAAGmB,CAAU,IAAIC,CAAU,IAAI/C,EAAS2C,EAAU,KAAK,CAAC,IAAI3C,EAAS2C,EAAU,MAAM,CAAC,IAAI3C,EAAS4C,EAAS,KAAK,CAAC,IAAI5C,EAAS4C,EAAS,MAAM,CAAC,IAAIxC,GAAayC,CAAI,CAAC,IAAIxC,GAAiBqB,CAAQ,CAAC,GAE9ME,EAASrB,GAAOZ,GAAsBgC,CAAQ,EACpD,GAAIC,EACF,OAAOA,EAET,KAAM,CAAE,MAAAJ,EAAO,OAAAC,CAAA,EAAWF,GACxBoB,EAAU,MACVA,EAAU,OACVjB,CAAA,EAGIsB,EAAexB,EAAQqB,EAAO,GAAMD,EAAS,MAAQ,GACrDK,EAAexB,EAASoB,EAAO,GAAMD,EAAS,OAAS,GAEvDZ,EAAgB,CACpB,EAAGpC,GAAM8C,EAAS,EAAG,CAACM,EAAcA,CAAY,EAChD,EAAGpD,GAAM8C,EAAS,EAAG,CAACO,EAAcA,CAAY,CAAA,EAGlD,OAAAtC,GAAOhB,GAAsBgC,EAAUK,EAAQ1C,CAAc,EACtD0C,CACT,CAEA,SAASkB,GACPC,EACAR,EACAC,EACAN,EACAO,EACAnB,EAAW,EACX0B,EAAgB,GAC2C,CAC3D,MAAMzB,EAAW,GAAGxB,GAAiBgD,EAAK,CAAC,CAAC,IAAIhD,GAAiBgD,EAAK,CAAC,CAAC,IAAInD,EAAS2C,EAAU,KAAK,CAAC,IAAI3C,EAAS2C,EAAU,MAAM,CAAC,IAAI3C,EAAS2C,EAAU,YAAY,CAAC,IAAI3C,EAAS2C,EAAU,aAAa,CAAC,IAAI3C,EAAS4C,EAAS,KAAK,CAAC,IAAI5C,EAAS4C,EAAS,MAAM,CAAC,IAAI5C,EAASsC,EAAQ,GAAI,CAAC,IAAIlC,GAAayC,CAAI,CAAC,IAAIxC,GAAiBqB,CAAQ,CAAC,IAAI0B,CAAa,GAE9VxB,EAASrB,GAAOb,GAAkBiC,CAAQ,EAEhD,GAAIC,EAAQ,OAAOA,EAEnB,MAAMyB,EAAeD,EAEjB,CAACE,EAAczD,IAAkBA,EADjC,CAACE,EAAaF,IAAkB,KAAK,IAAIE,EAAK,KAAK,IAAI,EAAGF,CAAK,CAAC,EAG9D0D,EAAgBhC,GAAWoB,EAAU,MAAOA,EAAU,OAAQjB,CAAQ,EACtE8B,EAAuBjC,GAC3BoB,EAAU,aACVA,EAAU,cACVjB,CAAA,EAGI+B,EAA+B,CACnC,EAAGJ,EACD,MACGE,EAAc,MAAQX,EAAS,MAAQC,GAAQ,EAAIM,EAAK,EAAIN,GAC7DU,EAAc,MACd,GAAA,EAEJ,EAAGF,EACD,MACGE,EAAc,OAASX,EAAS,OAASC,GAAQ,EAAIM,EAAK,EAAIN,GAC/DU,EAAc,OACd,GAAA,EAEJ,MAAOF,EACL,IACET,EAAS,MAAQW,EAAc,MAAS,IAAOV,CAAA,EAEnD,OAAQQ,EACN,IACET,EAAS,OAASW,EAAc,OAAU,IAAOV,CAAA,CACrD,EAGIa,EAAgB,KAAK,MACzBL,EACEG,EAAqB,MACpBC,EAAuB,MAAQD,EAAqB,MAAS,GAAA,CAChE,EAEIG,EAAiB,KAAK,MAC1BN,EACEG,EAAqB,OACpBC,EAAuB,OAASD,EAAqB,OAAU,GAAA,CAClE,EAKII,EAFJJ,EAAqB,OAASA,EAAqB,OAASlB,EAG1D,CACE,MAAO,KAAK,MAAMqB,EAAiBrB,CAAM,EACzC,OAAQqB,CAAA,EAEV,CACE,MAAOD,EACP,OAAQ,KAAK,MAAMA,EAAgBpB,CAAM,CAAA,EAGzCuB,EAA0B,CAC9B,GAAGD,EACH,EAAG,KAAK,MACNP,EACEG,EAAqB,MAAQI,EAAW,MACvCH,EAAuB,EAAID,EAAqB,MAAS,GAAA,CAC5D,EAEF,EAAG,KAAK,MACNH,EACEG,EAAqB,OAASI,EAAW,OACxCH,EAAuB,EAAID,EAAqB,OAAU,GAAA,CAC7D,CACF,EAGIxB,EAAS,CAAE,uBAAAyB,EAAwB,kBAAAI,CAAA,EAEzC,OAAAlD,GAAOjB,GAAkBiC,EAAUK,EAAQ1C,CAAc,EAClD0C,CACT,CAEA,SAAS8B,GAAcC,EAAa,CAClC,MAAMC,EAAMC,EAAM,OAAiB,IAAI,EAEvC,OAAID,EAAI,UAAY,OAClBA,EAAI,QAAUD,EAAA,GAGTC,CACT,CAEA,MAAME,GACJ,OAAO,OAAW,IAAcD,EAAM,gBAAkBA,EAAM,UAoBhE,SAASE,GACPC,EACAC,EACAC,EACAlB,EACAmB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACO,CACP,IAAIC,EAAa,GACbC,EAAqB,KAEzB,SAASC,GAAuB,CAC1BD,GAAO,OACXA,EAAM,sBAAsB,IAAM,CAChCA,EAAM,KACN,MAAME,EAAId,EAAS,QACnB,GAAIc,GAAG,WAAaA,EAAE,UAAYV,EAAkB,CAClD,KAAM,CAAE,uBAAAhB,EAAwB,kBAAAI,CAAA,EAAsBX,GACpDiC,EAAE,KACFA,EAAE,UACFA,EAAE,SACFb,EACAa,EAAE,KACFA,EAAE,SACF/B,CAAA,EAEFqB,EAAiBhB,EAAwBI,CAAiB,CAC5D,CACF,CAAC,EACH,CAEA,MAAMuB,EAAe,CACnB,UAAYC,GACNjB,EAAa,SACfA,EAAa,QAAQ,IAAIiB,CAAE,EACpB,IAAMjB,EAAa,SAAS,OAAOiB,CAAE,GAEvC,IAAM,CAAC,EAEhB,SAAU,IACRhB,EAAS,SAAW,CAClB,KAAM,CAAE,EAAG,EAAG,EAAG,CAAA,EACjB,KAAM,EACN,SAAU,EACV,UAAW,KACX,SAAU,KACV,WAAY,GACZ,eAAgB,EAAA,EAEpB,SAAU,CAAC5D,EAAKZ,IAAU,CACxB,MAAMyF,EAAQjB,EAAS,QACvB,GAAI,GAACiB,GAAS,OAAO,GAAGA,EAAM7E,CAAG,EAAGZ,CAAK,GAIzC,IAFAyF,EAAM7E,CAAG,EAAIZ,EAGXY,IAAQ,QACR,OAAOZ,GAAU,UACjBA,GACA,MAAOA,EAEP0E,IAAe1E,CAAK,UACXY,IAAQ,QAAU,OAAOZ,GAAU,SAC5C8E,IAAe9E,CAAK,UACXY,IAAQ,YAAc,OAAOZ,GAAU,SAChD+E,IAAmB/E,CAAK,UAExBY,IAAQ,YACR,OAAOZ,GAAU,UACjBA,GACA,UAAWA,EAEX2E,IAAmB3E,CAAK,UAExBY,IAAQ,aACR,OAAOZ,GAAU,UACjBA,GACA,iBAAkBA,EAElBgF,IAAgBhF,CAAK,UACZY,IAAQ,aACjB,GAAIZ,EACFiF,IAAA,MACK,CACLC,IAAA,EACA,MAAMQ,EAAelB,EAAS,QAC9B,GACEkB,GAAc,WACdA,EAAa,UACbb,EACA,CACA,KAAM,CAAE,uBAAAjB,EAAwB,kBAAAI,CAAA,EAC9BX,GACEqC,EAAa,KACbA,EAAa,UACbA,EAAa,SACbjB,EACAiB,EAAa,KACbA,EAAa,SACbnC,CAAA,EAEJsB,EAAejB,EAAwBI,CAAiB,CAC1D,CACF,EAICpD,IAAQ,QACPA,IAAQ,QACRA,IAAQ,YACRA,IAAQ,aACRA,IAAQ,aACVgE,GAEAS,EAAA,EAGGF,GACHI,EAAM,OAAA,EAEV,EACA,OAAQ,IAAM,CACZ,GAAIhB,EAAa,QACf,UAAWiB,KAAMjB,EAAa,QAC5BiB,EAAA,CAGN,EACA,MAAQtB,GAAmB,CACzB,GAAIiB,EAAY,CACdjB,EAAA,EACA,MACF,CACAiB,EAAa,GACb,GAAI,CACFjB,EAAA,CACF,QAAA,CACEiB,EAAa,GACbI,EAAM,OAAA,CACR,CACF,CAAA,EAGF,OAAOA,CACT,CAEA,MAAMI,GAAevB,EAAM,cAA4B,IAAI,EAE3D,SAASwB,GAAgBC,EAAsB,CAC7C,MAAMC,EAAU1B,EAAM,WAAWuB,EAAY,EAC7C,GAAI,CAACG,EACH,MAAM,IAAI,MAAM,KAAKD,CAAY,4BAA4BzG,EAAS,IAAI,EAE5E,OAAO0G,CACT,CAEA,SAASC,EAAYC,EAAuC,CAC1D,MAAMT,EAAQK,GAAgB,UAAU,EAElCK,EAAc7B,EAAM,YACxB,IAAM4B,EAAST,EAAM,UAAU,EAC/B,CAACA,EAAOS,CAAQ,CAAA,EAGlB,OAAO5B,EAAM,qBAAqBmB,EAAM,UAAWU,EAAaA,CAAW,CAC7E,CAkBA,MAAMC,GAAiB9B,EAAM,cAA0C,IAAI,EAE3E,SAAS+B,GAAkBN,EAAsB,CAC/C,MAAMC,EAAU1B,EAAM,WAAW8B,EAAc,EAC/C,GAAI,CAACJ,EACH,MAAM,IAAI,MAAM,KAAKD,CAAY,4BAA4BzG,EAAS,IAAI,EAE5E,OAAO0G,CACT,CA4BA,SAASM,GAAYC,EAAyB,CAC5C,KAAM,CACJ,KAAA/C,EAAO,CAAE,EAAG,EAAG,EAAG,CAAA,EAClB,KAAAN,EAAO,EACP,QAAAsD,EAAU,EACV,QAAAC,EAAU,EACV,UAAAC,EAAY,EACZ,SAAA3E,EAAW,EACX,aAAA4E,EAAe,EACf,YAAAhC,EAAc,EAAI,EAClB,MAAAiC,EAAQ,YACR,UAAAC,EAAY,UACZ,cAAApD,EAAgB,GAChB,kBAAAqD,EAAoB,GACpB,SAAAC,EAAW,GACX,aAAAnC,EACA,iBAAAC,EACA,iBAAAC,EACA,eAAAC,EACA,aAAAC,EACA,iBAAAC,EACA,cAAAC,EACA,mBAAAC,EACA,iBAAAC,EACA,UAAA4B,EACA,GAAGC,CAAA,EACDV,EAEE9B,EAAeN,GAAW,IAAM,IAAI,GAAiB,EACrDO,EAAWP,GAAuB,KAAO,CAC7C,KAAAX,EACA,KAAAN,EACA,SAAAnB,EACA,UAAW,KACX,SAAU,KACV,WAAY,GACZ,eAAgB,EAAA,EAChB,EAEImF,EAAU5C,EAAM,OAAoB,IAAI,EAExCmB,EAAQnB,EAAM,QAClB,IACEE,GACEC,EACAC,EACAC,EACAlB,EACAmB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAAA,EAEJ,CACEX,EACAC,EACAC,EACAlB,EACAmB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAAA,CACF,EAGFb,GAA0B,IAAM,CAC9B,MAAM4C,EAA+B,CAAA,EACrC,IAAIC,EAAa,GACbC,EAAkB,GAEtB,GAAI7D,IAAS,OAAW,CACtB,MAAMoC,EAAeH,EAAM,SAAA,EACtB,OAAO,GAAGG,EAAa,KAAMpC,CAAI,IACpC2D,EAAQ,KAAO3D,EACf4D,EAAa,GAEjB,CAEIlE,IAAS,QACUuC,EAAM,SAAA,EACV,OAASvC,IACxBiE,EAAQ,KAAOjE,EACfkE,EAAa,GACbC,EAAkB,IAIlBtF,IAAa,QACM0D,EAAM,SAAA,EACV,WAAa1D,IAC5BoF,EAAQ,SAAWpF,EACnBqF,EAAa,GACbC,EAAkB,IAIlBD,IACF3B,EAAM,MAAM,IAAM,CAChB,OAAO,QAAQ0B,CAAO,EAAE,QAAQ,CAAC,CAACrG,EAAKZ,CAAK,IAAM,CAChDuF,EAAM,SAAS3E,EAAyBZ,CAAK,CAC/C,CAAC,CACH,CAAC,EAEGmH,GAAmBH,EAAQ,SAC7B,sBAAsB,IAAM,CAC1B,MAAMtB,EAAeH,EAAM,SAAA,EAC3B,GAAIG,EAAa,UAAYA,EAAa,UAAW,CACnD,MAAM0B,EAAe7D,EAQjBmC,EAAa,KAPb9C,EACE8C,EAAa,KACbA,EAAa,UACbA,EAAa,SACbA,EAAa,KACbA,EAAa,QAAA,GAKjB,KAAK,IAAI0B,EAAY,EAAI1B,EAAa,KAAK,CAAC,EAAI,MAChD,KAAK,IAAI0B,EAAY,EAAI1B,EAAa,KAAK,CAAC,EAAI,OAEhDH,EAAM,SAAS,OAAQ6B,CAAW,CAEtC,CACF,CAAC,EAGP,EAAG,CAAC9D,EAAMN,EAAMnB,EAAU0D,EAAOhC,CAAa,CAAC,EAE/C,MAAM8D,EAAejD,EAAM,QACzB,KAAO,CACL,QAAAkC,EACA,QAAAC,EACA,UAAAC,EACA,aAAAC,EACA,YAAAhC,EACA,MAAAiC,EACA,UAAAC,EACA,kBAAAC,EACA,cAAArD,EACA,SAAAsD,EACA,QAAAG,CAAA,GAEF,CACEV,EACAC,EACAC,EACAC,EACAhC,EACAiC,EACAC,EACAC,EACArD,EACAsD,CAAA,CACF,EAGF,OACES,EAAAA,IAAC3B,GAAa,SAAb,CAAsB,MAAOJ,EAC5B,SAAA+B,EAAAA,IAACpB,GAAe,SAAf,CAAwB,MAAOmB,EAC9B,SAAAC,EAAAA,IAAC,MAAA,CACC,YAAU,kBACV,UAAWC,EAAAA,GAAG,qCAAsCT,CAAS,EAE7D,SAAAQ,EAAAA,IAACE,GAAA,CAAiB,GAAGT,CAAA,CAAW,CAAA,CAAA,EAEpC,CAAA,CACF,CAEJ,CAMA,SAASS,GAAgBnB,EAA6B,CACpD,KAAM,CAAE,UAAAS,EAAW,QAAAW,EAAS,IAAAtD,EAAK,GAAGuD,GAAiBrB,EAE/CP,EAAUK,GAAkB9G,EAAY,EACxCkG,EAAQK,GAAgBvG,EAAY,EACpCiE,EAAOyC,EAAUN,GAAUA,EAAM,IAAI,EACrCzC,EAAO+C,EAAUN,GAAUA,EAAM,IAAI,EACrC5D,EAAWkE,EAAUN,GAAUA,EAAM,QAAQ,EAC7C3C,EAAYiD,EAAUN,GAAUA,EAAM,SAAS,EAC/C1C,EAAWgD,EAAUN,GAAUA,EAAM,QAAQ,EAE7CkC,EAAcC,EAAAA,gBAAgBzD,EAAK2B,EAAQ,OAAO,EAClD+B,EAAuBzD,EAAM,OAAc,CAAE,EAAG,EAAG,EAAG,EAAG,EACzD0D,EAAmB1D,EAAM,OAAc,CAAE,EAAG,EAAG,EAAG,EAAG,EACrD2D,EAAqB3D,EAAM,OAAc,CAAE,EAAG,EAAG,EAAG,EAAG,EACvD4D,EAAuB5D,EAAM,OAAO,CAAC,EACrC6D,EAAuB7D,EAAM,OAAO,CAAC,EACrC8D,EAAoB9D,EAAM,OAAsB,IAAI,EACpD+D,EAAqB/D,EAAM,OAAsB,IAAI,EACrDgE,EAAgBhE,EAAM,OAAsB,IAAI,EAChDiE,EAAgBjE,EAAM,OAAO,EAAK,EAClCkE,EAAsBlE,EAAM,OAAO,CAAC,EACpCmE,EAA0BnE,EAAM,OAAO,CAAC,EAExCoE,EAAgBpE,EAAM,YAAY,IAAM,CACxC8D,EAAkB,UACpB,qBAAqBA,EAAkB,OAAO,EAC9CA,EAAkB,QAAU,MAE1BC,EAAmB,UACrB,qBAAqBA,EAAmB,OAAO,EAC/CA,EAAmB,QAAU,MAE3BC,EAAc,UAChB,aAAaA,EAAc,OAAO,EAClCA,EAAc,QAAU,MAE1BC,EAAc,QAAU,EAC1B,EAAG,CAAA,CAAE,EAECI,EAAkBrE,EAAM,YAAY,IAAM,CAC1CtE,GAAqB,KAAOL,EAAiB,KAC/CK,GAAqB,MAAA,EAEnBD,GAAiB,KAAOJ,EAAiB,KAC3CI,GAAiB,MAAA,CAErB,EAAG,CAAA,CAAE,EAEC6I,EAAgBtE,EAAM,YACzBuE,IAA0C,CACzC,EAAG,OAAOA,EAAM,OAAO,EACvB,EAAG,OAAOA,EAAM,OAAO,CAAA,GAEzB,CAAA,CAAC,EAGGC,EAAgBxE,EAAM,YACzByE,IAAgC,CAC/B,EAAG,OAAOA,EAAM,OAAO,EACvB,EAAG,OAAOA,EAAM,OAAO,CAAA,GAEzB,CAAA,CAAC,EAGGC,EAA0B1E,EAAM,YAAY,IAAM,CACtD,GAAI0B,EAAQ,SAAS,QAAS,CAC5B,MAAMiD,EAASjD,EAAQ,QAAQ,QAAQ,sBAAA,EACvCiC,EAAmB,QAAU,CAAE,EAAGgB,EAAO,KAAM,EAAGA,EAAO,GAAA,CAC3D,CACF,EAAG,CAACjD,EAAQ,OAAO,CAAC,EAEdkD,EAAoB5E,EAAM,YAC9B,CAAC,CAAE,EAAA6E,EAAG,EAAAC,CAAA,EAAYC,IAAiC,CACjD,GAAI,CAACrD,EAAQ,SAAS,QACpB,MAAO,CAAE,EAAG,EAAG,EAAG,CAAA,EAEpB,MAAMsD,EAActD,EAAQ,QAAQ,QAAQ,sBAAA,EAC5C,MAAO,CACL,EAAGsD,EAAY,MAAQ,GAAKH,EAAIE,EAAe,GAC/C,EAAGC,EAAY,OAAS,GAAKF,EAAIC,EAAe,EAAA,CAEpD,EACA,CAACrD,EAAQ,OAAO,CAAA,EAGZuD,EAAkBjF,EAAM,YAC5B,CAAC,CAAE,EAAA6E,EAAG,EAAAC,MACG,CACL,GAAID,EAAI3F,EAAK,GAAKN,EAClB,GAAIkG,EAAI5F,EAAK,GAAKN,CAAA,GAGtB,CAACM,EAAMN,CAAI,CAAA,EAGPsG,EAAwBlF,EAAM,YAAY,IAAM,CACpD,GAAI,CAACrB,GAAY,CAACD,EAAW,OAE7B,MAAMsE,EAAetB,EAAQ,cAEzBxC,EADAV,EAAgBU,EAAMR,EAAWC,EAAUC,EAAMnB,CAAQ,GAI3D,KAAK,IAAIuF,EAAY,EAAI9D,EAAK,CAAC,EAAI,MACnC,KAAK,IAAI8D,EAAY,EAAI9D,EAAK,CAAC,EAAI,OAEnCiC,EAAM,SAAS,OAAQ6B,CAAW,CAEtC,EAAG,CAACrE,EAAUD,EAAWgD,EAAQ,cAAexC,EAAMN,EAAMnB,EAAU0D,CAAK,CAAC,EAEtET,EAAeV,EAAM,YACzB,CAACmF,EAAiBC,EAAcC,EAAuB,KAAS,CAC9D,GAAI,CAAC1G,GAAY,CAACD,EAAW,OAE7B,MAAM4G,EAAc3J,GAAMwJ,EAASzD,EAAQ,QAASA,EAAQ,OAAO,EAEnEP,EAAM,MAAM,IAAM,CAChB,GAAIkE,EAAsB,CACxB,MAAME,EAAYX,EAChBQ,EACAzB,EAAmB,OAAA,EAEf6B,EAAaP,EAAgBM,CAAS,EACtCE,EAAoB,CACxB,EAAGD,EAAW,EAAIF,EAAcC,EAAU,EAC1C,EAAGC,EAAW,EAAIF,EAAcC,EAAU,CAAA,EAGtCvC,GAAetB,EAAQ,cAQzB+D,EAPAjH,EACEiH,EACA/G,EACAC,EACA2G,EACA7H,CAAA,EAIN0D,EAAM,SAAS,OAAQ6B,EAAW,CACpC,CACA7B,EAAM,SAAS,OAAQmE,CAAW,CACpC,CAAC,EAED,sBAAsB,IAAM,CAC1BJ,EAAA,CACF,CAAC,CACH,EACA,CACEvG,EACAD,EACAgD,EAAQ,QACRA,EAAQ,QACRA,EAAQ,cACRkD,EACAK,EACAxH,EACA0D,EACA+D,CAAA,CACF,EAGIQ,EAAc1F,EAAM,YACxB,CAAC,CAAE,EAAA6E,EAAG,EAAAC,KAAe,CACnBrB,EAAqB,QAAU,CAAE,EAAAoB,EAAG,EAAAC,CAAA,EACpCpB,EAAiB,QAAU,CAAE,GAAGxE,CAAA,EAChCiC,EAAM,SAAS,aAAc,EAAI,CACnC,EACA,CAACjC,EAAMiC,CAAK,CAAA,EAGRwE,EAAS3F,EAAM,YACnB,CAAC,CAAE,EAAA6E,EAAG,EAAAC,KAAe,CACfhB,EAAkB,SACpB,qBAAqBA,EAAkB,OAAO,EAGhDA,EAAkB,QAAU,sBAAsB,IAAM,CAEtD,GADI,CAACnF,GAAY,CAACD,GACdmG,IAAM,QAAaC,IAAM,OAAW,OAExC,MAAMc,EAAUf,EAAIpB,EAAqB,QAAQ,EAC3CoC,EAAUf,EAAIrB,EAAqB,QAAQ,EAEjD,GAAI,KAAK,IAAImC,CAAO,EAAI,GAAK,KAAK,IAAIC,CAAO,EAAI,EAC/C,OAGF,MAAMJ,EAAoB,CACxB,EAAG/B,EAAiB,QAAQ,EAAIkC,EAChC,EAAGlC,EAAiB,QAAQ,EAAImC,CAAA,EAG5B7C,EAAetB,EAAQ,cAQzB+D,EAPAjH,EACEiH,EACA/G,EACAC,EACAC,EACAnB,CAAA,EAIAqI,EAAc3E,EAAM,SAAA,EAAW,MAEnC,KAAK,IAAI6B,EAAY,EAAI8C,EAAY,CAAC,EAAI,GAC1C,KAAK,IAAI9C,EAAY,EAAI8C,EAAY,CAAC,EAAI,IAE1C3E,EAAM,SAAS,OAAQ6B,CAAW,CAEtC,CAAC,CACH,EACA,CAACrE,EAAUD,EAAWgD,EAAQ,cAAe9C,EAAMnB,EAAU0D,CAAK,CAAA,EAG9D4E,EAAc/F,EAAM,YACvBuE,GAAsBoB,EAAOrB,EAAcC,CAAK,CAAC,EAClD,CAACD,EAAeqB,CAAM,CAAA,EAGlBK,EAAchG,EAAM,YACvBuE,GAAsB,CAErB,GADAA,EAAM,eAAA,EACFA,EAAM,QAAQ,SAAW,EAAG,CAC9B,KAAM,CAAC0B,EAAYC,CAAW,EAAI3B,EAAM,SAAW,CAAA,EACnD,GAAI0B,GAAcC,EAAa,CAC7B,MAAMpJ,EAAS0H,EAAcyB,CAAU,EACjClJ,EAASyH,EAAc0B,CAAW,EAClCC,EAASnJ,GAAUF,EAAQC,CAAM,EACvC4I,EAAOQ,CAAM,EAETpC,EAAmB,SACrB,qBAAqBA,EAAmB,OAAO,EAGjDA,EAAmB,QAAU,sBAAsB,IAAM,CACvD,MAAMqC,EAAWvJ,GAAyBC,EAAQC,CAAM,EAClDsJ,GAAgBD,EAAWxC,EAAqB,QAEtD,GAAI,KAAK,IAAIyC,GAAgB,CAAC,EAAI,IAAM,CACtC,MAAMlB,GAAUvG,EAAOyH,GACvB3F,EAAayE,GAASgB,EAAQ,EAAK,EACnCvC,EAAqB,QAAUwC,CACjC,CAEA,MAAME,GAAgBnJ,GAAyBL,EAAQC,CAAM,EACvDwJ,GAAeD,GAAgBzC,EAAqB,QAE1D,GAAI,KAAK,IAAI0C,EAAY,EAAI,GAAK,CAChC,MAAMC,GAAc/I,EAAW8I,GAC/BpF,EAAM,SAAS,WAAYqF,EAAW,EACtC3C,EAAqB,QAAUyC,EACjC,CACF,CAAC,CACH,CACF,SAAW/B,EAAM,QAAQ,SAAW,EAAG,CACrC,MAAM0B,EAAa1B,EAAM,QAAQ,CAAC,EAC9B0B,GACFN,EAAOnB,EAAcyB,CAAU,CAAC,CAEpC,CACF,EACA,CAACzB,EAAemB,EAAQ/G,EAAM8B,EAAcjD,EAAU0D,CAAK,CAAA,EAGvDsF,EAAkBzG,EAAM,YAC3BuE,GAAwB,CAEvB,GADAA,EAAM,eAAA,EACFN,EAAc,QAChB,OAGF,MAAMmB,EAAQ,CAAE,EAAG,OAAOb,EAAM,OAAO,EAAG,EAAG,OAAOA,EAAM,OAAO,CAAA,EAC3DY,EAAUjB,EAAoB,QAAU,EAAIK,EAAM,MACxD7D,EAAayE,EAASC,EAAO,EAAI,EAEjC,MAAMoB,EAAcrC,EAAwB,QAAUI,EAAM,SAC5DpD,EAAM,SAAS,WAAYqF,CAAW,CACxC,EACA,CAAC9F,EAAcS,CAAK,CAAA,EAGhBuF,EAAe1G,EAAM,YAAY,IAAM,CAC3C,SAAS,oBACP,gBACAyG,CAAA,EAEF,SAAS,oBAAoB,aAAcC,CAA6B,CAC1E,EAAG,CAACD,CAAe,CAAC,EAEdE,GAAiB3G,EAAM,YAC1BuE,GAAwB,CACvBA,EAAM,eAAA,EACN,SAAS,iBACP,gBACAkC,CAAA,EAEF,SAAS,iBAAiB,aAAcC,CAA6B,EACrExC,EAAoB,QAAUtF,EAC9BuF,EAAwB,QAAU1G,CACpC,EACA,CAACmB,EAAMnB,EAAUgJ,EAAiBC,CAAY,CAAA,EAG1CE,GAAsB5G,EAAM,YAC/BuE,GAAiBA,EAAM,eAAA,EACxB,CAAA,CAAC,EAGGsC,GAAkB7G,EAAM,YAAY,IAAM,CAC9C,SAAS,oBAAoB,YAAa+F,CAAW,EACrD,SAAS,oBAAoB,YAAaC,CAAW,EACrD,SAAS,oBACP,gBACAS,CAAA,EAEF,SAAS,oBAAoB,aAAcC,CAA6B,CAC1E,EAAG,CAACX,EAAaC,EAAaS,EAAiBC,CAAY,CAAC,EAEtDI,EAAgB9G,EAAM,YAAY,IAAM,CAC5CiE,EAAc,QAAU,GACxB9C,EAAM,SAAS,aAAc,EAAK,EAClCiD,EAAA,EACA,SAAS,oBAAoB,UAAW0C,CAAa,EACrD,SAAS,oBAAoB,WAAYA,CAAa,EACtDD,GAAA,CACF,EAAG,CAAC1F,EAAO0F,GAAiBzC,CAAa,CAAC,EAEpC2C,GAAgB/G,EAAM,YAAauE,GAAsB,CAC7D,IAAIyC,EAASzC,EAAM,OACf0C,EAAS1C,EAAM,OACf2C,EAAS3C,EAAM,OAEnB,OAAIA,EAAM,YAAc,GACtByC,GAAU,GACVC,GAAU,GACVC,GAAU,IACD3C,EAAM,YAAc,IAC7ByC,GAAU,IACVC,GAAU,IACVC,GAAU,KAGL,CAAE,OAAAF,EAAQ,OAAAC,EAAQ,OAAAC,CAAA,CAC3B,EAAG,CAAA,CAAE,EAECC,GAAcnH,EAAM,YACvBuE,GAAsB,CAErB,GADAjB,EAAa,cAAciB,CAAK,EAC5BA,EAAM,iBAAkB,OAE5BA,EAAM,eAAA,EACN,MAAMa,EAAQd,EAAcC,CAAK,EAC3B,CAAE,OAAA0C,CAAA,EAAWF,GAAcxC,CAAK,EAChCY,EAAUvG,EAAQqI,EAASvF,EAAQ,UAAa,IACtDhB,EAAayE,EAASC,EAAO,EAAI,EAEjCjE,EAAM,MAAM,IAAM,CAChB,MAAMG,EAAeH,EAAM,SAAA,EACtBG,EAAa,gBAChBH,EAAM,SAAS,iBAAkB,EAAI,EAElCG,EAAa,YAChBH,EAAM,SAAS,aAAc,EAAI,CAErC,CAAC,EAEG6C,EAAc,SAChB,aAAaA,EAAc,OAAO,EAEpCA,EAAc,QAAU,OAAO,WAAW,IAAM,CAC9C7C,EAAM,MAAM,IAAM,CAChBA,EAAM,SAAS,iBAAkB,EAAK,EACtCA,EAAM,SAAS,aAAc,EAAK,CACpC,CAAC,CACH,EAAG,GAAG,CACR,EACA,CACEmC,EAAa,YACbgB,EACA1F,EACA8C,EAAQ,UACRhB,EACAqG,GACA5F,CAAA,CACF,EAGIiG,GAAUpH,EAAM,YACnBuE,GAA4C,CAE3C,GADAjB,EAAa,UAAUiB,CAAK,EACxBA,EAAM,iBAAkB,WAEN,IAAI,CACxB,UACA,YACA,YACA,YAAA,CACD,EAEa,IAAIA,EAAM,GAAG,IACzBA,EAAM,eAAA,EACNpD,EAAM,SAAS,aAAc,EAAK,EAEtC,EACA,CAACmC,EAAa,QAASnC,CAAK,CAAA,EAGxBkG,GAAYrH,EAAM,YACrBuE,GAA4C,CAE3C,GADAjB,EAAa,YAAYiB,CAAK,EAC1BA,EAAM,kBAAoB,CAAC5F,GAAY,CAACD,EAAW,OAEvD,IAAIzC,EAAOyF,EAAQ,aACf6C,EAAM,WACRtI,GAAQ,IAUV,MAAMqL,EAP4C,CAChD,QAAS,KAAO,CAAE,GAAGpI,EAAM,EAAGA,EAAK,EAAIjD,IACvC,UAAW,KAAO,CAAE,GAAGiD,EAAM,EAAGA,EAAK,EAAIjD,IACzC,UAAW,KAAO,CAAE,GAAGiD,EAAM,EAAGA,EAAK,EAAIjD,IACzC,WAAY,KAAO,CAAE,GAAGiD,EAAM,EAAGA,EAAK,EAAIjD,CAAA,EAAK,EAGnBsI,EAAM,GAAG,EACvC,GAAI,CAAC+C,EAAU,OAEf/C,EAAM,eAAA,EAEN,IAAIgD,EAAUD,EAAA,EAET5F,EAAQ,gBACX6F,EAAU/I,EAAgB+I,EAAS7I,EAAWC,EAAUC,EAAMnB,CAAQ,GAGnE8G,EAAM,QACTpD,EAAM,SAAS,aAAc,EAAI,EAGnCA,EAAM,SAAS,OAAQoG,CAAO,CAChC,EACA,CACEjE,EAAa,UACb3E,EACAD,EACAgD,EAAQ,aACRA,EAAQ,cACRxC,EACAN,EACAnB,EACA0D,CAAA,CACF,EAGIqG,GAAcxH,EAAM,YACvBuE,GAAyC,CACxCjB,EAAa,cAAciB,CAAK,EAC5B,CAAAA,EAAM,mBAEVA,EAAM,eAAA,EACN,SAAS,iBAAiB,YAAawB,CAAW,EAClD,SAAS,iBAAiB,UAAWe,CAAa,EAClDpC,EAAA,EACAgB,EAAYpB,EAAcC,CAAK,CAAC,EAClC,EACA,CACEjB,EAAa,YACbgB,EACAoB,EACAoB,EACAf,EACArB,CAAA,CACF,EAGI+C,GAAezH,EAAM,YACxBuE,GAAyC,CAExC,GADAjB,EAAa,eAAeiB,CAAK,EAC7B,CAAAA,EAAM,kBAOV,GALAN,EAAc,QAAU,GACxB,SAAS,iBAAiB,YAAa+B,EAAa,CAAE,QAAS,GAAO,EACtE,SAAS,iBAAiB,WAAYc,CAAa,EACnDpC,EAAA,EAEIH,EAAM,QAAQ,SAAW,EAAG,CAC9B,KAAM,CAAC0B,EAAYC,CAAW,EAAI3B,EAAM,QACpC,MAAM,KAAKA,EAAM,OAAO,EACxB,CAAA,EACJ,GAAI0B,GAAcC,EAAa,CAC7B,MAAMpJ,EAAS0H,EAAcyB,CAAU,EACjClJ,EAASyH,EAAc0B,CAAW,EACxCtC,EAAqB,QAAU/G,GAC7BC,EACAC,CAAA,EAEF8G,EAAqB,QAAU1G,GAC7BL,EACAC,CAAA,EAEF2I,EAAY1I,GAAUF,EAAQC,CAAM,CAAC,CACvC,CACF,SAAWwH,EAAM,QAAQ,SAAW,EAAG,CACrC,MAAM0B,EAAa1B,EAAM,QAAQ,CAAC,EAC9B0B,GACFP,EAAYlB,EAAcyB,CAAU,CAAC,CAEzC,EACF,EACA,CACE3C,EAAa,aACbwD,EACAd,EACAtB,EACAF,EACAkB,CAAA,CACF,EAGF1F,EAAM,UAAU,IAAM,CACpB,MAAM0H,EAAUhG,EAAQ,SAAS,QACjC,GAAKgG,EAEL,OAAKhG,EAAQ,mBACXgG,EAAQ,iBAAiB,QAASP,GAAa,CAAE,QAAS,GAAO,EAGnEO,EAAQ,iBAAiB,eAAgBd,EAAmB,EAC5Dc,EAAQ,iBAAiB,eAAgBf,EAA+B,EAEjE,IAAM,CACNjF,EAAQ,mBACXgG,EAAQ,oBAAoB,QAASP,EAAW,EAElDO,EAAQ,oBAAoB,eAAgBd,EAAmB,EAC/Dc,EAAQ,oBACN,eACAf,EAAA,EAEFvC,EAAA,CACF,CACF,EAAG,CACD1C,EAAQ,QACRA,EAAQ,kBACRyF,GACA/C,EACAwC,GACAD,EAAA,CACD,EAED3G,EAAM,UAAU,IACP,IAAM,CACXoE,EAAA,EACAC,EAAA,CACF,EACC,CAACD,EAAeC,CAAe,CAAC,EAEnC,MAAMsD,GAAgBtE,EAAUuE,EAAAA,KAAO,MAEvC,OACE1E,EAAAA,IAACyE,GAAA,CACC,YAAU,UACV,SAAU,EACT,GAAGrE,EACJ,IAAKC,EACL,UAAWJ,EAAAA,GACT,oHACAT,CAAA,EAEF,QAAA0E,GACA,UAAAC,GACA,YAAAG,GACA,aAAAC,EAAA,CAAA,CAGN,CAEA,MAAMI,GAAuBC,GAAAA,IAAI,wBAAyB,CACxD,SAAU,CACR,UAAW,CACT,QAAS,gDACT,MAAO,gBACP,mBAAoB,gBACpB,iBAAkB,eAAA,CACpB,EAEF,gBAAiB,CACf,UAAW,SAAA,CAEf,CAAC,EAYD,SAASC,GAAmE,CAC1E,SAAAC,EACA,QAAAtG,EACA,MAAAP,EACA,SAAA1D,EACA,qBAAAwK,CACF,EAAgC,CAqH9B,MAAO,CAAE,aApHYjI,EAAM,YAAY,IAAM,CAC3C,MAAMkI,EAAQF,EAAS,QACjBN,EAAUhG,EAAQ,SAAS,QACjC,GAAI,CAACwG,GAAS,CAACR,EAAS,OAExB,MAAM1C,EAAc0C,EAAQ,sBAAA,EACtBS,EAAkBnD,EAAY,MAAQA,EAAY,OAClD,CAAE,MAAOoD,EAAc,OAAQC,CAAA,EACnCJ,EAAqBC,CAAK,EACtBI,EACJJ,EAAM,YAAcE,GAAgBF,EAAM,aAAeG,EACrDE,EAAcH,EAAeC,EAEnC,IAAIG,EAEJ,GAAIF,EAAc,CAgChB,MAAMhB,EA/BqB,CACzB,QAAS,IACPa,EAAkBI,EACd,CACE,MAAOvD,EAAY,OAASuD,EAC5B,OAAQvD,EAAY,MAAA,EAEtB,CACE,MAAOA,EAAY,MACnB,OAAQA,EAAY,MAAQuD,CAAA,EAEpC,mBAAoB,KAAO,CACzB,MAAOvD,EAAY,MACnB,OAAQA,EAAY,MAAQuD,CAAA,GAE9B,iBAAkB,KAAO,CACvB,MAAOvD,EAAY,OAASuD,EAC5B,OAAQvD,EAAY,MAAA,GAEtB,MAAO,IACLmD,EAAkBI,EACd,CACE,MAAOvD,EAAY,MACnB,OAAQA,EAAY,MAAQuD,CAAA,EAE9B,CACE,MAAOvD,EAAY,OAASuD,EAC5B,OAAQvD,EAAY,MAAA,CACtB,EAG4BtD,EAAQ,SAAS,EACrD8G,EAAoBlB,EAChBA,IACAa,EAAkBI,EAChB,CACE,MAAOvD,EAAY,OAASuD,EAC5B,OAAQvD,EAAY,MAAA,EAEtB,CACE,MAAOA,EAAY,MACnB,OAAQA,EAAY,MAAQuD,CAAA,CAEtC,MACEC,EAAoB,CAClB,MAAON,EAAM,YACb,OAAQA,EAAM,YAAA,EAIlB,MAAMxJ,EAAuB,CAC3B,GAAG8J,EACH,aAAAJ,EACA,cAAAC,CAAA,EAGFlH,EAAM,SAAS,YAAazC,CAAS,EAErC,MAAMC,EAAWX,GACfU,EAAU,MACVA,EAAU,OACVsG,EAAY,MACZA,EAAY,OACZtD,EAAQ,YACRjE,CAAA,EAGF,OAAA0D,EAAM,SAAS,WAAYxC,CAAQ,EAEnC,sBAAsB,IAAM,CAC1B,MAAM2C,EAAeH,EAAM,SAAA,EAC3B,GAAIG,EAAa,UAAYA,EAAa,UAAW,CACnD,MAAM0B,EAAcxE,EAClB8C,EAAa,KACbA,EAAa,UACbA,EAAa,SACbA,EAAa,KACbA,EAAa,QAAA,GAIb,KAAK,IAAI0B,EAAY,EAAI1B,EAAa,KAAK,CAAC,EAAI,MAChD,KAAK,IAAI0B,EAAY,EAAI1B,EAAa,KAAK,CAAC,EAAI,OAEhDH,EAAM,SAAS,OAAQ6B,CAAW,CAEtC,CACF,CAAC,EAEM,CAAE,UAAAtE,EAAW,SAAAC,CAAA,CACtB,EAAG,CACDqJ,EACAtG,EAAQ,YACRA,EAAQ,QACRA,EAAQ,UACRP,EACA1D,EACAwK,CAAA,CACD,CAEQ,CACX,CAUA,SAASQ,GAAaxG,EAA0B,CAC9C,KAAM,CACJ,UAAAS,EACA,MAAAgG,EACA,QAAArF,EACA,IAAAtD,EACA,OAAA4I,EACA,UAAApG,EACA,WAAAqG,EAAa,GACb,GAAGC,CAAA,EACD5G,EAEEP,EAAUK,GAAkB7G,EAAU,EACtCiG,EAAQK,GAAgBtG,EAAU,EAClCgE,EAAOyC,EAAUN,GAAUA,EAAM,IAAI,EACrCzC,EAAO+C,EAAUN,GAAUA,EAAM,IAAI,EACrC5D,EAAWkE,EAAUN,GAAUA,EAAM,QAAQ,EAE7CyH,EAAW9I,EAAM,OAAyB,IAAI,EAC9CuD,EAAcC,EAAAA,gBAAgBzD,EAAK+I,CAAQ,EAE3Cb,EAAuBjI,EAAM,YAChC+I,IAA6B,CAC5B,MAAOA,EAAM,aACb,OAAQA,EAAM,aAAA,GAEhB,CAAA,CAAC,EAGG,CAAE,aAAAC,CAAA,EAAiBjB,GAAoB,CAC3C,SAAUe,EACV,QAAApH,EACA,MAAAP,EACA,SAAA1D,EACA,qBAAAwK,CAAA,CACD,EAEKgB,EAAcjJ,EAAM,YAAY,IAAM,CAC5B8I,EAAS,UAGvBE,EAAA,EAEAL,IACE,IAAI,MAAM,MAAM,CAAA,EAEpB,EAAG,CAACK,EAAcL,CAAM,CAAC,EAEzB3I,EAAM,UAAU,IAAM,CACpB,MAAM+I,EAAQD,EAAS,QACnBC,GAAO,UAAYA,EAAM,aAAe,GAC1CE,EAAA,CAEJ,EAAG,CAACA,CAAW,CAAC,EAEhBjJ,EAAM,UAAU,IAAM,CACpB,MAAM0H,EAAUhG,EAAQ,SAAS,QACjC,GAAKgG,EAEL,GAAI,OAAO,eAAmB,IAAa,CACzC,IAAIwB,EAAgB,GACpB,MAAMC,EAAiB,IAAI,eAAe,IAAM,CAC9C,GAAID,EAAe,CACjBA,EAAgB,GAChB,MACF,CAEA,MAAM5B,EAAW,IAAM,CACrB,MAAMyB,EAAQD,EAAS,QACnBC,GAAO,UAAYA,EAAM,aAAe,GAC1CC,EAAA,CAEJ,EAEI,wBAAyB,OAC3B,oBAAoB1B,CAAQ,EAE5B,WAAWA,EAAU,EAAE,CAE3B,CAAC,EAED,OAAA6B,EAAe,QAAQzB,CAAO,EAEvB,IAAM,CACXyB,EAAe,WAAA,CACjB,CACF,KAAO,CACL,MAAMC,EAAiB,IAAM,CAC3B,MAAML,EAAQD,EAAS,QACnBC,GAAO,UAAYA,EAAM,aAAe,GAC1CC,EAAA,CAEJ,EAEA,cAAO,iBAAiB,SAAUI,CAAc,EACzC,IAAM,CACX,OAAO,oBAAoB,SAAUA,CAAc,CACrD,CACF,CACF,EAAG,CAAC1H,EAAQ,QAASsH,CAAY,CAAC,EAElC,MAAMK,EAAiBhG,EAAUuE,EAAAA,KAAO,MAExC,OACE1E,EAAAA,IAACmG,EAAA,CACC,YAAU,gBACT,GAAGR,EACJ,IAAKtF,EACL,UAAWJ,EAAAA,GACT0E,GAAqB,CACnB,UAAWtF,GAAab,EAAQ,UAChC,UAAAgB,CAAA,CACD,CAAA,EAEH,MAAO,CACL,UAAWkG,EACP,aAAavM,GAAkB6C,EAAK,CAAC,CAAC,OAAO7C,GAAkB6C,EAAK,CAAC,CAAC,cAAczB,CAAQ,cAAcmB,CAAI,IAC9G,aAAaM,EAAK,CAAC,OAAOA,EAAK,CAAC,cAAczB,CAAQ,cAAcmB,CAAI,IAC5E,GAAG8J,CAAA,EAEL,OAAQO,CAAA,CAAA,CAGd,CAUA,SAASK,GAAarH,EAA0B,CAC9C,KAAM,CACJ,UAAAS,EACA,MAAAgG,EACA,QAAArF,EACA,IAAAtD,EACA,iBAAAwJ,EACA,UAAAhH,EACA,WAAAqG,EAAa,GACb,GAAGY,CAAA,EACDvH,EAEEP,EAAUK,GAAkB5G,EAAU,EACtCgG,EAAQK,GAAgBrG,EAAU,EAClC+D,EAAOyC,EAAUN,GAAUA,EAAM,IAAI,EACrCzC,EAAO+C,EAAUN,GAAUA,EAAM,IAAI,EACrC5D,EAAWkE,EAAUN,GAAUA,EAAM,QAAQ,EAE7CoI,EAAWzJ,EAAM,OAAyB,IAAI,EAC9CuD,EAAcC,EAAAA,gBAAgBzD,EAAK0J,CAAQ,EAE3CxB,EAAuBjI,EAAM,YAChC0J,IAA6B,CAC5B,MAAOA,EAAM,WACb,OAAQA,EAAM,WAAA,GAEhB,CAAA,CAAC,EAGG,CAAE,aAAAV,CAAA,EAAiBjB,GAAoB,CAC3C,SAAU0B,EACV,QAAA/H,EACA,MAAAP,EACA,SAAA1D,EACA,qBAAAwK,CAAA,CACD,EAEKgB,EAAcjJ,EAAM,YAAY,IAAM,CAC5ByJ,EAAS,UAGvBT,EAAA,EAEAO,IACE,IAAI,MACF,gBAAA,CACF,EAEJ,EAAG,CAACP,EAAcO,CAAgB,CAAC,EAEnCvJ,EAAM,UAAU,IAAM,CACpB,MAAM0H,EAAUhG,EAAQ,SAAS,QACjC,GAAKgG,EAEL,GAAI,OAAO,eAAmB,IAAa,CACzC,IAAIwB,EAAgB,GACpB,MAAMC,EAAiB,IAAI,eAAe,IAAM,CAC9C,GAAID,EAAe,CACjBA,EAAgB,GAChB,MACF,CAEA,MAAM5B,EAAW,IAAM,CACrB,MAAMoC,EAAQD,EAAS,QACnBC,GAASA,EAAM,WAAa,GAAKA,EAAM,YAAc,GACvDV,EAAA,CAEJ,EAEI,wBAAyB,OAC3B,oBAAoB1B,CAAQ,EAE5B,WAAWA,EAAU,EAAE,CAE3B,CAAC,EAED,OAAA6B,EAAe,QAAQzB,CAAO,EAEvB,IAAM,CACXyB,EAAe,WAAA,CACjB,CACF,KAAO,CACL,MAAMC,EAAiB,IAAM,CAC3B,MAAMM,EAAQD,EAAS,QACnBC,GAASA,EAAM,WAAa,GAAKA,EAAM,YAAc,GACvDV,EAAA,CAEJ,EAEA,cAAO,iBAAiB,SAAUI,CAAc,EACzC,IAAM,CACX,OAAO,oBAAoB,SAAUA,CAAc,CACrD,CACF,CACF,EAAG,CAAC1H,EAAQ,QAASsH,CAAY,CAAC,EAElC,MAAMW,EAAiBtG,EAAUuE,EAAAA,KAAO,QAExC,OACE1E,EAAAA,IAACyG,EAAA,CACC,YAAU,gBACV,SAAQ,GACR,YAAW,GACX,KAAI,GACJ,MAAK,GACL,SAAU,GACT,GAAGH,EACJ,IAAKjG,EACL,UAAWJ,EAAAA,GACT0E,GAAqB,CACnB,UAAWtF,GAAab,EAAQ,UAChC,UAAAgB,CAAA,CACD,CAAA,EAEH,MAAO,CACL,UAAWkG,EACP,aAAavM,GAAkB6C,EAAK,CAAC,CAAC,OAAO7C,GAAkB6C,EAAK,CAAC,CAAC,cAAczB,CAAQ,cAAcmB,CAAI,IAC9G,aAAaM,EAAK,CAAC,OAAOA,EAAK,CAAC,cAAczB,CAAQ,cAAcmB,CAAI,IAC5E,GAAG8J,CAAA,EAEL,iBAAkBO,CAAA,CAAA,CAGxB,CAEA,MAAMW,GAAsB9B,GAAAA,IAC1B,qKACA,CACE,SAAU,CACR,MAAO,CACL,UAAW,GACX,OAAQ,cAAA,EAEV,SAAU,CACR,KAAM,iXACN,MAAO,EAAA,CACT,EAEF,gBAAiB,CACf,MAAO,YACP,SAAU,EAAA,CACZ,CAEJ,EAOA,SAAS+B,GAAY5H,EAAyB,CAC5C,KAAM,CACJ,UAAAS,EACA,MAAAgG,EACA,QAAArF,EACA,IAAAtD,EACA,WAAA6I,EAAa,GACb,MAAAtG,EACA,SAAAG,EACA,GAAGqH,CAAA,EACD7H,EAEEP,EAAUK,GAAkB3G,EAAS,EACrCuD,EAAWgD,EAAUN,GAAUA,EAAM,QAAQ,EAEnD,GAAI,CAAC1C,EAAU,OAAO,KAEtB,MAAMoL,EAAgB1G,EAAUuE,EAAAA,KAAO,MAEvC,OACE1E,EAAAA,IAAC6G,EAAA,CACC,YAAU,eACT,GAAGD,EACJ,IAAA/J,EACA,UAAWoD,EAAAA,GACTyG,GAAoB,CAClB,MAAOtH,GAASZ,EAAQ,MACxB,SAAUe,GAAYf,EAAQ,SAC9B,UAAAgB,CAAA,CACD,CAAA,EAEH,MAAO,CACL,MAAOkG,EAAa,KAAK,MAAMjK,EAAS,KAAK,EAAIA,EAAS,MAC1D,OAAQiK,EAAa,KAAK,MAAMjK,EAAS,MAAM,EAAIA,EAAS,OAC5D,GAAG+J,CAAA,CACL,CAAA,CAGN"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const q=require("react/jsx-runtime"),e=require("react"),I=require("./Cropper.cjs"),T=require("./utils.cjs"),j=e.forwardRef((R,C)=>{const{src:i,alt:y="Crop image",onCropComplete:s,onCropAreaChange:t,cropOptions:r={},crossOrigin:S="anonymous",rotation:u=0,shape:f="rectangle",...w}=R,[g,d]=e.useState({x:0,y:0}),p=e.useRef(null),c=e.useRef(null),l=e.useCallback(async(h,o)=>{if(t?.(h,o),!!s){if(c.current){const a=c.current;if(a.x===o.x&&a.y===o.y&&a.width===o.width&&a.height===o.height)return}c.current=o,p.current&&window.clearTimeout(p.current),p.current=window.setTimeout(async()=>{try{if((r.type||"base64")==="blob"){const b=await T.getCroppedImg({imageSrc:i,pixelCrop:o,rotation:u,shape:f,format:r.format||"image/jpeg",quality:r.quality??.92,flip:r.flip,type:"blob"});s(b)}else{const b=await T.getCroppedImg({imageSrc:i,pixelCrop:o,rotation:u,shape:f,format:r.format||"image/jpeg",quality:r.quality??.92,flip:r.flip,type:"base64"});s(b)}}catch(a){console.error("Error creating cropped image:",a)}},300)}},[i,u,f,r,s,t]);return e.useEffect(()=>()=>{p.current&&window.clearTimeout(p.current)},[]),q.jsxs(I.Root,{ref:C,...w,crop:g,rotation:u,shape:f,onCropChange:d,onCropAreaChange:l,children:[q.jsx(I.Image,{src:i,alt:y,crossOrigin:S}),q.jsx(I.Area,{})]})});j.displayName="CropperTool";function v(R){const{imageSrc:C,initialCrop:i,initialZoom:y=1,initialRotation:s=0,cropOptions:t,type:r="base64"}=R,[S,u]=e.useState(i||{x:0,y:0}),[f,w]=e.useState(y),[g,d]=e.useState(s),[p,c]=e.useState(null),l=e.useRef(null),h=e.useRef(null),o=e.useCallback(async(b,m)=>{if(h.current){const n=h.current;if(n.x===m.x&&n.y===m.y&&n.width===m.width&&n.height===m.height)return}h.current=m,l.current&&window.clearTimeout(l.current),l.current=window.setTimeout(async()=>{try{if(r==="blob"){const n=await T.getCroppedImg({imageSrc:C,pixelCrop:m,rotation:g,shape:t?.shape,format:t?.format,quality:t?.quality,flip:t?.flip,type:"blob"});c(n)}else{const n=await T.getCroppedImg({imageSrc:C,pixelCrop:m,rotation:g,shape:t?.shape,format:t?.format,quality:t?.quality,flip:t?.flip,type:"base64"});c(n)}}catch(n){console.error("Error creating cropped image:",n)}},300)},[C,g,t,r]);e.useEffect(()=>()=>{l.current&&window.clearTimeout(l.current)},[]);const a=e.useCallback(()=>{u(i||{x:0,y:0}),w(y),d(s),c(null)},[i,y,s]);return{crop:S,zoom:f,rotation:g,croppedImage:p,setCrop:u,setZoom:w,setRotation:d,setCroppedImage:c,handleCropAreaChange:o,reset:a}}exports.CropperTool=j;exports.useCropperTool=v;
|
|
2
|
+
//# sourceMappingURL=CropperTool.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CropperTool.cjs","sources":["../../../../src/components/Cropper/CropperTool.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n Cropper,\n CropperImage,\n CropperArea,\n type CropperProps,\n type CropperPoint,\n type CropperAreaData,\n} from \"./Cropper\";\nimport { getCroppedImg, type CroppedImageOptions } from \"./utils\";\n\nexport interface CropperToolProps extends Omit<CropperProps, \"onCropComplete\"> {\n /**\n * Image source URL\n */\n src: string;\n /**\n * Alt text for the image\n */\n alt?: string;\n /**\n * Callback when crop is completed with the cropped image as base64 or Blob\n */\n onCropComplete?: (croppedImage: string | Blob) => void;\n /**\n * Callback when crop area changes (for real-time updates)\n */\n onCropAreaChange?: (\n croppedArea: CropperAreaData,\n croppedAreaPixels: CropperAreaData,\n ) => void;\n /**\n * Options for the cropped image output\n */\n cropOptions?: Pick<\n CroppedImageOptions,\n \"format\" | \"quality\" | \"flip\" | \"type\"\n >;\n /**\n * Cross-origin setting for the image\n */\n crossOrigin?: \"anonymous\" | \"use-credentials\";\n}\n\n/**\n * A higher-level Cropper component that handles image cropping automatically\n * and returns the cropped image as base64 data URL or Blob.\n *\n * @example\n * ```tsx\n * // Get base64 output (default)\n * <CropperTool\n * src=\"https://example.com/image.jpg\"\n * aspectRatio={1}\n * shape=\"circle\"\n * onCropComplete={(base64) => {\n * console.log('Cropped image:', base64);\n * }}\n * />\n *\n * // Get Blob output\n * <CropperTool\n * src=\"https://example.com/image.jpg\"\n * aspectRatio={1}\n * shape=\"circle\"\n * cropOptions={{ type: 'blob' }}\n * onCropComplete={(blob) => {\n * console.log('Cropped image blob:', blob);\n * }}\n * />\n * ```\n */\nexport const CropperTool = React.forwardRef<HTMLDivElement, CropperToolProps>(\n (props, ref) => {\n const {\n src,\n alt = \"Crop image\",\n onCropComplete,\n onCropAreaChange,\n cropOptions = {},\n crossOrigin = \"anonymous\",\n rotation = 0,\n shape = \"rectangle\",\n ...cropperProps\n } = props;\n\n // State to manage crop position\n const [crop, setCrop] = React.useState<CropperPoint>({ x: 0, y: 0 });\n\n // Debounce timer ref\n const debounceTimerRef = React.useRef<number | null>(null);\n // Store previous crop area to compare\n const prevCropAreaRef = React.useRef<CropperAreaData | null>(null);\n\n const handleCropAreaChange = React.useCallback(\n async (\n _croppedArea: CropperAreaData,\n croppedAreaPixels: CropperAreaData,\n ) => {\n // Call the user's onCropAreaChange if provided\n onCropAreaChange?.(_croppedArea, croppedAreaPixels);\n\n if (!onCropComplete) return;\n\n // Check if crop area actually changed\n if (prevCropAreaRef.current) {\n const prev = prevCropAreaRef.current;\n const isSame =\n prev.x === croppedAreaPixels.x &&\n prev.y === croppedAreaPixels.y &&\n prev.width === croppedAreaPixels.width &&\n prev.height === croppedAreaPixels.height;\n\n if (isSame) {\n return; // Don't regenerate if nothing changed\n }\n }\n\n // Update the ref\n prevCropAreaRef.current = croppedAreaPixels;\n\n // Clear previous timer\n if (debounceTimerRef.current) {\n window.clearTimeout(debounceTimerRef.current);\n }\n\n // Debounce the crop generation\n debounceTimerRef.current = window.setTimeout(async () => {\n try {\n const outputType = cropOptions.type || \"base64\";\n\n if (outputType === \"blob\") {\n const croppedBlob = await getCroppedImg({\n imageSrc: src,\n pixelCrop: croppedAreaPixels,\n rotation,\n shape,\n format: cropOptions.format || \"image/jpeg\",\n quality: cropOptions.quality ?? 0.92,\n flip: cropOptions.flip,\n type: \"blob\",\n });\n onCropComplete(croppedBlob);\n } else {\n const croppedImageBase64 = await getCroppedImg({\n imageSrc: src,\n pixelCrop: croppedAreaPixels,\n rotation,\n shape,\n format: cropOptions.format || \"image/jpeg\",\n quality: cropOptions.quality ?? 0.92,\n flip: cropOptions.flip,\n type: \"base64\",\n });\n onCropComplete(croppedImageBase64);\n }\n } catch (error) {\n console.error(\"Error creating cropped image:\", error);\n }\n }, 300); // 300ms debounce delay\n },\n [src, rotation, shape, cropOptions, onCropComplete, onCropAreaChange],\n );\n\n // Cleanup debounce timer on unmount\n React.useEffect(() => {\n return () => {\n if (debounceTimerRef.current) {\n window.clearTimeout(debounceTimerRef.current);\n }\n };\n }, []);\n\n return (\n <Cropper\n ref={ref}\n {...cropperProps}\n crop={crop}\n rotation={rotation}\n shape={shape}\n onCropChange={setCrop}\n onCropAreaChange={handleCropAreaChange}\n >\n <CropperImage src={src} alt={alt} crossOrigin={crossOrigin} />\n <CropperArea />\n </Cropper>\n );\n },\n);\n\nCropperTool.displayName = \"CropperTool\";\n\nexport interface UseCropperToolOptions {\n /**\n * Image source URL\n */\n imageSrc: string;\n /**\n * Initial crop position\n */\n initialCrop?: CropperPoint;\n /**\n * Initial zoom level\n */\n initialZoom?: number;\n /**\n * Initial rotation angle\n */\n initialRotation?: number;\n /**\n * Crop options (shape, format, quality, type, etc.)\n */\n cropOptions?: Omit<CroppedImageOptions, \"imageSrc\" | \"pixelCrop\">;\n /**\n * Output type: 'base64' for data URL (default) or 'blob' for Blob object\n */\n type?: \"base64\" | \"blob\";\n}\n\n/**\n * Hook to easily handle cropping logic in your components.\n * Automatically handles crop area changes and generates cropped images.\n *\n * @example\n * ```tsx\n * // Get base64 output (default)\n * const {\n * crop,\n * zoom,\n * rotation,\n * setCrop,\n * setZoom,\n * setRotation,\n * croppedImage,\n * handleCropAreaChange,\n * reset\n * } = useCropperTool({\n * imageSrc: \"https://example.com/image.jpg\",\n * cropOptions: { shape: \"circle\", format: \"image/png\" }\n * });\n *\n * // Get Blob output\n * const {\n * croppedImage, // This will be a Blob\n * ...rest\n * } = useCropperTool({\n * imageSrc: \"https://example.com/image.jpg\",\n * type: \"blob\",\n * cropOptions: { shape: \"circle\", format: \"image/png\" }\n * });\n *\n * return (\n * <div>\n * <Cropper\n * crop={crop}\n * zoom={zoom}\n * rotation={rotation}\n * onCropChange={setCrop}\n * onZoomChange={setZoom}\n * onCropAreaChange={handleCropAreaChange}\n * >\n * <CropperImage src={imageSrc} />\n * <CropperArea />\n * </Cropper>\n * {croppedImage && typeof croppedImage === 'string' && (\n * <img src={croppedImage} alt=\"Cropped\" />\n * )}\n * </div>\n * );\n * ```\n */\nexport function useCropperTool(options: UseCropperToolOptions) {\n const {\n imageSrc,\n initialCrop,\n initialZoom = 1,\n initialRotation = 0,\n cropOptions,\n type = \"base64\",\n } = options;\n\n const [crop, setCrop] = React.useState<CropperPoint>(\n initialCrop || { x: 0, y: 0 },\n );\n const [zoom, setZoom] = React.useState(initialZoom);\n const [rotation, setRotation] = React.useState(initialRotation);\n const [croppedImage, setCroppedImage] = React.useState<string | Blob | null>(\n null,\n );\n\n // Debounce timer ref\n const debounceTimerRef = React.useRef<number | null>(null);\n\n // Store previous crop area to compare\n const prevCropAreaRef = React.useRef<CropperAreaData | null>(null);\n\n const handleCropAreaChange = React.useCallback(\n async (\n _croppedArea: CropperAreaData,\n croppedAreaPixels: CropperAreaData,\n ) => {\n // Check if crop area actually changed\n if (prevCropAreaRef.current) {\n const prev = prevCropAreaRef.current;\n const isSame =\n prev.x === croppedAreaPixels.x &&\n prev.y === croppedAreaPixels.y &&\n prev.width === croppedAreaPixels.width &&\n prev.height === croppedAreaPixels.height;\n\n if (isSame) {\n return; // Don't regenerate if nothing changed\n }\n }\n\n // Update the ref\n prevCropAreaRef.current = croppedAreaPixels;\n\n // Clear previous timer\n if (debounceTimerRef.current) {\n window.clearTimeout(debounceTimerRef.current);\n }\n\n // Set new timer to debounce the crop generation\n debounceTimerRef.current = window.setTimeout(async () => {\n try {\n if (type === \"blob\") {\n const blob = await getCroppedImg({\n imageSrc,\n pixelCrop: croppedAreaPixels,\n rotation,\n shape: cropOptions?.shape,\n format: cropOptions?.format,\n quality: cropOptions?.quality,\n flip: cropOptions?.flip,\n type: \"blob\",\n });\n setCroppedImage(blob);\n } else {\n const base64 = await getCroppedImg({\n imageSrc,\n pixelCrop: croppedAreaPixels,\n rotation,\n shape: cropOptions?.shape,\n format: cropOptions?.format,\n quality: cropOptions?.quality,\n flip: cropOptions?.flip,\n type: \"base64\",\n });\n setCroppedImage(base64);\n }\n } catch (error) {\n console.error(\"Error creating cropped image:\", error);\n }\n }, 300); // 300ms debounce delay\n },\n [imageSrc, rotation, cropOptions, type],\n );\n\n // Cleanup debounce timer on unmount\n React.useEffect(() => {\n return () => {\n if (debounceTimerRef.current) {\n window.clearTimeout(debounceTimerRef.current);\n }\n };\n }, []);\n\n const reset = React.useCallback(() => {\n setCrop(initialCrop || { x: 0, y: 0 });\n setZoom(initialZoom);\n setRotation(initialRotation);\n setCroppedImage(null);\n }, [initialCrop, initialZoom, initialRotation]);\n\n return {\n crop,\n zoom,\n rotation,\n croppedImage,\n setCrop,\n setZoom,\n setRotation,\n setCroppedImage,\n handleCropAreaChange,\n reset,\n };\n}\n"],"names":["CropperTool","React","props","ref","src","alt","onCropComplete","onCropAreaChange","cropOptions","crossOrigin","rotation","shape","cropperProps","crop","setCrop","debounceTimerRef","prevCropAreaRef","handleCropAreaChange","_croppedArea","croppedAreaPixels","prev","croppedBlob","getCroppedImg","croppedImageBase64","error","jsxs","Cropper","jsx","CropperImage","CropperArea","useCropperTool","options","imageSrc","initialCrop","initialZoom","initialRotation","type","zoom","setZoom","setRotation","croppedImage","setCroppedImage","blob","base64","reset"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});async function S(o){const{imageSrc:e,pixelCrop:t,rotation:a=0,shape:r="rectangle",format:c="image/png",quality:h=.92,flip:d={},type:R="base64"}=o;let n;typeof e=="string"?n=await T(e):n=e;const m=E(a),x=Math.abs(Math.sin(m)),y=Math.abs(Math.cos(m)),u=n.width*y+n.height*x,w=n.width*x+n.height*y,g=document.createElement("canvas"),l=g.getContext("2d");if(!l)throw new Error("Failed to get canvas 2D context");if(g.width=u,g.height=w,l.translate(u/2,w/2),l.rotate(m),d.horizontal||d.vertical){const M=d.horizontal?-1:1,f=d.vertical?-1:1;l.scale(M,f)}l.drawImage(n,-n.width/2,-n.height/2,n.width,n.height);const i=document.createElement("canvas"),s=i.getContext("2d",{alpha:!0});if(!s)throw new Error("Failed to get canvas 2D context");i.width=t.width,i.height=t.height,s.clearRect(0,0,i.width,i.height);const v=Math.max(0,t.x),C=Math.max(0,t.y),b=Math.min(t.width-Math.max(0,-t.x),u-v),p=Math.min(t.height-Math.max(0,-t.y),w-C),B=Math.max(0,-t.x),P=Math.max(0,-t.y);return b>0&&p>0&&s.drawImage(g,v,C,b,p,B,P,b,p),r==="circle"&&(s.globalCompositeOperation="destination-in",s.beginPath(),s.arc(i.width/2,i.height/2,Math.min(i.width,i.height)/2,0,Math.PI*2),s.fill()),R==="blob"?new Promise((M,f)=>{i.toBlob(I=>{I?M(I):f(new Error("Failed to create blob from canvas"))},c,h)}):i.toDataURL(c,h)}function T(o){return new Promise((e,t)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>e(a),a.onerror=r=>t(new Error(`Failed to load image: ${r}`)),a.src=o})}function E(o){return o*Math.PI/180}function z(o,e,t){const a=E(t),r=Math.cos(a),c=Math.sin(a);return{width:Math.abs(r*o)+Math.abs(c*e),height:Math.abs(c*o)+Math.abs(r*e)}}function j(o,e="cropped-image.jpg"){const t=document.createElement("a");t.href=o,t.download=e,document.body.appendChild(t),t.click(),document.body.removeChild(t)}function F(o){const e=o.split(","),t=e[0]?.match(/:(.*?);/),a=t?t[1]:"image/jpeg",r=atob(e[1]??"");let c=r.length;const h=new Uint8Array(c);for(;c--;)h[c]=r.charCodeAt(c);return new Blob([h],{type:a})}function A(o,e){const t=F(o);return new File([t],e,{type:t.type})}exports.base64ToBlob=F;exports.base64ToFile=A;exports.downloadImage=j;exports.getCroppedImg=S;exports.rotateSize=z;
|
|
2
|
+
//# sourceMappingURL=utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.cjs","sources":["../../../../src/components/Cropper/utils.ts"],"sourcesContent":["/**\n * Utility functions for Cropper component\n */\n\nexport interface CroppedImageOptions {\n /**\n * The source image URL or HTMLImageElement\n */\n imageSrc: string | HTMLImageElement;\n /**\n * Pixel coordinates of the cropped area\n */\n pixelCrop: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n /**\n * Rotation angle in degrees\n */\n rotation?: number;\n /**\n * Shape of the crop area\n */\n shape?: \"rectangle\" | \"circle\";\n /**\n * Output image format (default: 'image/png')\n */\n format?: \"image/jpeg\" | \"image/png\" | \"image/webp\";\n /**\n * Quality of the output image (0-1, default: 0.92)\n */\n quality?: number;\n /**\n * Flip the image horizontally\n */\n flip?: {\n horizontal?: boolean;\n vertical?: boolean;\n };\n /**\n * Output type: 'base64' (data URL) or 'blob' (Blob object)\n */\n type?: \"base64\" | \"blob\";\n}\n\n/**\n * Creates a cropped image from the given parameters and returns it as a base64 data URL or Blob\n *\n * @param options - Options for creating the cropped image\n * @returns Promise that resolves to a base64 data URL string or Blob based on the type option\n *\n * @example\n * ```tsx\n * // Get base64 data URL (default)\n * const croppedImageBase64 = await getCroppedImg({\n * imageSrc: 'https://example.com/image.jpg',\n * pixelCrop: { x: 100, y: 100, width: 200, height: 200 },\n * rotation: 45,\n * shape: 'circle',\n * format: 'image/png',\n * quality: 0.95\n * });\n *\n * // Get Blob\n * const croppedImageBlob = await getCroppedImg({\n * imageSrc: 'https://example.com/image.jpg',\n * pixelCrop: { x: 100, y: 100, width: 200, height: 200 },\n * type: 'blob'\n * });\n * ```\n */\nexport async function getCroppedImg(\n options: CroppedImageOptions & { type: \"blob\" },\n): Promise<Blob>;\nexport async function getCroppedImg(\n options: CroppedImageOptions & { type?: \"base64\" },\n): Promise<string>;\nexport async function getCroppedImg(\n options: CroppedImageOptions,\n): Promise<string | Blob> {\n const {\n imageSrc,\n pixelCrop,\n rotation = 0,\n shape = \"rectangle\",\n format = \"image/png\",\n quality = 0.92,\n flip = {},\n type = \"base64\",\n } = options;\n\n // Load image if URL is provided\n let image: HTMLImageElement;\n if (typeof imageSrc === \"string\") {\n image = await loadImage(imageSrc);\n } else {\n image = imageSrc;\n }\n\n const rotRad = getRadianAngle(rotation);\n const sin = Math.abs(Math.sin(rotRad));\n const cos = Math.abs(Math.cos(rotRad));\n\n // Calculate bounding box of rotated image\n const bBoxWidth = image.width * cos + image.height * sin;\n const bBoxHeight = image.width * sin + image.height * cos;\n\n // Step 1: Create a canvas for the rotated full image\n const tempCanvas = document.createElement(\"canvas\");\n const tempCtx = tempCanvas.getContext(\"2d\");\n\n if (!tempCtx) {\n throw new Error(\"Failed to get canvas 2D context\");\n }\n\n // Set temp canvas to bounding box size\n tempCanvas.width = bBoxWidth;\n tempCanvas.height = bBoxHeight;\n\n // Translate to center\n tempCtx.translate(bBoxWidth / 2, bBoxHeight / 2);\n\n // Rotate\n tempCtx.rotate(rotRad);\n\n // Apply flip if needed\n if (flip.horizontal || flip.vertical) {\n const scaleX = flip.horizontal ? -1 : 1;\n const scaleY = flip.vertical ? -1 : 1;\n tempCtx.scale(scaleX, scaleY);\n }\n\n // Draw image centered\n tempCtx.drawImage(\n image,\n -image.width / 2,\n -image.height / 2,\n image.width,\n image.height,\n );\n\n // Step 2: Create output canvas and crop from temp canvas\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\", { alpha: true });\n\n if (!ctx) {\n throw new Error(\"Failed to get canvas 2D context\");\n }\n\n canvas.width = pixelCrop.width;\n canvas.height = pixelCrop.height;\n\n // Clear canvas to ensure transparency (important for PNG output)\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n // Handle overflow: calculate the valid area to draw\n // When pixelCrop.x or y is negative, it means the crop area extends beyond the image\n const sourceX = Math.max(0, pixelCrop.x);\n const sourceY = Math.max(0, pixelCrop.y);\n\n // Calculate how much of the crop area is actually within the image bounds\n const sourceWidth = Math.min(\n pixelCrop.width - Math.max(0, -pixelCrop.x), // Reduce width if crop starts before image\n bBoxWidth - sourceX, // Don't exceed image right edge\n );\n const sourceHeight = Math.min(\n pixelCrop.height - Math.max(0, -pixelCrop.y), // Reduce height if crop starts before image\n bBoxHeight - sourceY, // Don't exceed image bottom edge\n );\n\n // Calculate where to place the cropped portion on the output canvas\n // If crop area extends beyond image (negative x/y), offset the destination\n const destX = Math.max(0, -pixelCrop.x);\n const destY = Math.max(0, -pixelCrop.y);\n\n // Only draw if there's a valid area to draw\n if (sourceWidth > 0 && sourceHeight > 0) {\n ctx.drawImage(\n tempCanvas,\n sourceX,\n sourceY,\n sourceWidth,\n sourceHeight,\n destX,\n destY,\n sourceWidth,\n sourceHeight,\n );\n }\n\n // Apply circular mask if shape is circle\n if (shape === \"circle\") {\n ctx.globalCompositeOperation = \"destination-in\";\n ctx.beginPath();\n ctx.arc(\n canvas.width / 2,\n canvas.height / 2,\n Math.min(canvas.width, canvas.height) / 2,\n 0,\n Math.PI * 2,\n );\n ctx.fill();\n }\n\n // Return as blob or base64 based on type\n if (type === \"blob\") {\n return new Promise<Blob>((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new Error(\"Failed to create blob from canvas\"));\n }\n },\n format,\n quality,\n );\n });\n }\n\n // Convert to base64\n return canvas.toDataURL(format, quality);\n}\n\n/**\n * Load an image from URL\n */\nfunction loadImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n\n image.onload = () => resolve(image);\n image.onerror = (error) =>\n reject(new Error(`Failed to load image: ${error}`));\n\n image.src = url;\n });\n}\n\n/**\n * Convert degrees to radians\n */\nfunction getRadianAngle(degreeValue: number): number {\n return (degreeValue * Math.PI) / 180;\n}\n\n/**\n * Calculate the rotated size of a rectangle\n *\n * @param width - Original width\n * @param height - Original height\n * @param rotation - Rotation angle in degrees\n * @returns Rotated size dimensions\n */\nexport function rotateSize(\n width: number,\n height: number,\n rotation: number,\n): { width: number; height: number } {\n const rotRad = getRadianAngle(rotation);\n const cosRot = Math.cos(rotRad);\n const sinRot = Math.sin(rotRad);\n\n return {\n width: Math.abs(cosRot * width) + Math.abs(sinRot * height),\n height: Math.abs(sinRot * width) + Math.abs(cosRot * height),\n };\n}\n\n/**\n * Download a base64 image\n *\n * @param base64Data - Base64 data URL\n * @param filename - Output filename (default: 'cropped-image.jpg')\n *\n * @example\n * ```tsx\n * const croppedImage = await getCroppedImg({ ... });\n * downloadImage(croppedImage, 'my-cropped-image.png');\n * ```\n */\nexport function downloadImage(\n base64Data: string,\n filename: string = \"cropped-image.jpg\",\n): void {\n const link = document.createElement(\"a\");\n link.href = base64Data;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n}\n\n/**\n * Convert base64 data URL to Blob\n *\n * @param base64Data - Base64 data URL\n * @returns Blob object\n *\n * @example\n * ```tsx\n * const croppedImage = await getCroppedImg({ ... });\n * const blob = base64ToBlob(croppedImage);\n * ```\n */\nexport function base64ToBlob(base64Data: string): Blob {\n const arr = base64Data.split(\",\");\n const mimeMatch = arr[0]?.match(/:(.*?);/);\n const mime = mimeMatch ? mimeMatch[1] : \"image/jpeg\";\n const bstr = atob(arr[1] ?? \"\");\n let n = bstr.length;\n const u8arr = new Uint8Array(n);\n\n while (n--) {\n u8arr[n] = bstr.charCodeAt(n);\n }\n\n return new Blob([u8arr], { type: mime });\n}\n\n/**\n * Convert base64 data URL to File\n *\n * @param base64Data - Base64 data URL\n * @param filename - Output filename\n * @returns File object\n *\n * @example\n * ```tsx\n * const croppedImage = await getCroppedImg({ ... });\n * const file = base64ToFile(croppedImage, 'cropped-image.jpg');\n * ```\n */\nexport function base64ToFile(base64Data: string, filename: string): File {\n const blob = base64ToBlob(base64Data);\n return new File([blob], filename, { type: blob.type });\n}\n"],"names":["getCroppedImg","options","imageSrc","pixelCrop","rotation","shape","format","quality","flip","type","image","loadImage","rotRad","getRadianAngle","sin","cos","bBoxWidth","bBoxHeight","tempCanvas","tempCtx","scaleX","scaleY","canvas","ctx","sourceX","sourceY","sourceWidth","sourceHeight","destX","destY","resolve","reject","blob","url","error","degreeValue","rotateSize","width","height","cosRot","sinRot","downloadImage","base64Data","filename","link","base64ToBlob","arr","mimeMatch","mime","bstr","n","u8arr","base64ToFile"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),ge=require("react"),me=require("@dsui/ui/components/calendar"),T=require("@dsui/ui/components/popover"),m=require("@dsui/ui/components/drawer"),v=require("@dsui/ui/index"),pe=require("../Input/Input.cjs"),ve=require("../Button/Button.cjs"),we=require("./TimePicker.cjs"),be=require("lucide-react"),w=require("react-device-detect"),b=require("date-fns"),U=require("date-fns/locale"),K=require("../../constants/common.cjs");function he(a){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(a){for(const t in a)if(t!=="default"){const h=Object.getOwnPropertyDescriptor(a,t);Object.defineProperty(n,t,h.get?h:{enumerable:!0,get:()=>a[t]})}}return n.default=a,Object.freeze(n)}const j=he(ge);function xe(a,n=K.DATE_FORMAT,t){return a?b.format(a,n,t?{locale:t}:void 0):""}const q=(a,n=K.DATE_FORMAT)=>{const t=b.parse(a,n,new Date);return b.isValid(t)?t:void 0};function ye(a){return a.replace(/dd|MM|yyyy/g,n=>{switch(n){case"dd":case"MM":return"99";case"yyyy":return"9999";default:return n}}).replace(/d|M|y/g,n=>{switch(n){case"d":case"M":return"9";case"y":return"9";default:return n}})}function De({value:a,onChange:n,onSelect:t,calendarClassName:h,side:$="bottom",align:G="end",format:p="dd/MM/yyyy",language:J="vi",mask:z,closeOnSelect:Q=!1,calendarConfig:P,desktopMode:O="popover",mobileMode:W="drawer",showOutsideDays:X=!0,children:S,showTime:u=!1,timeFormat:x="HH:mm",hideDate:F=!1,numberOfMonths:Y=1,variant:Z="default",color:_="primary",timePickerMode:ee="wheel",hourInterval:re=1,minuteInterval:te=1,secondInterval:ne=1,disabledTimes:se,disabledTimeRanges:ae,showNowButton:oe=!1,nowButtonLabel:ie="Now",timePickerLabel:ce,...c}){let d,k;typeof p=="string"?(d=p,k=p):(d=p.input,k=p.output);let N;z===!0?N=ye(d):typeof z=="string"&&(N=z);const A=a?q(a,d):void 0,[I,y]=j.useState(!1),[o,l]=j.useState(A),[le,D]=j.useState(A),[C,f]=j.useState(a||""),H=P?.locale?P?.locale:J==="en"?U.enUS:U.vi,R=w.isMobile?W:O,i=e=>{if(!e)return"";let r=xe(e,k,H);return u&&(r+=` ${b.format(e,x)}`),r},ue=e=>{l(e),f(i(e)),t?.(e,i(e))},de=e=>{if(!e){f(""),l(void 0),t?.(void 0,void 0);return}f(e);const r=q(e,d);r?(l(r),D(r),t?.(r,i(r))):(l(void 0),t?.(void 0,void 0))},fe=(e,r,M)=>{if(!M){n?.(e,r,void 0);return}const g=new Date(o||new Date);g.setHours(M.getHours(),M.getMinutes(),M.getSeconds(),0),l(g),f(i(g)),t?.(g,i(g)),n?.(e,i(g),g)},V=S?S({value:C,date:o,onSelect:ue,onChange:de}):s.jsxs(ve.default,{variant:"ghost",className:"!p-1 !leading-0 h-auto rounded hover:bg-accent transition-colors",size:c.size,children:[s.jsx(be.CalendarIcon,{className:v.cn({"size-3":c.size==="xs"||c.size==="sm","size-3.5":!c.size||c.size==="normal","size-4":c.size==="lg"||c.size==="xl"})}),s.jsx("span",{className:"sr-only",children:"Select date"})]}),L=s.jsxs("div",{className:v.cn("flex items-stretch mx-auto w-full",u&&!F?"gap-0 md:max-w-lg":"",w.isMobile?"max-w-md md:max-w-md lg:max-w-lg":""),children:[!F&&s.jsx(me.Calendar,{...P,mode:"single",selected:o,captionLayout:"dropdown",month:le,onMonthChange:D,numberOfMonths:w.isMobile?1:Y||1,variant:Z,color:_,onSelect:e=>{let r=e;e&&o&&u&&(r=new Date(e),r.setHours(o.getHours(),o.getMinutes(),o.getSeconds(),o.getMilliseconds())),l(r),f(i(r)),t?.(r,i(r)),Q&&!u&&y(!1)},locale:H,formatters:{formatMonthDropdown:e=>e.toLocaleString(H.code,{month:"short"})},showOutsideDays:X,className:v.cn("my-auto bg-transparent mx-auto",{"[--cell-size:clamp(0px,calc(100vw/7.5),52px)] mb-8 bg-transparent":w.isMobile&&!u||O==="drawer","[--cell-size:clamp(0px,calc(100vw/7.5),34px)]":!w.isMobile&&O!=="drawer","w-full":R==="drawer"&&u},h)}),u&&s.jsx("div",{className:"border-l border-border",children:s.jsx(we.TimePicker,{value:o?b.format(o,x):void 0,format:x,onChange:fe,showHours:!0,showMinutes:!0,showSeconds:x==="HH:mm:ss",mode:ee,hourInterval:re,minuteInterval:te,secondInterval:ne,disabledTimes:se,disabledTimeRanges:ae,showNowButton:oe,nowButtonLabel:ie,timeLabel:ce,standalone:!1,color:_})})]}),B=s.jsxs(T.Popover,{open:I,onOpenChange:y,children:[s.jsx(T.PopoverTrigger,{asChild:!0,disabled:c.disabled,children:V}),s.jsx(T.PopoverContent,{className:v.cn("w-auto overflow-hidden p-0","backdrop-blur bg-background/50"),side:$,align:G,children:L})]}),E=s.jsxs(m.Drawer,{open:I,onOpenChange:y,children:[s.jsx(m.DrawerTrigger,{asChild:!0,children:V}),s.jsxs(m.DrawerContent,{className:v.cn("w-auto overflow-hidden p-0","backdrop-blur bg-background"),children:[s.jsxs(m.DrawerHeader,{className:"sr-only",children:[s.jsx(m.DrawerTitle,{children:"Select date"}),s.jsx(m.DrawerDescription,{children:"Set date"})]}),L]})]});return S?R==="drawer"?E:B:s.jsx(pe.default,{...c,clearable:!0,value:C,mask:N,onChange:e=>{f(e.target.value);const r=q(e.target.value,d);r?(l(r),D(r),t?.(r,i(r)),n?.(e,i(r),r)):(t?.(void 0,void 0),n?.(e,void 0,void 0))},onBlur:()=>{q(C,d)||(f(""),l(void 0),D(void 0),t?.(void 0,void 0))},onKeyDown:e=>{e.key==="ArrowDown"&&(e.preventDefault(),y(!0))},suffixIcon:R==="drawer"?E:B})}exports.DatePicker=De;
|
|
2
|
+
//# sourceMappingURL=DatePicker.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.cjs","sources":["../../../../src/components/DatePicker/DatePicker.tsx"],"sourcesContent":["import * as React from \"react\";\nimport {\n CalendarDayButton as SCalendarDayButton,\n type CalendarDayButtonProps as SCalendarDayButtonProps,\n Calendar,\n type CalendarProps,\n type CalendarColor,\n} from \"@dsui/ui/components/calendar\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@dsui/ui/components/popover\";\nimport {\n Drawer,\n DrawerContent,\n DrawerDescription,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@dsui/ui/components/drawer\";\nimport { cn } from \"@dsui/ui/index\";\nimport Input, { type InputProps } from \"../Input/Input\";\nimport Button from \"../Button/Button\";\nimport {\n TimePicker,\n type TimePickerMode,\n type DisabledTimeRange,\n} from \"./TimePicker\";\nimport { CalendarIcon } from \"lucide-react\";\nimport type { VariantProps } from \"class-variance-authority\";\nimport { isMobile } from \"react-device-detect\";\nimport { format as dfFormat, parse, isValid, type Locale } from \"date-fns\";\nimport { vi, enUS } from \"date-fns/locale\";\nimport { DATE_FORMAT } from \"@/constants/common\";\n\nfunction formatDate(\n date: Date | undefined,\n outputFormat: string = DATE_FORMAT,\n locale?: Locale,\n) {\n if (!date) return \"\";\n\n return dfFormat(date, outputFormat, locale ? { locale } : undefined);\n}\n\nconst parseDate = (\n str: string,\n inputFormat: string = DATE_FORMAT,\n): Date | undefined => {\n const date = parse(str, inputFormat, new Date());\n return isValid(date) ? date : undefined;\n};\n\nfunction generateMaskFromFormat(format: string): string {\n return format\n .replace(/dd|MM|yyyy/g, (match) => {\n switch (match) {\n case \"dd\":\n case \"MM\":\n return \"99\";\n case \"yyyy\":\n return \"9999\";\n default:\n return match;\n }\n })\n .replace(/d|M|y/g, (match) => {\n switch (match) {\n case \"d\":\n case \"M\":\n return \"9\";\n case \"y\":\n return \"9\";\n default:\n return match;\n }\n });\n}\n\nexport type FormatType = string | { input: string; output: string };\n\nexport type DatePickerRenderProps = {\n value: string;\n date?: Date;\n onSelect: (date?: Date) => void;\n onChange: (text?: string) => void;\n};\n\nexport type DatePickerProps = Omit<\n InputProps,\n \"value\" | \"onChange\" | \"onSelect\" | \"mask\" | \"children\"\n> & {\n value?: string;\n onChange?: (\n event?: React.ChangeEvent<HTMLInputElement>,\n value?: string,\n date?: Date,\n ) => void;\n onSelect?: (date?: Date, value?: string) => void;\n calendarClassName?: string;\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n align?: \"start\" | \"center\" | \"end\";\n size?: VariantProps<typeof Input>[\"size\"];\n format?: FormatType;\n language?: \"vi\" | \"en\";\n mask?: boolean | string;\n closeOnSelect?: boolean;\n calendarConfig?: CalendarProps;\n desktopMode?: \"popover\" | \"drawer\";\n mobileMode?: \"popover\" | \"drawer\";\n showOutsideDays?: boolean;\n children?: (props: DatePickerRenderProps) => React.ReactNode;\n showTime?: boolean;\n timeFormat?: \"HH:mm\" | \"HH:mm:ss\";\n hideDate?: boolean;\n numberOfMonths?: number;\n variant?: \"default\" | \"rounded\";\n color?: CalendarColor;\n\n // TimePicker configuration options\n timePickerMode?: TimePickerMode; // Display mode: 'wheel' (default), 'select', 'compact'\n hourInterval?: number; // Hour interval (e.g., 1, 2, 3) - defaults to 1\n minuteInterval?: number; // Minute interval (e.g., 5, 10, 15, 30) - defaults to 1\n secondInterval?: number; // Second interval (e.g., 5, 10, 15, 30) - defaults to 1\n disabledTimes?: string[]; // Array of disabled times in \"HH:mm\" or \"HH:mm:ss\" format\n disabledTimeRanges?: DisabledTimeRange[]; // Array of disabled time ranges\n showNowButton?: boolean; // Show \"Now\" button to select current time\n nowButtonLabel?: string; // Label for \"Now\" button (defaults to \"Now\")\n timePickerLabel?:\n | boolean\n | { hours?: string; minutes?: string; seconds?: string };\n};\n\nexport function DatePicker({\n value,\n onChange,\n onSelect,\n calendarClassName,\n side = \"bottom\",\n align = \"end\",\n format = \"dd/MM/yyyy\",\n language = \"vi\",\n mask,\n closeOnSelect = false,\n calendarConfig,\n desktopMode = \"popover\",\n mobileMode = \"drawer\",\n showOutsideDays = true,\n children,\n showTime = false,\n timeFormat = \"HH:mm\",\n hideDate = false,\n numberOfMonths = 1,\n variant = \"default\",\n color = \"primary\",\n // TimePicker props\n timePickerMode = \"wheel\",\n hourInterval = 1,\n minuteInterval = 1,\n secondInterval = 1,\n disabledTimes,\n disabledTimeRanges,\n showNowButton = false,\n nowButtonLabel = \"Now\",\n timePickerLabel,\n ...props\n}: DatePickerProps) {\n let inputFormat: string;\n let outputFormat: string;\n if (typeof format === \"string\") {\n inputFormat = format;\n outputFormat = format;\n } else {\n inputFormat = format.input;\n outputFormat = format.output;\n }\n\n // Determine the mask to use\n let maskToUse: string | undefined;\n if (mask === true) {\n maskToUse = generateMaskFromFormat(inputFormat);\n } else if (typeof mask === \"string\") {\n maskToUse = mask;\n }\n // If mask is false or undefined, maskToUse remains undefined\n\n const initialDate = value ? parseDate(value, inputFormat) : undefined;\n\n const [open, setOpen] = React.useState(false);\n const [date, setDate] = React.useState<Date | undefined>(initialDate);\n const [month, setMonth] = React.useState<Date | undefined>(initialDate);\n const [inputValue, setInputValue] = React.useState(value || \"\");\n\n const _locale: Locale = calendarConfig?.locale\n ? (calendarConfig?.locale as Locale)\n : language === \"en\"\n ? enUS\n : vi;\n\n const mode = isMobile ? mobileMode : desktopMode;\n\n // Helper to format date-time based on showTime and timeFormat\n const formatDateTimeValue = (d: Date | undefined): string => {\n if (!d) return \"\";\n let result = formatDate(d, outputFormat, _locale);\n if (showTime) {\n result += ` ${dfFormat(d, timeFormat)}`;\n }\n return result;\n };\n\n // Helper functions for render props\n const handleSelectForRenderProp = (date?: Date) => {\n setDate(date);\n setInputValue(formatDateTimeValue(date));\n onSelect?.(date, formatDateTimeValue(date));\n };\n\n const handleChangeForRenderProp = (text?: string) => {\n if (!text) {\n setInputValue(\"\");\n setDate(undefined);\n onSelect?.(undefined, undefined);\n return;\n }\n setInputValue(text);\n const parsedDate = parseDate(text, inputFormat);\n if (parsedDate) {\n setDate(parsedDate);\n setMonth(parsedDate);\n onSelect?.(parsedDate, formatDateTimeValue(parsedDate));\n } else {\n setDate(undefined);\n onSelect?.(undefined, undefined);\n }\n };\n\n const handleTimeChange = (\n event?: React.ChangeEvent<HTMLInputElement>,\n value?: string,\n newDate?: Date,\n ) => {\n if (!newDate) {\n // Handle clear/invalid time\n onChange?.(event, value, undefined);\n return;\n }\n\n // Merge: keep date (year, month, day) from Calendar, take time (hours, minutes, seconds) from TimePicker\n const mergedDate = new Date(date || new Date());\n mergedDate.setHours(\n newDate.getHours(),\n newDate.getMinutes(),\n newDate.getSeconds(),\n 0,\n );\n\n setDate(mergedDate);\n setInputValue(formatDateTimeValue(mergedDate));\n onSelect?.(mergedDate, formatDateTimeValue(mergedDate));\n onChange?.(event, formatDateTimeValue(mergedDate), mergedDate);\n };\n\n // Determine trigger component\n const triggerComponent = children ? (\n children({\n value: inputValue,\n date,\n onSelect: handleSelectForRenderProp,\n onChange: handleChangeForRenderProp,\n })\n ) : (\n <Button\n variant=\"ghost\"\n className=\"!p-1 !leading-0 h-auto rounded hover:bg-accent transition-colors\"\n size={props.size}\n >\n <CalendarIcon\n className={cn({\n \"size-3\": props.size === \"xs\" || props.size === \"sm\",\n \"size-3.5\": !props.size || props.size === \"normal\",\n \"size-4\": props.size === \"lg\" || props.size === \"xl\",\n })}\n />\n <span className=\"sr-only\">Select date</span>\n </Button>\n );\n\n const calendarSelection = (\n <div\n className={cn(\n \"flex items-stretch mx-auto w-full\",\n showTime && !hideDate ? \"gap-0 md:max-w-lg\" : \"\",\n // mode === \"drawer\" ? \"mb-6\" : \"\",\n isMobile ? \"max-w-md md:max-w-md lg:max-w-lg\" : \"\",\n )}\n >\n {!hideDate && (\n <Calendar\n {...calendarConfig}\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n month={month}\n onMonthChange={setMonth}\n numberOfMonths={isMobile ? 1 : numberOfMonths || 1}\n variant={variant}\n color={color}\n onSelect={(selectedDate) => {\n // Preserve time from current date when selecting new date\n let newDate = selectedDate;\n if (selectedDate && date && showTime) {\n newDate = new Date(selectedDate);\n newDate.setHours(\n date.getHours(),\n date.getMinutes(),\n date.getSeconds(),\n date.getMilliseconds(),\n );\n }\n setDate(newDate);\n setInputValue(formatDateTimeValue(newDate));\n onSelect?.(newDate, formatDateTimeValue(newDate));\n if (closeOnSelect && !showTime) setOpen(false);\n }}\n locale={_locale}\n formatters={{\n formatMonthDropdown: (date) =>\n date.toLocaleString(_locale.code, { month: \"short\" }),\n }}\n showOutsideDays={showOutsideDays}\n className={cn(\n \"my-auto bg-transparent mx-auto\",\n {\n \"[--cell-size:clamp(0px,calc(100vw/7.5),52px)] mb-8 bg-transparent\":\n (isMobile && !showTime) || desktopMode === \"drawer\",\n \"[--cell-size:clamp(0px,calc(100vw/7.5),34px)]\":\n !isMobile && desktopMode !== \"drawer\",\n \"w-full\": mode === \"drawer\" && showTime,\n },\n calendarClassName,\n )}\n />\n )}\n {showTime && (\n <div className=\"border-l border-border\">\n <TimePicker\n value={date ? dfFormat(date, timeFormat) : undefined}\n format={timeFormat}\n onChange={handleTimeChange}\n showHours\n showMinutes\n showSeconds={timeFormat === \"HH:mm:ss\"}\n mode={timePickerMode}\n hourInterval={hourInterval}\n minuteInterval={minuteInterval}\n secondInterval={secondInterval}\n disabledTimes={disabledTimes}\n disabledTimeRanges={disabledTimeRanges}\n showNowButton={showNowButton}\n nowButtonLabel={nowButtonLabel}\n timeLabel={timePickerLabel}\n standalone={false}\n color={color}\n />\n </div>\n )}\n </div>\n );\n\n const popPicker = (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild disabled={props.disabled}>\n {triggerComponent}\n </PopoverTrigger>\n <PopoverContent\n className={cn(\n \"w-auto overflow-hidden p-0\",\n \"backdrop-blur bg-background/50\",\n )}\n side={side}\n align={align}\n >\n {calendarSelection}\n </PopoverContent>\n </Popover>\n );\n\n const drawPicker = (\n <Drawer open={open} onOpenChange={setOpen}>\n <DrawerTrigger asChild>{triggerComponent}</DrawerTrigger>\n <DrawerContent\n className={cn(\n \"w-auto overflow-hidden p-0\",\n \"backdrop-blur bg-background\",\n )}\n >\n <DrawerHeader className=\"sr-only\">\n <DrawerTitle>Select date</DrawerTitle>\n <DrawerDescription>Set date</DrawerDescription>\n </DrawerHeader>\n {calendarSelection}\n </DrawerContent>\n </Drawer>\n );\n\n // If children is provided, use render prop pattern with picker\n if (children) {\n return mode === \"drawer\" ? drawPicker : popPicker;\n }\n\n // Default input rendering\n return (\n <Input\n {...props}\n clearable\n value={inputValue}\n mask={maskToUse}\n onChange={(e) => {\n setInputValue(e.target.value);\n const date = parseDate(e.target.value, inputFormat);\n if (date) {\n setDate(date);\n setMonth(date);\n onSelect?.(date, formatDateTimeValue(date));\n onChange?.(e, formatDateTimeValue(date), date);\n } else {\n onSelect?.(undefined, undefined);\n onChange?.(e, undefined, undefined);\n }\n }}\n onBlur={() => {\n const parsedDate = parseDate(inputValue, inputFormat);\n if (!parsedDate) {\n setInputValue(\"\");\n setDate(undefined);\n setMonth(undefined);\n onSelect?.(undefined, undefined);\n }\n }}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setOpen(true);\n }\n }}\n suffixIcon={mode === \"drawer\" ? drawPicker : popPicker}\n />\n );\n}\n\nexport const CalendarDayButton = SCalendarDayButton;\nexport type CalendarDayButtonProps = SCalendarDayButtonProps;\n"],"names":["formatDate","date","outputFormat","DATE_FORMAT","locale","dfFormat","parseDate","str","inputFormat","parse","isValid","generateMaskFromFormat","format","match","DatePicker","value","onChange","onSelect","calendarClassName","side","align","language","mask","closeOnSelect","calendarConfig","desktopMode","mobileMode","showOutsideDays","children","showTime","timeFormat","hideDate","numberOfMonths","variant","color","timePickerMode","hourInterval","minuteInterval","secondInterval","disabledTimes","disabledTimeRanges","showNowButton","nowButtonLabel","timePickerLabel","props","maskToUse","initialDate","open","setOpen","React","setDate","month","setMonth","inputValue","setInputValue","_locale","enUS","vi","mode","isMobile","formatDateTimeValue","d","result","handleSelectForRenderProp","handleChangeForRenderProp","text","parsedDate","handleTimeChange","event","newDate","mergedDate","triggerComponent","jsxs","Button","jsx","CalendarIcon","cn","calendarSelection","Calendar","selectedDate","TimePicker","popPicker","Popover","PopoverTrigger","PopoverContent","drawPicker","Drawer","DrawerTrigger","DrawerContent","DrawerHeader","DrawerTitle","DrawerDescription","Input"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),Oe=require("react"),Se=require("@dsui/ui/components/calendar"),Z=require("@dsui/ui/components/popover"),q=require("@dsui/ui/components/drawer"),F=require("@dsui/ui/index"),Ie=require("../Input/Input.cjs"),ke=require("../Button/Button.cjs"),le=require("./TimePicker.cjs"),fe=require("lucide-react"),S=require("react-device-detect"),H=require("date-fns"),de=require("date-fns/locale"),me=require("../../constants/common.cjs"),Ve=require("../FloatLabel.cjs");function Ce(u){const a=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(u){for(const f in u)if(f!=="default"){const w=Object.getOwnPropertyDescriptor(u,f);Object.defineProperty(a,f,w.get?w:{enumerable:!0,get:()=>u[f]})}}return a.default=u,Object.freeze(a)}const j=Ce(Oe);function $e(u,a=me.DATE_FORMAT,f){return u?H.format(u,a,f?{locale:f}:void 0):""}const x=(u,a=me.DATE_FORMAT)=>{const f=H.parse(u,a,new Date);return H.isValid(f)?f:void 0};function Le(u){return u.replace(/dd|MM|yyyy/g,a=>{switch(a){case"dd":case"MM":return"99";case"yyyy":return"9999";default:return a}}).replace(/d|M|y/g,a=>{switch(a){case"d":case"M":return"9";case"y":return"9";default:return a}})}function Ae({label:u,value:a,placeholder:f,onChange:w,onSelect:d,calendarClassName:ge,side:be="bottom",align:ve="end",format:O="dd/MM/yyyy",language:we="vi",mask:V,closeOnSelect:he=!1,showOutsideDays:pe=!0,calendarConfig:C,timeConfig:ee,desktopMode:I="popover",mobileMode:te="drawer",children:$,separator:De=i.jsx(fe.MoveRight,{className:"size-5"}),showTime:y=!1,timeFormat:h="HH:mm",hideDate:oe=!1,numberOfMonths:je=1,variant:xe="default",color:ye="primary",...s}){const re=j.useId();let g,L;typeof O=="string"?(g=O,L=O):(g=O.input,L=O.output);let A;V===!0?A=Le(g):typeof V=="string"&&(A=V);const ne=a?.from?x(a.from,g):void 0,Me=a?.to?x(a.to,g):void 0,Te={from:ne,to:Me},[se,k]=j.useState(!1),[n,m]=j.useState(Te),[ze,E]=j.useState(ne||new Date),[R,p]=j.useState(a?.from||""),[N,D]=j.useState(a?.to||""),[_,B]=j.useState(void 0),[U,Y]=j.useState(void 0),K=j.useRef(null),G=j.useRef(null),Fe=!!(R.trim()||N.trim()),J=C?.locale?C?.locale:we==="en"?de.enUS:de.vi,o=e=>{if(!e)return"";let t=$e(e,L,J);return y&&(t+=` ${H.format(e,h)}`),t},Re=e=>{m(e);const t=o(e?.from),r=o(e?.to);p(t),D(r),d?.(e,{from:t,to:r})},Ne=e=>{if(p(e),e.trim()===""){p(""),D("");const b={from:void 0,to:void 0};m(b),d?.(b,b);return}let t;y?t=x(e,`${g} ${h}`):t=x(e,g);const r={from:t,to:n?.to};t?(m(r),E(t),B(t),d?.(r,{from:o(t),to:o(n?.to)})):(m(r),d?.(r,{from:o(n?.from),to:o(n?.to)}))},Pe=e=>{if(D(e),e.trim()===""){p(""),D("");const b={from:void 0,to:void 0};m(b),d?.(b,b);return}let t;y?t=x(e,`${g} ${h}`):t=x(e,g);const r={from:n?.from,to:t};t?(m(r),Y(t),d?.(r,{from:o(n?.from),to:o(t)})):(m(r),d?.(r,{from:o(n?.from),to:void 0}))},qe=e=>{if(e){B(e);const t=new Date(n?.from||new Date);t.setHours(e.getHours(),e.getMinutes(),e.getSeconds(),0);const r={from:t,to:n?.to};m(r),p(o(t)),d?.(r,{from:o(t),to:o(n?.to)}),w?.(r,{from:o(t),to:o(n?.to)})}},He=e=>{if(e){Y(e);const t=new Date(n?.to||new Date);t.setHours(e.getHours(),e.getMinutes(),e.getSeconds(),0);const r={from:n?.from,to:t};m(r),D(o(t)),d?.(r,{from:o(n?.from),to:o(t)}),w?.(r,{from:o(n?.from),to:o(t)})}},ie=$?$({fromValue:R,toValue:N,range:n,onSelect:Re,onFromChange:Ne,onToChange:Pe}):i.jsxs(ke.default,{variant:"ghost",className:"!p-1 !leading-0 h-auto rounded hover:bg-accent transition-colors",size:s?.size,children:[i.jsx(fe.CalendarIcon,{className:F.cn({"size-3":s.size==="xs"||s.size==="sm","size-3.5":!s.size||s.size==="normal","size-4":s.size==="lg"||s.size==="xl"})}),i.jsx("span",{className:"sr-only",children:"Select date range"})]}),ae=i.jsxs("div",{className:F.cn("flex items-stretch",y&&!oe?"gap-0":""),children:[!oe&&i.jsx(Se.Calendar,{...C,mode:"range",selected:n,captionLayout:"dropdown",month:ze,onMonthChange:E,numberOfMonths:S.isMobile?1:je||1,variant:xe,color:ye,onSelect:e=>{let t=e;if(y){const c=_,l=U;t={from:e?.from?new Date(e.from.getFullYear(),e.from.getMonth(),e.from.getDate(),c?.getHours()||0,c?.getMinutes()||0,c?.getSeconds()||0):void 0,to:e?.to?new Date(e.to.getFullYear(),e.to.getMonth(),e.to.getDate(),l?.getHours()||0,l?.getMinutes()||0,l?.getSeconds()||0):void 0}}m(t);const r=o(t?.from),b=o(t?.to);p(r),D(b),d?.(t,{from:r,to:b}),w?.(t,{from:r,to:b}),he&&t?.from&&t?.to&&!y&&k(!1)},locale:J,formatters:{formatMonthDropdown:e=>e.toLocaleString(J.code,{month:"short"})},showOutsideDays:pe,className:F.cn("mx-auto",{"[--cell-size:clamp(0px,calc(100vw/7.5),52px)] mb-8 bg-transparent":S.isMobile||I==="drawer","[--cell-size:clamp(0px,calc(100vw/7.5),34px)]":!S.isMobile&&I!=="drawer"},ge)}),y&&i.jsxs("div",{className:"flex gap-0 border-l border-border",children:[i.jsx(le.TimePicker,{...ee?.[0],value:_?H.format(_,h):void 0,onSelect:qe,format:h,showHours:!0,showMinutes:!0,showSeconds:h==="HH:mm:ss",standalone:!1}),i.jsx("div",{className:"border-l border-border"}),i.jsx(le.TimePicker,{...ee?.[1],value:U?H.format(U,h):void 0,onSelect:He,format:h,showHours:!0,showMinutes:!0,showSeconds:h==="HH:mm:ss",standalone:!1})]})]}),Q=i.jsxs(Z.Popover,{open:se,onOpenChange:k,children:[i.jsx(Z.PopoverTrigger,{asChild:!0,disabled:s.disabled,children:ie}),i.jsx(Z.PopoverContent,{className:F.cn("w-auto overflow-hidden p-0","backdrop-blur bg-background/50"),side:be,align:ve,children:ae})]}),W=i.jsxs(q.Drawer,{open:se,onOpenChange:k,children:[i.jsx(q.DrawerTrigger,{asChild:!0,children:ie}),i.jsxs(q.DrawerContent,{className:F.cn("w-auto overflow-hidden p-0","backdrop-blur bg-background"),children:[i.jsxs(q.DrawerHeader,{className:"sr-only",children:[i.jsx(q.DrawerTitle,{children:"Select date range"}),i.jsx(q.DrawerDescription,{children:"Set your date range"})]}),ae]})]});if($)return(S.isMobile?te:I)==="drawer"?W:Q;const ce=(e,t,r,b)=>{const c=e==="from";return i.jsx(Ie.default,{...s,...b,ref:c?K:G,id:re,size:s.isFloatLabel?s.size?s.size:"xl":s.size,className:F.cn(s.className,"relative peer border-0 focus:ring-0 rounded-none hover:bg-transparent active:bg-transparent focus-visible:ring-0 focus-visible:border-0",c?"pr-0":""),label:s.isFloatLabel&&typeof u=="object"?c?u?.from||"":u?.to||"":"",placeholder:typeof f=="object"?c?f?.from||"":f?.to||"":f,clearable:!c,value:t,mask:A,onChange:l=>{const M=l.target.value;if(r(M),M.trim()===""){p(""),D("");const T={from:void 0,to:void 0};m(T),d?.(T,T),w?.(T,T);return}let v;y?v=x(M,`${g} ${h}`):v=x(M,g);const P=c?{from:v,to:n?.to}:{from:n?.from,to:v};if(v){m(P),c&&E(v),c?B(v):Y(v);const T=o(c?v:n?.from),ue=o(c?n?.to:v);d?.(P,{from:T,to:ue}),w?.(P,{from:c?M:R,to:c?N:M})}else d?.(P,{from:o(n?.from),to:c?o(n?.to):void 0}),w?.(P,{from:o(n?.from),to:c?o(n?.to):void 0})},onClear:c?void 0:()=>{p(""),D("");const l={from:void 0,to:void 0};m(l),d?.(l,l),w?.(l,l)},onBlur:()=>{const l=document.activeElement;l!==K.current&&l!==G.current&&setTimeout(()=>{const M=document.activeElement;if(M!==K.current&&M!==G.current){const v=z=>{if(z.trim()==="")return!0;let X;return y?X=x(z,`${g} ${h}`):X=x(z,g),!!X},P=v(R),T=v(N);if(!P||!T||R.trim()&&!N.trim()||!R.trim()&&N.trim()){p(""),D("");const z={from:void 0,to:void 0};m(z),d?.(z,z),w?.(z,z)}}},100)},onKeyDown:l=>{l.key==="ArrowDown"&&(l.preventDefault(),k(!0))}})};return i.jsxs("div",{className:F.cn("group relative flex items-center border rounded-md focus-within:ring-2 focus-within:ring-offset-2 bg-background transition-[color,box-shadow]",{"border-input focus-within:ring-ring":!s.state,"border-success focus-within:ring-success":s.state==="success","border-warning focus-within:ring-warning":s.state==="warning","border-error focus-within:ring-error":s.state==="error"}),children:[ce("from",R,p),i.jsx("span",{className:F.cn("text-muted-foreground select-none pl-2",{"opacity-30":s.disabled}),children:De}),ce("to",N,D,{suffixIcon:S.isMobile?te==="drawer"?W:Q:I==="drawer"?W:Q}),s.isFloatLabel&&typeof u=="string"&&i.jsx(Ve.FloatingLabel,{htmlFor:re,size:s.size,infoTooltip:s.infoTooltip,className:"z-10",shouldFloat:Fe,children:u})]})}exports.RangePicker=Ae;
|
|
2
|
+
//# sourceMappingURL=RangePicker.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RangePicker.cjs","sources":["../../../../src/components/DatePicker/RangePicker.tsx"],"sourcesContent":["import * as React from \"react\";\nimport {\n CalendarDayButton as SCalendarDayButton,\n type CalendarDayButtonProps as SCalendarDayButtonProps,\n Calendar,\n type CalendarColor,\n} from \"@dsui/ui/components/calendar\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@dsui/ui/components/popover\";\nimport {\n Drawer,\n DrawerContent,\n DrawerDescription,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@dsui/ui/components/drawer\";\nimport { cn } from \"@dsui/ui/index\";\nimport Input, { type InputProps } from \"../Input/Input\";\nimport Button from \"../Button/Button\";\nimport { TimePicker } from \"./TimePicker\";\nimport { type DatePickerProps } from \"./DatePicker\";\nimport { CalendarIcon, MoveRight } from \"lucide-react\";\nimport { isMobile } from \"react-device-detect\";\nimport { format as dfFormat, parse, isValid, type Locale } from \"date-fns\";\nimport { vi, enUS } from \"date-fns/locale\";\nimport { DATE_FORMAT } from \"@/constants/common\";\nimport { FloatingLabel } from \"@/components/FloatLabel\";\n\nexport type DateRange = {\n from?: Date | undefined;\n to?: Date | undefined;\n};\n\nexport type DateRangeText = { from?: string; to?: string } | null;\n\nfunction formatDate(\n date: Date | undefined,\n outputFormat: string = DATE_FORMAT,\n locale?: Locale,\n) {\n if (!date) return \"\";\n\n return dfFormat(date, outputFormat, locale ? { locale } : undefined);\n}\n\nconst parseDate = (\n str: string,\n inputFormat: string = DATE_FORMAT,\n): Date | undefined => {\n const date = parse(str, inputFormat, new Date());\n return isValid(date) ? date : undefined;\n};\n\nfunction generateMaskFromFormat(format: string): string {\n return format\n .replace(/dd|MM|yyyy/g, (match) => {\n switch (match) {\n case \"dd\":\n case \"MM\":\n return \"99\";\n case \"yyyy\":\n return \"9999\";\n default:\n return match;\n }\n })\n .replace(/d|M|y/g, (match) => {\n switch (match) {\n case \"d\":\n case \"M\":\n return \"9\";\n case \"y\":\n return \"9\";\n default:\n return match;\n }\n });\n}\n\nexport type FormatType = string | { input: string; output: string };\n\nexport type RangePickerRenderProps = {\n fromValue: string;\n toValue: string;\n range?: DateRange;\n onSelect: (range?: DateRange) => void;\n onFromChange: (text: string) => void;\n onToChange: (text: string) => void;\n};\n\nexport type TimeConfig = Omit<\n React.ComponentProps<typeof TimePicker>,\n \"value\" | \"onSelect\" | \"format\"\n>;\n\nexport type RangePickerProps = Omit<\n DatePickerProps,\n \"value\" | \"onChange\" | \"onSelect\" | \"children\" | \"label\" | \"placeholder\"\n> & {\n label?: string | DateRangeText;\n placeholder?: string | DateRangeText;\n value?: DateRangeText;\n onChange?: (value?: DateRange, text?: DateRangeText) => void;\n onSelect?: (value?: DateRange, text?: DateRangeText) => void;\n children?: (props: RangePickerRenderProps) => React.ReactNode;\n separator?: React.ReactNode;\n timeConfig?: [TimeConfig, TimeConfig];\n numberOfMonths?: number;\n variant?: \"default\" | \"rounded\";\n color?: CalendarColor;\n};\n\nexport function RangePicker({\n label,\n value,\n placeholder,\n onChange,\n onSelect,\n calendarClassName,\n side = \"bottom\",\n align = \"end\",\n format = \"dd/MM/yyyy\",\n language = \"vi\",\n mask,\n closeOnSelect = false,\n showOutsideDays = true,\n calendarConfig,\n timeConfig,\n desktopMode = \"popover\",\n mobileMode = \"drawer\",\n children,\n separator = <MoveRight className=\"size-5\" />,\n showTime = false,\n timeFormat = \"HH:mm\",\n hideDate = false,\n numberOfMonths = 1,\n variant = \"default\",\n color = \"primary\",\n ...props\n}: RangePickerProps) {\n const inputId = React.useId();\n\n let inputFormat: string;\n let outputFormat: string;\n if (typeof format === \"string\") {\n inputFormat = format;\n outputFormat = format;\n } else {\n inputFormat = format.input;\n outputFormat = format.output;\n }\n\n // Determine the mask to use\n let maskToUse: string | undefined;\n if (mask === true) {\n maskToUse = generateMaskFromFormat(inputFormat);\n } else if (typeof mask === \"string\") {\n maskToUse = mask;\n }\n\n const initialFromDate = value?.from\n ? parseDate(value.from, inputFormat)\n : undefined;\n const initialToDate = value?.to\n ? parseDate(value.to, inputFormat)\n : undefined;\n const initialRange: DateRange = {\n from: initialFromDate,\n to: initialToDate,\n };\n\n const [open, setOpen] = React.useState(false);\n const [range, setRange] = React.useState<DateRange | undefined>(initialRange);\n const [month, setMonth] = React.useState<Date | undefined>(\n initialFromDate || new Date(),\n );\n const [fromInputValue, setFromInputValue] = React.useState(value?.from || \"\");\n const [toInputValue, setToInputValue] = React.useState(value?.to || \"\");\n const [fromTime, setFromTime] = React.useState<Date | undefined>(undefined);\n const [toTime, setToTime] = React.useState<Date | undefined>(undefined);\n const fromInputRef = React.useRef<HTMLInputElement>(null);\n const toInputRef = React.useRef<HTMLInputElement>(null);\n\n const shouldFloat = !!(fromInputValue.trim() || toInputValue.trim());\n\n const _locale: Locale = calendarConfig?.locale\n ? (calendarConfig?.locale as Locale)\n : language === \"en\"\n ? enUS\n : vi;\n\n // Helper to format date-time based on showTime and timeFormat\n const formatDateTimeValue = (d: Date | undefined): string => {\n if (!d) return \"\";\n let result = formatDate(d, outputFormat, _locale);\n if (showTime) {\n result += ` ${dfFormat(d, timeFormat)}`;\n }\n return result;\n };\n\n // Helper functions for render props\n const handleSelectForRenderProp = (range?: DateRange) => {\n setRange(range);\n const fromFormatted = formatDateTimeValue(range?.from);\n const toFormatted = formatDateTimeValue(range?.to);\n setFromInputValue(fromFormatted);\n setToInputValue(toFormatted);\n onSelect?.(range, { from: fromFormatted, to: toFormatted });\n };\n\n const handleFromChangeForRenderProp = (text: string) => {\n setFromInputValue(text);\n\n // If the input is cleared (empty), clear both fields\n if (text.trim() === \"\") {\n setFromInputValue(\"\");\n setToInputValue(\"\");\n const newRange: DateRange = { from: undefined, to: undefined };\n setRange(newRange);\n onSelect?.(newRange, newRange as DateRangeText);\n return;\n }\n\n // Try to parse based on showTime\n let parsedDate: Date | undefined;\n if (showTime) {\n parsedDate = parseDate(text, `${inputFormat} ${timeFormat}`);\n } else {\n parsedDate = parseDate(text, inputFormat);\n }\n const newRange: DateRange = { from: parsedDate, to: range?.to };\n if (parsedDate) {\n setRange(newRange);\n setMonth(parsedDate);\n setFromTime(parsedDate);\n onSelect?.(newRange, {\n from: formatDateTimeValue(parsedDate),\n to: formatDateTimeValue(range?.to),\n });\n } else {\n setRange(newRange);\n onSelect?.(newRange, {\n from: formatDateTimeValue(range?.from),\n to: formatDateTimeValue(range?.to),\n });\n }\n };\n\n const handleToChangeForRenderProp = (text: string) => {\n setToInputValue(text);\n\n // If the input is cleared (empty), clear both fields\n if (text.trim() === \"\") {\n setFromInputValue(\"\");\n setToInputValue(\"\");\n const newRange: DateRange = { from: undefined, to: undefined };\n setRange(newRange);\n onSelect?.(newRange, newRange as DateRangeText);\n return;\n }\n\n // Try to parse based on showTime\n let parsedDate: Date | undefined;\n if (showTime) {\n parsedDate = parseDate(text, `${inputFormat} ${timeFormat}`);\n } else {\n parsedDate = parseDate(text, inputFormat);\n }\n const newRange: DateRange = {\n from: range?.from,\n to: parsedDate,\n };\n if (parsedDate) {\n setRange(newRange);\n setToTime(parsedDate);\n onSelect?.(newRange, {\n from: formatDateTimeValue(range?.from),\n to: formatDateTimeValue(parsedDate),\n });\n } else {\n setRange(newRange);\n onSelect?.(newRange, {\n from: formatDateTimeValue(range?.from),\n to: undefined,\n });\n }\n };\n\n const handleTimeChangeFrom = (date?: Date) => {\n if (date) {\n setFromTime(date);\n // Merge: keep date (year, month, day) from existing range.from, take time (hours, minutes, seconds) from TimePicker\n const mergedDate = new Date(range?.from || new Date());\n mergedDate.setHours(\n date.getHours(),\n date.getMinutes(),\n date.getSeconds(),\n 0,\n );\n\n const newRange: DateRange = {\n from: mergedDate,\n to: range?.to,\n };\n setRange(newRange);\n setFromInputValue(formatDateTimeValue(mergedDate));\n onSelect?.(newRange, {\n from: formatDateTimeValue(mergedDate),\n to: formatDateTimeValue(range?.to),\n });\n onChange?.(newRange, {\n from: formatDateTimeValue(mergedDate),\n to: formatDateTimeValue(range?.to),\n });\n }\n };\n\n const handleTimeChangeTo = (date?: Date) => {\n if (date) {\n setToTime(date);\n // Merge: keep date (year, month, day) from existing range.to, take time (hours, minutes, seconds) from TimePicker\n const mergedDate = new Date(range?.to || new Date());\n mergedDate.setHours(\n date.getHours(),\n date.getMinutes(),\n date.getSeconds(),\n 0,\n );\n\n const newRange: DateRange = {\n from: range?.from,\n to: mergedDate,\n };\n setRange(newRange);\n setToInputValue(formatDateTimeValue(mergedDate));\n onSelect?.(newRange, {\n from: formatDateTimeValue(range?.from),\n to: formatDateTimeValue(mergedDate),\n });\n onChange?.(newRange, {\n from: formatDateTimeValue(range?.from),\n to: formatDateTimeValue(mergedDate),\n });\n }\n };\n\n // Determine trigger component\n const triggerComponent = children ? (\n children({\n fromValue: fromInputValue,\n toValue: toInputValue,\n range,\n onSelect: handleSelectForRenderProp,\n onFromChange: handleFromChangeForRenderProp,\n onToChange: handleToChangeForRenderProp,\n })\n ) : (\n <Button\n variant=\"ghost\"\n className=\"!p-1 !leading-0 h-auto rounded hover:bg-accent transition-colors\"\n size={props?.size}\n >\n <CalendarIcon\n className={cn({\n \"size-3\": props.size === \"xs\" || props.size === \"sm\",\n \"size-3.5\": !props.size || props.size === \"normal\",\n \"size-4\": props.size === \"lg\" || props.size === \"xl\",\n })}\n />\n <span className=\"sr-only\">Select date range</span>\n </Button>\n );\n\n const calendarSelection = (\n <div\n className={cn(\"flex items-stretch\", showTime && !hideDate ? \"gap-0\" : \"\")}\n >\n {!hideDate && (\n <Calendar\n {...calendarConfig}\n mode=\"range\"\n selected={range as any}\n captionLayout=\"dropdown\"\n month={month}\n onMonthChange={setMonth}\n numberOfMonths={isMobile ? 1 : numberOfMonths || 1}\n variant={variant}\n color={color}\n onSelect={(selectedRange) => {\n // Preserve time from TimePicker values if showTime is enabled\n let preservedRange = selectedRange;\n if (showTime) {\n // Get current time from TimePicker state\n const fromTimeObj = fromTime;\n const toTimeObj = toTime;\n\n preservedRange = {\n from: selectedRange?.from\n ? new Date(\n selectedRange.from.getFullYear(),\n selectedRange.from.getMonth(),\n selectedRange.from.getDate(),\n fromTimeObj?.getHours() || 0,\n fromTimeObj?.getMinutes() || 0,\n fromTimeObj?.getSeconds() || 0,\n )\n : undefined,\n to: selectedRange?.to\n ? new Date(\n selectedRange.to.getFullYear(),\n selectedRange.to.getMonth(),\n selectedRange.to.getDate(),\n toTimeObj?.getHours() || 0,\n toTimeObj?.getMinutes() || 0,\n toTimeObj?.getSeconds() || 0,\n )\n : undefined,\n };\n }\n setRange(preservedRange);\n const fromFormatted = formatDateTimeValue(preservedRange?.from);\n const toFormatted = formatDateTimeValue(preservedRange?.to);\n setFromInputValue(fromFormatted);\n setToInputValue(toFormatted);\n onSelect?.(preservedRange, {\n from: fromFormatted,\n to: toFormatted,\n });\n onChange?.(preservedRange, {\n from: fromFormatted,\n to: toFormatted,\n });\n if (\n closeOnSelect &&\n preservedRange?.from &&\n preservedRange?.to &&\n !showTime\n ) {\n setOpen(false);\n }\n }}\n locale={_locale}\n formatters={{\n formatMonthDropdown: (date) =>\n date.toLocaleString(_locale.code, { month: \"short\" }),\n }}\n showOutsideDays={showOutsideDays}\n className={cn(\n \"mx-auto\",\n {\n \"[--cell-size:clamp(0px,calc(100vw/7.5),52px)] mb-8 bg-transparent\":\n isMobile || desktopMode === \"drawer\",\n \"[--cell-size:clamp(0px,calc(100vw/7.5),34px)]\":\n !isMobile && desktopMode !== \"drawer\",\n },\n calendarClassName,\n )}\n />\n )}\n {showTime && (\n <div className=\"flex gap-0 border-l border-border\">\n <TimePicker\n {...timeConfig?.[0]}\n value={fromTime ? dfFormat(fromTime, timeFormat) : undefined}\n onSelect={handleTimeChangeFrom}\n format={timeFormat}\n showHours\n showMinutes\n showSeconds={timeFormat === \"HH:mm:ss\"}\n standalone={false}\n />\n <div className=\"border-l border-border\" />\n <TimePicker\n {...timeConfig?.[1]}\n value={toTime ? dfFormat(toTime, timeFormat) : undefined}\n onSelect={handleTimeChangeTo}\n format={timeFormat}\n showHours\n showMinutes\n showSeconds={timeFormat === \"HH:mm:ss\"}\n standalone={false}\n />\n </div>\n )}\n </div>\n );\n\n const popPicker = (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild disabled={props.disabled}>\n {triggerComponent}\n </PopoverTrigger>\n <PopoverContent\n className={cn(\n \"w-auto overflow-hidden p-0\",\n \"backdrop-blur bg-background/50\",\n )}\n side={side}\n align={align}\n >\n {calendarSelection}\n </PopoverContent>\n </Popover>\n );\n\n const drawPicker = (\n <Drawer open={open} onOpenChange={setOpen}>\n <DrawerTrigger asChild>{triggerComponent}</DrawerTrigger>\n <DrawerContent\n className={cn(\n \"w-auto overflow-hidden p-0\",\n \"backdrop-blur bg-background\",\n )}\n >\n <DrawerHeader className=\"sr-only\">\n <DrawerTitle>Select date range</DrawerTitle>\n <DrawerDescription>Set your date range</DrawerDescription>\n </DrawerHeader>\n {calendarSelection}\n </DrawerContent>\n </Drawer>\n );\n\n // If children is provided, use render prop pattern with picker\n if (children) {\n const mode = isMobile ? mobileMode : desktopMode;\n return mode === \"drawer\" ? drawPicker : popPicker;\n }\n\n // Helper function to render range input\n const renderRangeInput = (\n type: \"from\" | \"to\",\n inputValue: string,\n setInputValue: (value: string) => void,\n additionalProps?: Partial<InputProps>,\n ) => {\n const isFrom = type === \"from\";\n\n return (\n <Input\n {...props}\n {...additionalProps}\n ref={isFrom ? fromInputRef : toInputRef}\n id={inputId}\n size={\n props.isFloatLabel ? (props.size ? props.size : \"xl\") : props.size\n }\n className={cn(\n props.className,\n \"relative peer border-0 focus:ring-0 rounded-none hover:bg-transparent active:bg-transparent focus-visible:ring-0 focus-visible:border-0\",\n isFrom ? \"pr-0\" : \"\",\n )}\n label={\n props.isFloatLabel && typeof label === \"object\"\n ? isFrom\n ? label?.from || \"\"\n : label?.to || \"\"\n : \"\"\n }\n placeholder={\n typeof placeholder === \"object\"\n ? isFrom\n ? placeholder?.from || \"\"\n : placeholder?.to || \"\"\n : placeholder\n }\n clearable={!isFrom}\n value={inputValue}\n mask={maskToUse}\n onChange={(e) => {\n const inputValue = e.target.value;\n setInputValue(inputValue);\n\n // If the input is cleared (empty), clear both fields\n if (inputValue.trim() === \"\") {\n setFromInputValue(\"\");\n setToInputValue(\"\");\n const newRange: DateRange = { from: undefined, to: undefined };\n setRange(newRange);\n onSelect?.(newRange, newRange as DateRangeText);\n onChange?.(newRange, newRange as DateRangeText);\n return;\n }\n\n // Try to parse based on showTime\n let date: Date | undefined;\n if (showTime) {\n date = parseDate(inputValue, `${inputFormat} ${timeFormat}`);\n } else {\n date = parseDate(inputValue, inputFormat);\n }\n const newRange: DateRange = isFrom\n ? { from: date, to: range?.to }\n : { from: range?.from, to: date };\n\n if (date) {\n setRange(newRange);\n if (isFrom) setMonth(date);\n // Update time state if time was parsed\n if (isFrom) {\n setFromTime(date);\n // setFromInputValue(formatDateTimeValue(date)); // Sync input value\n } else {\n setToTime(date);\n // setToInputValue(formatDateTimeValue(date)); // Sync input value\n }\n const fromFormatted = formatDateTimeValue(\n isFrom ? date : range?.from,\n );\n const toFormatted = formatDateTimeValue(isFrom ? range?.to : date);\n onSelect?.(newRange, { from: fromFormatted, to: toFormatted });\n onChange?.(newRange, {\n from: isFrom ? inputValue : fromInputValue,\n to: isFrom ? toInputValue : inputValue,\n });\n\n // If from input and date is valid, auto-focus to to input if to is empty\n // if (isFrom && toInputRef.current && !toInputValue.trim()) {\n // requestAnimationFrame(() => toInputRef.current?.focus());\n // }\n } else {\n onSelect?.(newRange, {\n from: formatDateTimeValue(range?.from),\n to: isFrom ? formatDateTimeValue(range?.to) : undefined,\n });\n onChange?.(newRange, {\n from: formatDateTimeValue(range?.from),\n to: isFrom ? formatDateTimeValue(range?.to) : undefined,\n });\n }\n }}\n onClear={\n !isFrom\n ? () => {\n setFromInputValue(\"\");\n setToInputValue(\"\");\n const newRange: DateRange = { from: undefined, to: undefined };\n setRange(newRange);\n onSelect?.(newRange, newRange as DateRangeText);\n onChange?.(newRange, newRange as DateRangeText);\n }\n : undefined\n }\n onBlur={() => {\n // Check if blurring out of the entire range picker group\n const activeElement = document.activeElement;\n if (\n activeElement !== fromInputRef.current &&\n activeElement !== toInputRef.current\n ) {\n // Delay validation by 100ms\n setTimeout(() => {\n // Check again if still blurred out of the group\n const currentActiveElement = document.activeElement;\n if (\n currentActiveElement !== fromInputRef.current &&\n currentActiveElement !== toInputRef.current\n ) {\n // Blurred out of the group, validate both inputs\n const validateInput = (val: string) => {\n if (val.trim() === \"\") return true; // empty is valid (will clear)\n let parsed: Date | undefined;\n if (showTime) {\n parsed = parseDate(val, `${inputFormat} ${timeFormat}`);\n } else {\n parsed = parseDate(val, inputFormat);\n }\n return !!parsed;\n };\n\n const fromValid = validateInput(fromInputValue);\n const toValid = validateInput(toInputValue);\n\n // Clear if either is invalid, or if only one has value\n const shouldClear =\n !fromValid ||\n !toValid ||\n (fromInputValue.trim() && !toInputValue.trim()) ||\n (!fromInputValue.trim() && toInputValue.trim());\n\n if (shouldClear) {\n // If either is invalid, clear both\n setFromInputValue(\"\");\n setToInputValue(\"\");\n const newRange: DateRange = {\n from: undefined,\n to: undefined,\n };\n setRange(newRange);\n onSelect?.(newRange, newRange as DateRangeText);\n onChange?.(newRange, newRange as DateRangeText);\n }\n }\n }, 100);\n }\n }}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setOpen(true);\n }\n }}\n />\n );\n };\n\n // Default input rendering with two inputs\n return (\n <div\n className={cn(\n \"group relative flex items-center border rounded-md focus-within:ring-2 focus-within:ring-offset-2 bg-background transition-[color,box-shadow]\",\n {\n \"border-input focus-within:ring-ring\": !props.state,\n \"border-success focus-within:ring-success\": props.state === \"success\",\n \"border-warning focus-within:ring-warning\": props.state === \"warning\",\n \"border-error focus-within:ring-error\": props.state === \"error\",\n },\n )}\n >\n {renderRangeInput(\"from\", fromInputValue, setFromInputValue)}\n <span\n className={cn(\"text-muted-foreground select-none pl-2\", {\n \"opacity-30\": props.disabled,\n })}\n >\n {separator}\n </span>\n {renderRangeInput(\"to\", toInputValue, setToInputValue, {\n suffixIcon: isMobile\n ? mobileMode === \"drawer\"\n ? drawPicker\n : popPicker\n : desktopMode === \"drawer\"\n ? drawPicker\n : popPicker,\n })}\n {props.isFloatLabel && typeof label === \"string\" && (\n <FloatingLabel\n htmlFor={inputId}\n size={props.size}\n infoTooltip={props.infoTooltip}\n className=\"z-10\"\n shouldFloat={shouldFloat}\n >\n {label}\n </FloatingLabel>\n )}\n </div>\n );\n}\n\nexport const CalendarDayButton = SCalendarDayButton;\nexport type CalendarDayButtonProps = SCalendarDayButtonProps;\n"],"names":["formatDate","date","outputFormat","DATE_FORMAT","locale","dfFormat","parseDate","str","inputFormat","parse","isValid","generateMaskFromFormat","format","match","RangePicker","label","value","placeholder","onChange","onSelect","calendarClassName","side","align","language","mask","closeOnSelect","showOutsideDays","calendarConfig","timeConfig","desktopMode","mobileMode","children","separator","jsx","MoveRight","showTime","timeFormat","hideDate","numberOfMonths","variant","color","props","inputId","React","maskToUse","initialFromDate","initialToDate","initialRange","open","setOpen","range","setRange","month","setMonth","fromInputValue","setFromInputValue","toInputValue","setToInputValue","fromTime","setFromTime","toTime","setToTime","fromInputRef","toInputRef","shouldFloat","_locale","enUS","vi","formatDateTimeValue","d","result","handleSelectForRenderProp","fromFormatted","toFormatted","handleFromChangeForRenderProp","text","newRange","parsedDate","handleToChangeForRenderProp","handleTimeChangeFrom","mergedDate","handleTimeChangeTo","triggerComponent","jsxs","Button","CalendarIcon","cn","calendarSelection","Calendar","isMobile","selectedRange","preservedRange","fromTimeObj","toTimeObj","TimePicker","popPicker","Popover","PopoverTrigger","PopoverContent","drawPicker","Drawer","DrawerTrigger","DrawerContent","DrawerHeader","DrawerTitle","DrawerDescription","renderRangeInput","type","inputValue","setInputValue","additionalProps","isFrom","Input","e","activeElement","currentActiveElement","validateInput","val","parsed","fromValid","toValid","FloatingLabel"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),r=require("react"),j=require("@dsui/ui/index"),Y=require("../Button/Button.cjs"),Oe=require("../Select/Select.cjs"),Fe=require("../Input/Input.cjs"),Z=require("@dsui/ui/components/popover"),k=require("@dsui/ui/components/drawer"),we=require("react-device-detect"),Ie=require("lucide-react"),_=require("../WheelColumn.cjs"),Ee=require("../TimeGridView.cjs"),E=require("date-fns"),B=(i,h=1)=>{const b=[];for(let x=0;x<i;x+=h)b.push(x);return b},I=i=>String(i).padStart(2,"0"),He=(i,h="HH:mm")=>!i||!E.isValid(i)?"":E.format(i,h),Te=(i,h="HH:mm")=>{if(!i)return;const b=new Date,x=E.parse(i,h,b);if(E.isValid(x))return x};function $e(i){return i.replace(/HH|mm|ss/g,h=>{switch(h){case"HH":case"mm":case"ss":return"99";default:return h}}).replace(/H|m|s/g,()=>"9")}function ze({value:i,onChange:h,onSelect:b,showHours:x=!0,showMinutes:L=!0,showSeconds:q=!1,disabled:v=!1,className:ee,timeLabel:a,mask:$,format:D,mode:l="wheel",hourInterval:se=1,minuteInterval:te=1,secondInterval:ne=1,disabledTimes:re=[],disabledTimeRanges:oe=[],showNowButton:ie=!1,nowButtonLabel:ce="Now",standalone:ae=!0,desktopMode:le="popover",mobileMode:Ne="drawer",color:O="primary",...Se}){let w,H;typeof D=="string"?(w=D,H=D):D?(w=D.input,H=D.output):(w=q?"HH:mm:ss":"HH:mm",H=q?"HH:mm:ss":"HH:mm");const[p,T]=r.useState(void 0),[g,N]=r.useState(void 0),[C,S]=r.useState(void 0),[z,ue]=r.useState(!1);r.useEffect(()=>{if(i){const e=Te(i,w);e&&(T(e.getHours()),N(e.getMinutes()),S(e.getSeconds()))}else T(void 0),N(void 0),S(void 0)},[i,w]);const U=r.useRef(null),G=r.useRef(null),A=r.useRef(null),W=r.useRef(null),y=r.useMemo(()=>B(24,se),[se]),M=r.useMemo(()=>B(60,te),[te]),R=r.useMemo(()=>B(60,ne),[ne]),u=r.useCallback((e,s,n=0)=>{const o=`${I(e??0)}:${I(s??0)}${q?`:${I(n??0)}`:""}`;if(re.includes(o))return!0;for(const d of oe){const[f,c,m=0]=d.from.split(":").map(Number),[F,qe,Re=0]=d.to.split(":").map(Number),je=(e??0)*3600+(s??0)*60+(n??0),Pe=f*3600+c*60+m,Ve=F*3600+qe*60+Re;if(je>=Pe&&je<=Ve)return!0}return!1},[re,oe,q]),J=r.useCallback(e=>{if(a)return typeof a=="boolean"?a?e==="hours"?"Hour":e==="minutes"?"Minute":"Second":void 0:typeof a=="string"?a:e==="hours"?a.hours||"Hour":e==="minutes"?a.minutes||"Minute":a.seconds||"Second"},[a]),fe=typeof a=="string"&&t.jsx("div",{className:"text-xs font-semibold text-muted-foreground uppercase p-2 border-b w-full text-center",children:a},"common-label"),De=r.useCallback((e,s,n=0)=>{const o=y.reduce((c,m)=>Math.abs(m-e)<Math.abs(c-e)?m:c),d=M.reduce((c,m)=>Math.abs(m-s)<Math.abs(c-s)?m:c),f=R.reduce((c,m)=>Math.abs(m-n)<Math.abs(c-n)?m:c);if(u(o,d,f)){for(const c of y)for(const m of M)for(const F of R)if(!u(c,m,F))return{h:c,m,s:F}}return{h:o,m:d,s:f}},[y,M,R,u]),P=r.useCallback((e,s,n)=>{const o=new Date;o.setHours(e,s,n,0);const d=He(o,H);b?.(o,d)},[H,b]),de=e=>{u(e,g,C)||(T(e),P(e,g??0,C??0))},me=e=>{u(p,e,C)||(N(e),P(p??0,e,C??0))},he=e=>{u(p,g,e)||(S(e),P(p??0,g??0,e))},V=r.useCallback(e=>{if(e.current){const s=e.current.querySelector("[data-selected]");if(s){const n=e.current,o=n.clientHeight,d=s.offsetTop,f=s.clientHeight,c=d-o/2+f/2;n.scrollTo({top:c,behavior:"smooth"})}}},[]),K=r.useCallback(()=>{l==="wheel"?(V(U),V(G),V(A)):l==="compact"&&V(W)},[U,G,A,W,l,V]),pe=()=>{const e=new Date,{h:s,m:n,s:o}=De(e.getHours(),e.getMinutes(),e.getSeconds());T(s),N(n),S(o),P(s,n,o),setTimeout(()=>K(),100)};r.useEffect(()=>{const e=setTimeout(()=>K(),100);return()=>clearTimeout(e)},[z,l,K]);const Q=r.memo(({items:e,value:s,onChange:n,timeLabel:o,type:d})=>t.jsxs("div",{className:"flex flex-col gap-2",children:[o&&t.jsx("div",{className:"text-xs font-semibold text-muted-foreground uppercase p-2 border-b w-full text-center",children:o}),t.jsx("div",{className:"p-2",children:t.jsx(Oe.default,{value:s?.toString()||"",onValueChange:f=>n(Number(f)),disabled:v,clearable:!1,search:!1,options:e.map(f=>{const c=d==="hours"&&u(f,g,C)||d==="minutes"&&u(p,f,C)||d==="seconds"&&u(p,g,f);return{label:I(f),value:f.toString(),disabled:c}})})})]})),ye=(e,s)=>{u(e,s,0)||(T(e),N(s),S(0),P(e,s,0))},ge=()=>{const e=[];if(l==="compact")return t.jsx(Ee.TimeGridView,{HOURS:y,MINUTES:M,hours:p,minutes:g,disabled:v,isTimeDisabled:u,onTimeSelect:ye,ref:W,color:O});if(x){const s=typeof a=="string"?void 0:J("hours");l==="wheel"?e.push(t.jsx(_.TimeColumnwheel,{ref:U,items:y,value:p,onChange:de,timeLabel:s,isItemDisabled:n=>u(n,g,C),disabled:v,color:O},"hours")):l==="select"&&e.push(t.jsx(Q,{items:y,value:p,onChange:de,timeLabel:s,type:"hours"},"hours"))}if(L){const s=typeof a=="string"?void 0:J("minutes");l==="wheel"?e.push(t.jsx(_.TimeColumnwheel,{ref:G,items:M,value:g,onChange:me,timeLabel:s,itemClassName:x?"border-l":void 0,isItemDisabled:n=>u(p,n,C),disabled:v,color:O},"minutes")):l==="select"&&e.push(t.jsx(Q,{items:M,value:g,onChange:me,timeLabel:s,type:"minutes"},"minutes"))}if(q){const s=typeof a=="string"?void 0:J("seconds");l==="wheel"?e.push(t.jsx(_.TimeColumnwheel,{ref:A,items:R,value:C,onChange:he,timeLabel:s,itemClassName:L||x?"border-l":void 0,isItemDisabled:n=>u(p,g,n),disabled:v,color:O},"seconds")):l==="select"&&e.push(t.jsx(Q,{items:R,value:C,onChange:he,timeLabel:s,type:"seconds"},"seconds"))}return e};if(!ae)return t.jsxs("div",{className:j.cn("flex flex-col gap-2 h-full justify-between",ee),children:[fe,t.jsx("div",{className:j.cn("flex rounded overflow-clip mb-auto",l==="wheel"?"items-end justify-center p-0 h-72":"items-start justify-center"),children:ge()}),ie&&t.jsx(Y.default,{type:"button",variant:"solid",size:"xs",onClick:pe,disabled:v,className:j.cn("rounded-none"),children:ce})]});const xe=t.jsxs("div",{className:j.cn("flex flex-col gap-4 h-full",ee),children:[fe,t.jsx("div",{className:j.cn("flex rounded overflow-clip my-auto mx-auto max-w-sm md:max-w-md lg:max-w-lg relative",l==="wheel"?"items-end justify-center p-0":"items-start justify-center",{"h-72":l==="wheel","w-xs":ae&&(we.isMobile||le==="drawer")}),children:ge()}),ie&&t.jsx(Y.default,{type:"button",variant:"solid",size:"xs",onClick:pe,disabled:v,className:j.cn("rounded-none"),children:ce})]}),ve=t.jsxs(Y.default,{variant:"ghost",className:"!p-1 !leading-0 h-auto rounded hover:bg-accent transition-colors",disabled:v,children:[t.jsx(Ie.Clock,{className:"size-4"}),t.jsx("span",{className:"sr-only",children:"Select time"})]}),Ce=t.jsxs(Z.Popover,{open:z,onOpenChange:ue,children:[t.jsx(Z.PopoverTrigger,{asChild:!0,disabled:v,children:ve}),t.jsx(Z.PopoverContent,{className:j.cn("w-auto overflow-hidden p-0","backdrop-blur bg-background/50"),children:xe})]}),be=t.jsxs(k.Drawer,{open:z,onOpenChange:ue,children:[t.jsx(k.DrawerTrigger,{asChild:!0,children:ve}),t.jsxs(k.DrawerContent,{className:j.cn("w-auto overflow-hidden p-0","backdrop-blur bg-background"),children:[t.jsxs(k.DrawerHeader,{className:"sr-only",children:[t.jsx(k.DrawerTitle,{children:"Select time"}),t.jsx(k.DrawerDescription,{children:"Choose a time"})]}),xe]})]}),Me=H;let X;$===!0?X=$e(w):typeof $=="string"&&(X=$);const ke=e=>{const s=e.target.value,n=Te(s,w);if(n){T(n.getHours()),N(n.getMinutes()),S(n.getSeconds());const o=He(n,H);h?.(e,o,n),b?.(n,o)}else T(0),N(0),S(0),h?.(e,s,void 0),b?.(void 0,s)};return t.jsx(Fe.default,{...Se,clearable:!0,value:i||"",placeholder:Me,mask:X,disabled:v,className:"cursor-pointer",onChange:ke,suffixIcon:we.isMobile?Ne==="drawer"?be:Ce:le==="drawer"?be:Ce})}exports.TimePicker=ze;
|
|
2
|
+
//# sourceMappingURL=TimePicker.cjs.map
|