@shohojdhara/atomix 0.1.30 → 0.2.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/CHANGELOG.md +0 -0
- package/LICENSE +0 -0
- package/README.md +151 -39
- package/dist/atomix.css +13529 -0
- package/dist/atomix.min.css +15 -0
- package/dist/index.d.ts +6112 -1757
- package/dist/index.esm.js +16852 -8364
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +16892 -8369
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/themes/boomdevs.css +13241 -0
- package/dist/themes/boomdevs.min.css +353 -0
- package/dist/themes/esrar.css +15374 -0
- package/dist/themes/esrar.min.css +189 -0
- package/dist/themes/mashroom.css +28079 -0
- package/dist/themes/mashroom.min.css +403 -0
- package/dist/themes/shaj-default.css +14203 -0
- package/dist/themes/shaj-default.min.css +500 -0
- package/dist/themes/yabai.css +13711 -0
- package/dist/themes/yabai.min.css +189 -0
- package/package.json +126 -99
- package/src/components/Accordion/Accordion.stories.tsx +271 -0
- package/src/components/Accordion/Accordion.tsx +131 -0
- package/src/components/Accordion/index.ts +3 -0
- package/src/components/AtomixLogo/AtomixLogo.tsx +36 -0
- package/src/components/AtomixLogo/index.ts +3 -0
- package/src/components/AtomixLogo.tsx +40 -0
- package/src/components/Avatar/Avatar.stories.tsx +257 -0
- package/src/components/Avatar/Avatar.tsx +68 -0
- package/src/components/Avatar/AvatarGroup.tsx +73 -0
- package/src/components/Avatar/index.ts +3 -0
- package/src/components/Badge/Badge.stories.tsx +371 -0
- package/src/components/Badge/Badge.tsx +39 -0
- package/src/components/Badge/index.ts +3 -0
- package/src/components/Block/Block.stories.tsx +408 -0
- package/src/components/Block/Block.tsx +137 -0
- package/src/components/Block/index.ts +1 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +106 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +112 -0
- package/src/components/Breadcrumb/index.ts +3 -0
- package/src/components/Button/Button.stories.tsx +312 -0
- package/src/components/Button/Button.tsx +69 -0
- package/src/components/Button/index.ts +3 -0
- package/src/components/Callout/Callout.stories.tsx +588 -0
- package/src/components/Callout/Callout.tsx +78 -0
- package/src/components/Callout/index.ts +1 -0
- package/src/components/Card/Card.stories.tsx +105 -0
- package/src/components/Card/Card.tsx +69 -0
- package/src/components/Card/ElevationCard.tsx +47 -0
- package/src/components/Card/index.ts +15 -0
- package/src/components/Chart/AdvancedChart.tsx +624 -0
- package/src/components/Chart/AnimatedChart.tsx +206 -0
- package/src/components/Chart/AreaChart.tsx +27 -0
- package/src/components/Chart/BarChart.tsx +148 -0
- package/src/components/Chart/BubbleChart.tsx +411 -0
- package/src/components/Chart/CandlestickChart.tsx +765 -0
- package/src/components/Chart/Chart.stories.tsx +527 -0
- package/src/components/Chart/Chart.tsx +218 -0
- package/src/components/Chart/ChartRenderer.tsx +322 -0
- package/src/components/Chart/ChartToolbar.tsx +436 -0
- package/src/components/Chart/ChartTooltip.tsx +101 -0
- package/src/components/Chart/DonutChart.tsx +370 -0
- package/src/components/Chart/FunnelChart.tsx +393 -0
- package/src/components/Chart/GaugeChart.tsx +550 -0
- package/src/components/Chart/HeatmapChart.tsx +614 -0
- package/src/components/Chart/LineChart.tsx +172 -0
- package/src/components/Chart/LineChartNew.tsx +167 -0
- package/src/components/Chart/MultiAxisChart.tsx +498 -0
- package/src/components/Chart/PieChart.tsx +103 -0
- package/src/components/Chart/RadarChart.tsx +332 -0
- package/src/components/Chart/RealTimeChart.tsx +436 -0
- package/src/components/Chart/ScatterChart.tsx +152 -0
- package/src/components/Chart/TreemapChart.tsx +574 -0
- package/src/components/Chart/WaterfallChart.tsx +450 -0
- package/src/components/Chart/index.ts +119 -0
- package/src/components/Chart/types.ts +338 -0
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +44 -0
- package/src/components/ColorModeToggle/ColorModeToggle.tsx +85 -0
- package/src/components/ColorModeToggle/index.ts +2 -0
- package/src/components/Countdown/Countdown.stories.tsx +46 -0
- package/src/components/Countdown/Countdown.tsx +90 -0
- package/src/components/Countdown/index.ts +2 -0
- package/src/components/DataTable/DataTable.stories.tsx +248 -0
- package/src/components/DataTable/DataTable.tsx +213 -0
- package/src/components/DataTable/index.ts +3 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +364 -0
- package/src/components/DatePicker/DatePicker.tsx +504 -0
- package/src/components/DatePicker/index.ts +4 -0
- package/src/components/DatePicker/readme.md +106 -0
- package/src/components/DatePicker/types.ts +167 -0
- package/src/components/DatePicker/utils.ts +185 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +358 -0
- package/src/components/Dropdown/Dropdown.tsx +352 -0
- package/src/components/Dropdown/index.ts +14 -0
- package/src/components/Dropdown/readme.md +151 -0
- package/src/components/EdgePanel/EdgePanel.stories.tsx +266 -0
- package/src/components/EdgePanel/EdgePanel.tsx +73 -0
- package/src/components/EdgePanel/index.ts +1 -0
- package/src/components/Form/Checkbox.stories.tsx +76 -0
- package/src/components/Form/Checkbox.tsx +69 -0
- package/src/components/Form/Form.stories.tsx +497 -0
- package/src/components/Form/Form.tsx +46 -0
- package/src/components/Form/FormGroup.stories.tsx +162 -0
- package/src/components/Form/FormGroup.tsx +53 -0
- package/src/components/Form/Input.stories.tsx +106 -0
- package/src/components/Form/Input.tsx +87 -0
- package/src/components/Form/Radio.stories.tsx +94 -0
- package/src/components/Form/Radio.tsx +65 -0
- package/src/components/Form/Select.stories.tsx +151 -0
- package/src/components/Form/Select.tsx +191 -0
- package/src/components/Form/Textarea.stories.tsx +123 -0
- package/src/components/Form/Textarea.tsx +78 -0
- package/src/components/Form/index.ts +7 -0
- package/src/components/Hero/Hero.stories.tsx +295 -0
- package/src/components/Hero/Hero.tsx +175 -0
- package/src/components/Hero/index.ts +6 -0
- package/src/components/Icon/Icon.tsx +87 -0
- package/src/components/Icon/index.ts +2 -0
- package/src/components/List/List.stories.tsx +122 -0
- package/src/components/List/List.tsx +35 -0
- package/src/components/List/ListGroup.tsx +35 -0
- package/src/components/List/index.ts +2 -0
- package/src/components/Messages/Messages.stories.tsx +160 -0
- package/src/components/Messages/Messages.tsx +172 -0
- package/src/components/Messages/index.ts +3 -0
- package/src/components/Modal/Modal.stories.tsx +284 -0
- package/src/components/Modal/Modal.tsx +198 -0
- package/src/components/Modal/README.md +169 -0
- package/src/components/Modal/index.ts +1 -0
- package/src/components/Navigation/Menu/MegaMenu.tsx +109 -0
- package/src/components/Navigation/Menu/Menu.stories.tsx +339 -0
- package/src/components/Navigation/Menu/Menu.tsx +111 -0
- package/src/components/Navigation/Nav/Nav.stories.tsx +456 -0
- package/src/components/Navigation/Nav/Nav.tsx +51 -0
- package/src/components/Navigation/Nav/NavDropdown.tsx +105 -0
- package/src/components/Navigation/Nav/NavItem.tsx +168 -0
- package/src/components/Navigation/Navbar/Navbar.stories.tsx +569 -0
- package/src/components/Navigation/Navbar/Navbar.tsx +150 -0
- package/src/components/Navigation/README.md +314 -0
- package/src/components/Navigation/SideMenu/SideMenu.README.md +494 -0
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +609 -0
- package/src/components/Navigation/SideMenu/SideMenu.tsx +101 -0
- package/src/components/Navigation/SideMenu/SideMenuItem.tsx +103 -0
- package/src/components/Navigation/SideMenu/SideMenuList.tsx +41 -0
- package/src/components/Navigation/index.ts +23 -0
- package/src/components/Pagination/Pagination.stories.tsx +188 -0
- package/src/components/Pagination/Pagination.tsx +162 -0
- package/src/components/Pagination/index.ts +1 -0
- package/src/components/PhotoViewer/PhotoViewer.stories.tsx +397 -0
- package/src/components/PhotoViewer/PhotoViewer.tsx +246 -0
- package/src/components/PhotoViewer/PhotoViewerHeader.tsx +184 -0
- package/src/components/PhotoViewer/PhotoViewerImage.tsx +173 -0
- package/src/components/PhotoViewer/PhotoViewerInfo.tsx +91 -0
- package/src/components/PhotoViewer/PhotoViewerNavigation.tsx +85 -0
- package/src/components/PhotoViewer/PhotoViewerThumbnails.tsx +63 -0
- package/src/components/PhotoViewer/README.md +358 -0
- package/src/components/PhotoViewer/examples/ImageGallery.tsx +187 -0
- package/src/components/PhotoViewer/examples/SimpleGallery.tsx +73 -0
- package/src/components/PhotoViewer/examples/index.ts +2 -0
- package/src/components/PhotoViewer/index.ts +14 -0
- package/src/components/Popover/Popover.stories.tsx +143 -0
- package/src/components/Popover/Popover.tsx +137 -0
- package/src/components/Popover/index.ts +5 -0
- package/src/components/Popover/readme.md +120 -0
- package/src/components/ProductReview/ProductReview.stories.tsx +88 -0
- package/src/components/ProductReview/ProductReview.tsx +169 -0
- package/src/components/ProductReview/index.ts +3 -0
- package/src/components/Progress/Progress.stories.tsx +75 -0
- package/src/components/Progress/Progress.tsx +45 -0
- package/src/components/Progress/index.ts +1 -0
- package/src/components/Rating/Rating.stories.tsx +109 -0
- package/src/components/Rating/Rating.tsx +286 -0
- package/src/components/Rating/index.ts +6 -0
- package/src/components/River/River.stories.tsx +230 -0
- package/src/components/River/River.tsx +134 -0
- package/src/components/River/index.ts +2 -0
- package/src/components/SectionIntro/SectionIntro.stories.tsx +143 -0
- package/src/components/SectionIntro/SectionIntro.tsx +184 -0
- package/src/components/SectionIntro/index.ts +3 -0
- package/src/components/Slider/Slider.stories.tsx +241 -0
- package/src/components/Slider/Slider.tsx +225 -0
- package/src/components/Slider/index.ts +24 -0
- package/src/components/Spinner/Spinner.stories.tsx +65 -0
- package/src/components/Spinner/Spinner.tsx +36 -0
- package/src/components/Spinner/index.ts +2 -0
- package/src/components/Steps/Steps.stories.tsx +158 -0
- package/src/components/Steps/Steps.tsx +115 -0
- package/src/components/Steps/index.ts +3 -0
- package/src/components/Tab/Tab.stories.tsx +129 -0
- package/src/components/Tab/Tab.tsx +111 -0
- package/src/components/Tab/index.ts +2 -0
- package/src/components/Testimonial/Testimonial.stories.tsx +180 -0
- package/src/components/Testimonial/Testimonial.tsx +138 -0
- package/src/components/Testimonial/index.ts +3 -0
- package/src/components/Todo/Todo.stories.tsx +103 -0
- package/src/components/Todo/Todo.tsx +158 -0
- package/src/components/Todo/index.ts +1 -0
- package/src/components/Toggle/Toggle.stories.tsx +49 -0
- package/src/components/Toggle/Toggle.tsx +84 -0
- package/src/components/Toggle/index.ts +2 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +115 -0
- package/src/components/Tooltip/Tooltip.tsx +150 -0
- package/src/components/Tooltip/index.ts +3 -0
- package/src/components/Upload/Upload.stories.tsx +220 -0
- package/src/components/Upload/Upload.tsx +354 -0
- package/src/components/Upload/index.ts +3 -0
- package/src/components/VideoPlayer/VideoPlayer.stories.tsx +484 -0
- package/src/components/VideoPlayer/VideoPlayer.tsx +574 -0
- package/src/components/VideoPlayer/index.ts +7 -0
- package/src/components/index.ts +111 -0
- package/src/layouts/Grid/Container.tsx +58 -0
- package/src/layouts/Grid/Grid.stories.tsx +861 -0
- package/src/layouts/Grid/Grid.tsx +68 -0
- package/src/layouts/Grid/GridCol.tsx +161 -0
- package/src/layouts/Grid/README.md +108 -0
- package/src/layouts/Grid/Row.tsx +70 -0
- package/src/layouts/Grid/index.ts +8 -0
- package/src/layouts/MasonryGrid/MasonryGrid.stories.tsx +387 -0
- package/src/layouts/MasonryGrid/MasonryGrid.tsx +408 -0
- package/src/layouts/MasonryGrid/MasonryGridItem.tsx +44 -0
- package/src/layouts/MasonryGrid/README.md +117 -0
- package/src/layouts/MasonryGrid/index.ts +4 -0
- package/src/layouts/index.ts +7 -0
- package/src/lib/README.md +89 -0
- package/src/lib/composables/index.ts +63 -0
- package/src/lib/composables/useAccordion.ts +129 -0
- package/src/lib/composables/useAmbientMode.ts +90 -0
- package/src/lib/composables/useBadge.ts +42 -0
- package/src/lib/composables/useBarChart.ts +365 -0
- package/src/lib/composables/useBlock.ts +56 -0
- package/src/lib/composables/useBreadcrumb.ts +81 -0
- package/src/lib/composables/useButton.ts +59 -0
- package/src/lib/composables/useCallout.ts +55 -0
- package/src/lib/composables/useCard.ts +155 -0
- package/src/lib/composables/useChart.ts +1082 -0
- package/src/lib/composables/useChartAnalytics.ts +505 -0
- package/src/lib/composables/useChartData.ts +38 -0
- package/src/lib/composables/useChartExport.ts +392 -0
- package/src/lib/composables/useChartInteraction.ts +34 -0
- package/src/lib/composables/useChartInteractions.ts +123 -0
- package/src/lib/composables/useChartPerformance.ts +323 -0
- package/src/lib/composables/useChartScale.ts +48 -0
- package/src/lib/composables/useChartToolbar.ts +532 -0
- package/src/lib/composables/useCheckbox.ts +70 -0
- package/src/lib/composables/useDataTable.ts +208 -0
- package/src/lib/composables/useDatePicker.ts +564 -0
- package/src/lib/composables/useDropdown.ts +272 -0
- package/src/lib/composables/useEdgePanel.ts +261 -0
- package/src/lib/composables/useForm.ts +62 -0
- package/src/lib/composables/useFormGroup.ts +51 -0
- package/src/lib/composables/useHero.ts +250 -0
- package/src/lib/composables/useInput.ts +58 -0
- package/src/lib/composables/useLineChart.ts +319 -0
- package/src/lib/composables/useMessages.ts +77 -0
- package/src/lib/composables/useModal.ts +110 -0
- package/src/lib/composables/useNavbar.ts +288 -0
- package/src/lib/composables/usePagination.ts +101 -0
- package/src/lib/composables/usePhotoViewer.ts +937 -0
- package/src/lib/composables/usePieChart.ts +362 -0
- package/src/lib/composables/usePopover.ts +354 -0
- package/src/lib/composables/useProgress.ts +74 -0
- package/src/lib/composables/useRadio.ts +47 -0
- package/src/lib/composables/useRating.ts +174 -0
- package/src/lib/composables/useRiver.ts +205 -0
- package/src/lib/composables/useSelect.ts +52 -0
- package/src/lib/composables/useSideMenu.ts +197 -0
- package/src/lib/composables/useSlider.ts +339 -0
- package/src/lib/composables/useSpinner.ts +42 -0
- package/src/lib/composables/useTextarea.ts +55 -0
- package/src/lib/composables/useTodo.ts +141 -0
- package/src/lib/composables/useVideoPlayer.ts +398 -0
- package/src/lib/constants/components.ts +1433 -0
- package/src/lib/constants/index.ts +4 -0
- package/src/lib/index.ts +11 -0
- package/src/lib/types/components.ts +4750 -0
- package/src/lib/types/index.ts +2 -0
- package/src/lib/utils/dom.ts +41 -0
- package/src/lib/utils/icons.ts +74 -0
- package/src/lib/utils/index.ts +55 -0
- package/src/lib/utils/useForkRef.test.tsx +64 -0
- package/src/lib/utils/useForkRef.ts +36 -0
- package/src/lib/utils.test.ts +14 -0
- package/src/styles/01-settings/_index.scss +2 -0
- package/src/styles/01-settings/_settings.accordion.scss +7 -5
- package/src/styles/01-settings/_settings.animations.scss +0 -0
- package/src/styles/01-settings/_settings.avatar-group.scss +6 -3
- package/src/styles/01-settings/_settings.avatar.scss +2 -2
- package/src/styles/01-settings/_settings.badge.scss +15 -9
- package/src/styles/01-settings/_settings.block.scss +11 -0
- package/src/styles/01-settings/_settings.border-radius.scss +12 -9
- package/src/styles/01-settings/_settings.border.scss +4 -1
- package/src/styles/01-settings/_settings.box-shadow.scss +1 -1
- package/src/styles/01-settings/_settings.breadcrumb.scss +9 -8
- package/src/styles/01-settings/_settings.breakpoints.scss +0 -0
- package/src/styles/01-settings/_settings.btn-group.scss +4 -1
- package/src/styles/01-settings/_settings.button.scss +19 -21
- package/src/styles/01-settings/_settings.callout.scss +42 -24
- package/src/styles/01-settings/_settings.card.scss +12 -10
- package/src/styles/01-settings/_settings.chart.scss +199 -0
- package/src/styles/01-settings/_settings.checkbox-group.scss +0 -0
- package/src/styles/01-settings/_settings.checkbox.scss +0 -0
- package/src/styles/01-settings/_settings.color-mode.scss +0 -0
- package/src/styles/01-settings/_settings.colors.scss +20 -0
- package/src/styles/01-settings/_settings.config.scss +1 -1
- package/src/styles/01-settings/_settings.countdown.scss +0 -0
- package/src/styles/01-settings/_settings.data-table.scss +0 -0
- package/src/styles/01-settings/_settings.datepicker.scss +0 -0
- package/src/styles/01-settings/_settings.dropdown.scss +0 -0
- package/src/styles/01-settings/_settings.edge-panel.scss +0 -0
- package/src/styles/01-settings/_settings.fonts.scss +1 -1
- package/src/styles/01-settings/_settings.form-group.scss +0 -0
- package/src/styles/01-settings/_settings.form.scss +0 -0
- package/src/styles/01-settings/_settings.grid.scss +3 -3
- package/src/styles/01-settings/_settings.hero.scss +1 -1
- package/src/styles/01-settings/_settings.input.scss +1 -1
- package/src/styles/01-settings/_settings.link.scss +0 -0
- package/src/styles/01-settings/_settings.list-group.scss +0 -0
- package/src/styles/01-settings/_settings.list.scss +0 -0
- package/src/styles/01-settings/_settings.maps.scss +43 -8
- package/src/styles/01-settings/_settings.masonry-grid.scss +0 -0
- package/src/styles/01-settings/_settings.menu.scss +0 -0
- package/src/styles/01-settings/_settings.messages.scss +0 -0
- package/src/styles/01-settings/_settings.modal.scss +1 -1
- package/src/styles/01-settings/_settings.nav.scss +0 -0
- package/src/styles/01-settings/_settings.navbar.scss +0 -0
- package/src/styles/01-settings/_settings.pagination.scss +0 -0
- package/src/styles/01-settings/_settings.photoviewer.scss +89 -23
- package/src/styles/01-settings/_settings.popover.scss +0 -0
- package/src/styles/01-settings/_settings.position.scss +0 -0
- package/src/styles/01-settings/_settings.progress.scss +0 -0
- package/src/styles/01-settings/_settings.rating.scss +0 -0
- package/src/styles/01-settings/_settings.river.scss +0 -0
- package/src/styles/01-settings/_settings.sectionintro.scss +0 -0
- package/src/styles/01-settings/_settings.select.scss +0 -0
- package/src/styles/01-settings/_settings.side-menu.scss +0 -0
- package/src/styles/01-settings/_settings.skeleton.scss +0 -0
- package/src/styles/01-settings/_settings.slider.scss +59 -0
- package/src/styles/01-settings/_settings.spacing.scss +11 -3
- package/src/styles/01-settings/_settings.spinner.scss +0 -0
- package/src/styles/01-settings/_settings.steps.scss +1 -1
- package/src/styles/01-settings/_settings.tabs.scss +4 -4
- package/src/styles/01-settings/_settings.testimonials.scss +0 -0
- package/src/styles/01-settings/_settings.todo.scss +0 -0
- package/src/styles/01-settings/_settings.toggle.scss +1 -1
- package/src/styles/01-settings/_settings.tooltip.scss +0 -0
- package/src/styles/01-settings/_settings.typography.scss +2 -0
- package/src/styles/01-settings/_settings.upload.scss +0 -0
- package/src/styles/01-settings/_settings.video-player.scss +64 -0
- package/src/styles/01-settings/_settings.z-layers.scss +0 -0
- package/src/styles/02-tools/_index.scss +1 -0
- package/src/styles/02-tools/_tools.animations.scss +82 -0
- package/src/styles/02-tools/_tools.border-radius.scss +0 -0
- package/src/styles/02-tools/_tools.breakpoints.scss +0 -0
- package/src/styles/02-tools/_tools.button.scss +5 -0
- package/src/styles/02-tools/_tools.clearfix.scss +0 -0
- package/src/styles/02-tools/_tools.color-functions.scss +0 -0
- package/src/styles/02-tools/_tools.color-mode.scss +1 -1
- package/src/styles/02-tools/_tools.component.scss +479 -0
- package/src/styles/02-tools/_tools.event.scss +0 -0
- package/src/styles/02-tools/_tools.grid.scss +0 -0
- package/src/styles/02-tools/_tools.hidden-visually.scss +0 -0
- package/src/styles/02-tools/_tools.hidden.scss +0 -0
- package/src/styles/02-tools/_tools.map-loop.scss +0 -0
- package/src/styles/02-tools/_tools.media-queries.scss +0 -0
- package/src/styles/02-tools/_tools.object-fit.scss +0 -0
- package/src/styles/02-tools/_tools.placeholder.scss +0 -0
- package/src/styles/02-tools/_tools.rem.scss +5 -1
- package/src/styles/02-tools/_tools.size.scss +0 -0
- package/src/styles/02-tools/_tools.spacing.scss +0 -0
- package/src/styles/02-tools/_tools.to-rgb.scss +0 -0
- package/src/styles/02-tools/_tools.transition.scss +0 -0
- package/src/styles/02-tools/_tools.utilities.scss +0 -0
- package/src/styles/02-tools/_tools.utility-api.scss +23 -2
- package/src/styles/03-generic/_generic.fonts.scss +0 -0
- package/src/styles/03-generic/_generic.reset.scss +0 -0
- package/src/styles/03-generic/_generic.root.scss +5 -1
- package/src/styles/03-generic/_generic.selection.scss +0 -0
- package/src/styles/03-generic/_index.scss +0 -0
- package/src/styles/04-elements/_elements.all.scss +0 -0
- package/src/styles/04-elements/_elements.body.scss +0 -0
- package/src/styles/04-elements/_elements.heading.scss +0 -0
- package/src/styles/04-elements/_elements.html.scss +0 -0
- package/src/styles/04-elements/_elements.links.scss +0 -0
- package/src/styles/04-elements/_index.scss +0 -0
- package/src/styles/05-objects/_index.scss +1 -0
- package/src/styles/05-objects/_objects.block.scss +122 -0
- package/src/styles/05-objects/_objects.container.scss +14 -10
- package/src/styles/05-objects/_objects.grid.scss +0 -0
- package/src/styles/05-objects/_objects.masonry-grid.scss +0 -0
- package/src/styles/06-components/_components.accordion.scss +3 -1
- package/src/styles/06-components/_components.avatar-group.scss +0 -0
- package/src/styles/06-components/_components.avatar.scss +0 -0
- package/src/styles/06-components/_components.badge.scss +9 -9
- package/src/styles/06-components/_components.breadcrumb.scss +0 -0
- package/src/styles/06-components/_components.btn-group.scss +0 -0
- package/src/styles/06-components/_components.button.scss +0 -0
- package/src/styles/06-components/_components.callout.scss +2 -1
- package/src/styles/06-components/_components.card.scss +0 -1
- package/src/styles/06-components/_components.chart.scss +2102 -0
- package/src/styles/06-components/_components.checkbox-group.scss +0 -0
- package/src/styles/06-components/_components.checkbox.scss +0 -0
- package/src/styles/06-components/_components.color-mode-toggle.scss +0 -0
- package/src/styles/06-components/_components.countdown.scss +0 -0
- package/src/styles/06-components/_components.data-table.scss +0 -0
- package/src/styles/06-components/_components.datepicker.scss +0 -0
- package/src/styles/06-components/_components.dropdown.scss +0 -0
- package/src/styles/06-components/_components.edge-panel.scss +0 -0
- package/src/styles/06-components/_components.form-group.scss +0 -0
- package/src/styles/06-components/_components.form.scss +0 -0
- package/src/styles/06-components/_components.hero.scss +1 -0
- package/src/styles/06-components/_components.icon.scss +2 -2
- package/src/styles/06-components/_components.image-gallery.scss +0 -0
- package/src/styles/06-components/_components.input.scss +0 -0
- package/src/styles/06-components/_components.list-group.scss +0 -0
- package/src/styles/06-components/_components.list.scss +0 -0
- package/src/styles/06-components/_components.menu.scss +0 -0
- package/src/styles/06-components/_components.messages.scss +0 -0
- package/src/styles/06-components/_components.modal.scss +3 -0
- package/src/styles/06-components/_components.nav.scss +0 -0
- package/src/styles/06-components/_components.navbar.scss +0 -0
- package/src/styles/06-components/_components.pagination.scss +0 -0
- package/src/styles/06-components/_components.photoviewer.scss +603 -545
- package/src/styles/06-components/_components.popover.scss +0 -0
- package/src/styles/06-components/_components.product-review.scss +0 -0
- package/src/styles/06-components/_components.progress.scss +0 -0
- package/src/styles/06-components/_components.rating.scss +0 -0
- package/src/styles/06-components/_components.river.scss +0 -0
- package/src/styles/06-components/_components.sectionintro.scss +0 -0
- package/src/styles/06-components/_components.select.scss +0 -0
- package/src/styles/06-components/_components.side-menu.scss +0 -0
- package/src/styles/06-components/_components.skeleton.scss +0 -0
- package/src/styles/06-components/_components.slider.scss +273 -0
- package/src/styles/06-components/_components.spinner.scss +0 -0
- package/src/styles/06-components/_components.steps.scss +1 -0
- package/src/styles/06-components/_components.tabs.scss +0 -0
- package/src/styles/06-components/_components.testimonials.scss +0 -0
- package/src/styles/06-components/_components.todo.scss +0 -0
- package/src/styles/06-components/_components.toggle.scss +0 -0
- package/src/styles/06-components/_components.tooltip.scss +4 -9
- package/src/styles/06-components/_components.upload.scss +0 -0
- package/src/styles/06-components/_components.video-player.scss +623 -0
- package/src/styles/06-components/_index.scss +3 -0
- package/src/styles/06-components/old.chart.styles.scss +2819 -0
- package/src/styles/99-utilities/_index.scss +0 -0
- package/src/styles/99-utilities/_utilities.background.scss +0 -0
- package/src/styles/99-utilities/_utilities.border.scss +0 -0
- package/src/styles/99-utilities/_utilities.clearfix.scss +0 -0
- package/src/styles/99-utilities/_utilities.display.scss +0 -0
- package/src/styles/99-utilities/_utilities.flex.scss +0 -0
- package/src/styles/99-utilities/_utilities.link.scss +0 -0
- package/src/styles/99-utilities/_utilities.object-fit.scss +0 -0
- package/src/styles/99-utilities/_utilities.opacity.scss +0 -0
- package/src/styles/99-utilities/_utilities.overflow.scss +0 -0
- package/src/styles/99-utilities/_utilities.position.scss +0 -0
- package/src/styles/99-utilities/_utilities.scss +2 -1
- package/src/styles/99-utilities/_utilities.shadow.scss +0 -0
- package/src/styles/99-utilities/_utilities.sizes.scss +0 -0
- package/src/styles/99-utilities/_utilities.spacing.scss +0 -0
- package/src/styles/99-utilities/_utilities.text.scss +5 -0
- package/src/styles/99-utilities/_utilities.visibility.scss +0 -0
- package/src/styles/99-utilities/_utilities.visually-hidden.scss +0 -0
- package/src/styles/99-utilities/_utilities.z-index.scss +0 -0
- package/src/styles/css-modules.d.ts +0 -0
- package/src/styles/index.scss +0 -0
- package/dist/index.css +0 -15
- package/dist/index.esm.css +0 -15
- package/dist/index.min.css +0 -15
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
HTMLAttributes,
|
|
4
|
+
ReactNode,
|
|
5
|
+
useEffect,
|
|
6
|
+
useImperativeHandle,
|
|
7
|
+
useRef,
|
|
8
|
+
useState,
|
|
9
|
+
useCallback,
|
|
10
|
+
useMemo,
|
|
11
|
+
Children,
|
|
12
|
+
cloneElement,
|
|
13
|
+
isValidElement,
|
|
14
|
+
} from 'react';
|
|
15
|
+
// Import styles for scoped CSS modules
|
|
16
|
+
|
|
17
|
+
export interface MasonryGridProps extends HTMLAttributes<HTMLDivElement> {
|
|
18
|
+
/**
|
|
19
|
+
* The content to be rendered within the masonry grid
|
|
20
|
+
*/
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
/**
|
|
23
|
+
* Additional CSS class names
|
|
24
|
+
*/
|
|
25
|
+
className?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Number of columns at extra small breakpoint (default)
|
|
28
|
+
*/
|
|
29
|
+
xs?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Number of columns at small breakpoint
|
|
32
|
+
*/
|
|
33
|
+
sm?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Number of columns at medium breakpoint
|
|
36
|
+
*/
|
|
37
|
+
md?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Number of columns at large breakpoint
|
|
40
|
+
*/
|
|
41
|
+
lg?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Number of columns at extra large breakpoint
|
|
44
|
+
*/
|
|
45
|
+
xl?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Number of columns at extra extra large breakpoint
|
|
48
|
+
*/
|
|
49
|
+
xxl?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Gap between items (in pixels)
|
|
52
|
+
*/
|
|
53
|
+
gap?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Whether to animate item transitions
|
|
56
|
+
*/
|
|
57
|
+
animate?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Whether to handle image loading to prevent layout shifts
|
|
60
|
+
* When true, items will be shown immediately and positions updated as images load
|
|
61
|
+
*/
|
|
62
|
+
imagesLoaded?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Callback fired when all images are loaded and layout is complete
|
|
65
|
+
*/
|
|
66
|
+
onLayoutComplete?: () => void;
|
|
67
|
+
/**
|
|
68
|
+
* Callback fired each time an image loads and layout is updated
|
|
69
|
+
*/
|
|
70
|
+
onImageLoad?: (loadedCount: number, totalCount: number) => void;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
interface ItemPosition {
|
|
74
|
+
left: number;
|
|
75
|
+
top: number;
|
|
76
|
+
width: number;
|
|
77
|
+
height: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
interface MasonryItemData {
|
|
81
|
+
element: React.ReactElement;
|
|
82
|
+
position: ItemPosition | null;
|
|
83
|
+
ref: React.RefObject<HTMLDivElement | null>;
|
|
84
|
+
id: string;
|
|
85
|
+
imageLoaded?: boolean;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* MasonryGrid component for creating a responsive masonry layout.
|
|
90
|
+
* Uses JavaScript to position items optimally based on available vertical space,
|
|
91
|
+
* similar to how a mason fits stones in a wall.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```tsx
|
|
95
|
+
* <MasonryGrid xs={1} sm={2} md={3} lg={4}>
|
|
96
|
+
* <MasonryGridItem>Item 1</MasonryGridItem>
|
|
97
|
+
* <MasonryGridItem>Item 2</MasonryGridItem>
|
|
98
|
+
* <MasonryGridItem>Item 3</MasonryGridItem>
|
|
99
|
+
* </MasonryGrid>
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export const MasonryGrid = forwardRef<HTMLDivElement, MasonryGridProps>(
|
|
103
|
+
(
|
|
104
|
+
{
|
|
105
|
+
children,
|
|
106
|
+
className = '',
|
|
107
|
+
xs = 1,
|
|
108
|
+
sm,
|
|
109
|
+
md,
|
|
110
|
+
lg,
|
|
111
|
+
xl,
|
|
112
|
+
xxl,
|
|
113
|
+
gap = 16,
|
|
114
|
+
animate = true,
|
|
115
|
+
imagesLoaded = true,
|
|
116
|
+
onLayoutComplete,
|
|
117
|
+
onImageLoad,
|
|
118
|
+
...props
|
|
119
|
+
},
|
|
120
|
+
ref
|
|
121
|
+
) => {
|
|
122
|
+
// === REFS & STATE ===
|
|
123
|
+
const [columns, setColumns] = useState(xs);
|
|
124
|
+
const [positions, setPositions] = useState<ItemPosition[]>([]);
|
|
125
|
+
const [layoutComplete, setLayoutComplete] = useState(false);
|
|
126
|
+
const [loadingImages, setLoadingImages] = useState(false);
|
|
127
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
128
|
+
const columnHeights = useRef<number[]>([]);
|
|
129
|
+
const imagesLoadedCount = useRef(0);
|
|
130
|
+
const totalImagesCount = useRef(0);
|
|
131
|
+
const imageElements = useRef<Map<HTMLImageElement, boolean>>(new Map());
|
|
132
|
+
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
if (imagesLoaded) setLoadingImages(true);
|
|
135
|
+
else setLoadingImages(false);
|
|
136
|
+
}, [columns, imagesLoaded]);
|
|
137
|
+
|
|
138
|
+
// Types
|
|
139
|
+
type MasonryImageElement = HTMLImageElement & {
|
|
140
|
+
_masonryLoadHandler?: EventListener;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// Forward ref for parent components
|
|
144
|
+
useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);
|
|
145
|
+
|
|
146
|
+
// === HANDLE RESPONSIVE COLUMNS ===
|
|
147
|
+
const getResponsiveColumns = useCallback(() => {
|
|
148
|
+
const width = window.innerWidth;
|
|
149
|
+
if (width >= 1400 && xxl !== undefined) return xxl;
|
|
150
|
+
if (width >= 1200 && xl !== undefined) return xl;
|
|
151
|
+
if (width >= 992 && lg !== undefined) return lg;
|
|
152
|
+
if (width >= 768 && md !== undefined) return md;
|
|
153
|
+
if (width >= 576 && sm !== undefined) return sm;
|
|
154
|
+
return xs;
|
|
155
|
+
}, [xs, sm, md, lg, xl, xxl]);
|
|
156
|
+
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
const handleResize = () => setColumns(getResponsiveColumns());
|
|
159
|
+
handleResize(); // Set on mount
|
|
160
|
+
window.addEventListener('resize', handleResize);
|
|
161
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
162
|
+
}, [getResponsiveColumns]);
|
|
163
|
+
|
|
164
|
+
// === PREPARE ITEMS WITH REFS ===
|
|
165
|
+
const [items, setItems] = useState<MasonryItemData[]>([]);
|
|
166
|
+
|
|
167
|
+
useEffect(() => {
|
|
168
|
+
const newItems: MasonryItemData[] = [];
|
|
169
|
+
Children.forEach(children, (child, index) => {
|
|
170
|
+
if (!isValidElement(child)) return;
|
|
171
|
+
newItems.push({
|
|
172
|
+
id: child.key?.toString() || `masonry-item-${index}`,
|
|
173
|
+
element: child,
|
|
174
|
+
position: null,
|
|
175
|
+
ref: React.createRef<HTMLDivElement>(),
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
setItems(newItems);
|
|
179
|
+
}, [children]);
|
|
180
|
+
|
|
181
|
+
// === TRACK & MANAGE IMAGES ===
|
|
182
|
+
|
|
183
|
+
const handleImageLoad = useCallback(
|
|
184
|
+
(img: HTMLImageElement) => {
|
|
185
|
+
if (imageElements.current.get(img)) return;
|
|
186
|
+
imageElements.current.set(img, true);
|
|
187
|
+
imagesLoadedCount.current += 1;
|
|
188
|
+
// Add loaded class for animation
|
|
189
|
+
if (containerRef.current && imagesLoaded) {
|
|
190
|
+
const itemElement = img.closest('.o-masonry-grid > div');
|
|
191
|
+
if (itemElement) {
|
|
192
|
+
// FORCE a sync browser reflow so offsetHeight reflects the new image size before measuring Masonry
|
|
193
|
+
void (itemElement as HTMLElement).offsetHeight;
|
|
194
|
+
itemElement.classList.add('o-masonry-grid__item-loaded');
|
|
195
|
+
itemElement.classList.remove('o-masonry-grid__item-loading');
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Ensure layout is recalculated after DOM paints the item image (prevents overlap on slow/late image loads)
|
|
199
|
+
requestAnimationFrame(() => {
|
|
200
|
+
requestAnimationFrame(() => {
|
|
201
|
+
calculateLayout();
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
onImageLoad?.(imagesLoadedCount.current, totalImagesCount.current);
|
|
205
|
+
|
|
206
|
+
// If all images have loaded, update loading state and complete layout
|
|
207
|
+
if (imagesLoadedCount.current >= totalImagesCount.current && totalImagesCount.current > 0) {
|
|
208
|
+
setLayoutComplete(true);
|
|
209
|
+
setLoadingImages(false); // This ensures the loading class is removed *immediately* after images load
|
|
210
|
+
// Force a double requestAnimationFrame for final layout calculation after all images are loaded (guarantees DOM paint)
|
|
211
|
+
requestAnimationFrame(() => {
|
|
212
|
+
requestAnimationFrame(() => {
|
|
213
|
+
calculateLayout();
|
|
214
|
+
// As a failsafe, if still present for some render lag, force another setLoadingImages(false)
|
|
215
|
+
setLoadingImages(false);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
onLayoutComplete?.();
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
[onImageLoad, onLayoutComplete, imagesLoaded]
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
const trackImages = useCallback(() => {
|
|
225
|
+
if (!imagesLoaded || !containerRef.current) return undefined;
|
|
226
|
+
imageElements.current.clear();
|
|
227
|
+
imagesLoadedCount.current = 0;
|
|
228
|
+
const images = containerRef.current.querySelectorAll('img');
|
|
229
|
+
totalImagesCount.current = images.length;
|
|
230
|
+
if (images.length === 0) {
|
|
231
|
+
setLayoutComplete(true);
|
|
232
|
+
setLoadingImages(false);
|
|
233
|
+
onLayoutComplete?.();
|
|
234
|
+
return undefined;
|
|
235
|
+
}
|
|
236
|
+
setLoadingImages(true);
|
|
237
|
+
images.forEach(img => {
|
|
238
|
+
const masonryImg = img as MasonryImageElement;
|
|
239
|
+
const itemElement = img.closest('.o-masonry-grid > div');
|
|
240
|
+
if (itemElement) {
|
|
241
|
+
itemElement.classList.add('o-masonry-grid__item-loading');
|
|
242
|
+
}
|
|
243
|
+
if (img.complete) {
|
|
244
|
+
handleImageLoad(img);
|
|
245
|
+
} else {
|
|
246
|
+
const loadHandler = () => handleImageLoad(img);
|
|
247
|
+
img.addEventListener('load', loadHandler);
|
|
248
|
+
img.addEventListener('error', loadHandler);
|
|
249
|
+
masonryImg._masonryLoadHandler = loadHandler;
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
// Cleanup
|
|
253
|
+
return () => {
|
|
254
|
+
images.forEach(img => {
|
|
255
|
+
const masonryImg = img as MasonryImageElement;
|
|
256
|
+
if (masonryImg._masonryLoadHandler) {
|
|
257
|
+
img.removeEventListener('load', masonryImg._masonryLoadHandler);
|
|
258
|
+
img.removeEventListener('error', masonryImg._masonryLoadHandler);
|
|
259
|
+
delete masonryImg._masonryLoadHandler;
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
};
|
|
263
|
+
}, [imagesLoaded, handleImageLoad, onLayoutComplete]);
|
|
264
|
+
|
|
265
|
+
// === MANAGE ITEM LAYOUT ===
|
|
266
|
+
const calculateLayout = useCallback(() => {
|
|
267
|
+
if (!containerRef.current || items.length === 0) return;
|
|
268
|
+
const containerWidth = containerRef.current.offsetWidth;
|
|
269
|
+
const colWidth = (containerWidth - gap * (columns - 1)) / columns;
|
|
270
|
+
columnHeights.current = Array(columns).fill(0);
|
|
271
|
+
const newPositions: ItemPosition[] = [];
|
|
272
|
+
items.forEach((item, index) => {
|
|
273
|
+
if (item.ref.current) {
|
|
274
|
+
// Find the shortest column
|
|
275
|
+
const shortestCol = columnHeights.current.indexOf(Math.min(...columnHeights.current));
|
|
276
|
+
const left = shortestCol * (colWidth + gap);
|
|
277
|
+
const top = columnHeights.current[shortestCol] ?? 0;
|
|
278
|
+
const height = item.ref.current.offsetHeight;
|
|
279
|
+
columnHeights.current[shortestCol] = top + height + gap;
|
|
280
|
+
newPositions[index] = {
|
|
281
|
+
left,
|
|
282
|
+
top,
|
|
283
|
+
width: colWidth,
|
|
284
|
+
height,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
setPositions(newPositions);
|
|
289
|
+
}, [items, columns, gap]);
|
|
290
|
+
|
|
291
|
+
// === OBSERVE CONTAINER RESIZE ===
|
|
292
|
+
useEffect(() => {
|
|
293
|
+
if (!containerRef.current) return undefined;
|
|
294
|
+
let animationFrame: ReturnType<typeof requestAnimationFrame> | null = null;
|
|
295
|
+
const observer = new ResizeObserver(() => {
|
|
296
|
+
if (animationFrame) cancelAnimationFrame(animationFrame);
|
|
297
|
+
animationFrame = requestAnimationFrame(() => calculateLayout());
|
|
298
|
+
});
|
|
299
|
+
observer.observe(containerRef.current);
|
|
300
|
+
return () => {
|
|
301
|
+
observer.disconnect();
|
|
302
|
+
if (animationFrame) cancelAnimationFrame(animationFrame);
|
|
303
|
+
};
|
|
304
|
+
}, [calculateLayout]);
|
|
305
|
+
|
|
306
|
+
// === LAYOUT EFFECT (REPLACES setTimeout) ===
|
|
307
|
+
React.useLayoutEffect(() => {
|
|
308
|
+
if (imagesLoaded) {
|
|
309
|
+
const cleanup = trackImages();
|
|
310
|
+
return cleanup;
|
|
311
|
+
} else {
|
|
312
|
+
calculateLayout();
|
|
313
|
+
setLayoutComplete(true);
|
|
314
|
+
setLoadingImages(false);
|
|
315
|
+
return undefined;
|
|
316
|
+
}
|
|
317
|
+
// Only reset layoutComplete when items or columns change
|
|
318
|
+
}, [items, columns, calculateLayout, imagesLoaded, trackImages]);
|
|
319
|
+
|
|
320
|
+
// === NEW: Add ResizeObservers to all grid items for bulletproof image+content measurement ===
|
|
321
|
+
React.useEffect(() => {
|
|
322
|
+
// Clean up old observers if items ever change
|
|
323
|
+
const observers: ResizeObserver[] = [];
|
|
324
|
+
items.forEach(item => {
|
|
325
|
+
if (item.ref.current) {
|
|
326
|
+
const obs = new ResizeObserver(() => {
|
|
327
|
+
// Double rAF: ensures layout only runs after DOM/paint/async renders
|
|
328
|
+
requestAnimationFrame(() => {
|
|
329
|
+
requestAnimationFrame(() => {
|
|
330
|
+
calculateLayout();
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
obs.observe(item.ref.current);
|
|
335
|
+
observers.push(obs);
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
return () => {
|
|
339
|
+
observers.forEach(obs => obs.disconnect());
|
|
340
|
+
};
|
|
341
|
+
}, [items, calculateLayout]);
|
|
342
|
+
|
|
343
|
+
// Ensure loadingImages state resets when items/columns/imagesLoaded change
|
|
344
|
+
|
|
345
|
+
// === DETERMINE CONTAINER HEIGHT ===
|
|
346
|
+
const containerHeight =
|
|
347
|
+
columnHeights.current.length > 0 ? Math.max(...columnHeights.current) : 0;
|
|
348
|
+
|
|
349
|
+
// === DETERMINE CLASSES ===
|
|
350
|
+
const classes = [
|
|
351
|
+
'o-masonry-grid',
|
|
352
|
+
className,
|
|
353
|
+
animate ? 'o-masonry-grid--animate' : '',
|
|
354
|
+
loadingImages ? 'o-masonry-grid--loading-images' : '',
|
|
355
|
+
]
|
|
356
|
+
.filter(Boolean)
|
|
357
|
+
.join(' ');
|
|
358
|
+
|
|
359
|
+
// === RENDER ===
|
|
360
|
+
|
|
361
|
+
return (
|
|
362
|
+
<div
|
|
363
|
+
ref={containerRef}
|
|
364
|
+
className={classes}
|
|
365
|
+
style={{
|
|
366
|
+
position: 'relative',
|
|
367
|
+
width: '100%',
|
|
368
|
+
height: `${containerHeight}px`,
|
|
369
|
+
...props.style,
|
|
370
|
+
}}
|
|
371
|
+
{...props}
|
|
372
|
+
>
|
|
373
|
+
{items.map((item, index) => {
|
|
374
|
+
const position = positions[index];
|
|
375
|
+
if (!position) {
|
|
376
|
+
return (
|
|
377
|
+
<div key={item.id} ref={item.ref} style={{ opacity: 0, position: 'absolute' }}>
|
|
378
|
+
{item.element}
|
|
379
|
+
</div>
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
return (
|
|
383
|
+
<div
|
|
384
|
+
key={item.id}
|
|
385
|
+
ref={item.ref}
|
|
386
|
+
className="o-masonry-grid__item"
|
|
387
|
+
style={{
|
|
388
|
+
position: 'absolute',
|
|
389
|
+
left: `${position.left}px`,
|
|
390
|
+
top: `${position.top}px`,
|
|
391
|
+
width: `${position.width}px`,
|
|
392
|
+
opacity: 1,
|
|
393
|
+
}}
|
|
394
|
+
>
|
|
395
|
+
{item.element}
|
|
396
|
+
</div>
|
|
397
|
+
);
|
|
398
|
+
})}
|
|
399
|
+
</div>
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
MasonryGrid.displayName = 'MasonryGrid';
|
|
405
|
+
|
|
406
|
+
export default MasonryGrid;
|
|
407
|
+
|
|
408
|
+
// Ensure loadingImages state resets when items/columns/imagesLoaded change
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React, { forwardRef, HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface MasonryGridItemProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
/**
|
|
5
|
+
* The content to be rendered within the masonry grid item
|
|
6
|
+
*/
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Additional CSS class names
|
|
10
|
+
*/
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* MasonryGridItem component for creating items within a MasonryGrid.
|
|
16
|
+
* Each item will be positioned optimally by the parent MasonryGrid component.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <MasonryGrid>
|
|
21
|
+
* <MasonryGridItem>Item 1</MasonryGridItem>
|
|
22
|
+
* <MasonryGridItem>Item 2</MasonryGridItem>
|
|
23
|
+
* </MasonryGrid>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export const MasonryGridItem = forwardRef<HTMLDivElement, MasonryGridItemProps>(
|
|
27
|
+
({ children, className = '', ...props }, ref) => {
|
|
28
|
+
const classes = ['o-masonry-grid__item-inner'];
|
|
29
|
+
|
|
30
|
+
if (className) {
|
|
31
|
+
classes.push(className);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div ref={ref} className={classes.join(' ')} {...props}>
|
|
36
|
+
{children}
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
MasonryGridItem.displayName = 'MasonryGridItem';
|
|
43
|
+
|
|
44
|
+
export default MasonryGridItem;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Masonry Grid
|
|
2
|
+
|
|
3
|
+
A responsive masonry grid layout component for creating Pinterest-like grid layouts with items of varying heights.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
The MasonryGrid component creates a responsive grid layout that arranges items optimally based on their height, similar to Pinterest or other masonry-style layouts.
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
import { MasonryGrid, MasonryGridItem } from './MasonryGrid';
|
|
11
|
+
|
|
12
|
+
<MasonryGrid xs={1} sm={2} md={3} lg={4}>
|
|
13
|
+
<MasonryGridItem>
|
|
14
|
+
<div>Item 1</div>
|
|
15
|
+
</MasonryGridItem>
|
|
16
|
+
<MasonryGridItem>
|
|
17
|
+
<div>Item 2</div>
|
|
18
|
+
</MasonryGridItem>
|
|
19
|
+
<MasonryGridItem>
|
|
20
|
+
<div>Item 3</div>
|
|
21
|
+
</MasonryGridItem>
|
|
22
|
+
</MasonryGrid>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Props
|
|
26
|
+
|
|
27
|
+
### MasonryGrid
|
|
28
|
+
|
|
29
|
+
| Prop | Type | Default | Description |
|
|
30
|
+
|------|------|---------|-------------|
|
|
31
|
+
| `xs` | `number` | `1` | Number of columns at extra small breakpoint (default) |
|
|
32
|
+
| `sm` | `number` | - | Number of columns at small breakpoint |
|
|
33
|
+
| `md` | `number` | - | Number of columns at medium breakpoint |
|
|
34
|
+
| `lg` | `number` | - | Number of columns at large breakpoint |
|
|
35
|
+
| `xl` | `number` | - | Number of columns at extra large breakpoint |
|
|
36
|
+
| `xxl` | `number` | - | Number of columns at extra extra large breakpoint |
|
|
37
|
+
| `gap` | `number` | `16` | Gap between items (in pixels) |
|
|
38
|
+
| `className` | `string` | - | Additional CSS class names |
|
|
39
|
+
|
|
40
|
+
### MasonryGridItem
|
|
41
|
+
|
|
42
|
+
| Prop | Type | Default | Description |
|
|
43
|
+
|------|------|---------|-------------|
|
|
44
|
+
| `className` | `string` | - | Additional CSS class names |
|
|
45
|
+
|
|
46
|
+
## Examples
|
|
47
|
+
|
|
48
|
+
### Basic Masonry Grid
|
|
49
|
+
|
|
50
|
+
```jsx
|
|
51
|
+
<MasonryGrid xs={1} sm={2} md={3} lg={4}>
|
|
52
|
+
<MasonryGridItem>
|
|
53
|
+
<div>Item 1</div>
|
|
54
|
+
</MasonryGridItem>
|
|
55
|
+
<MasonryGridItem>
|
|
56
|
+
<div>Item 2</div>
|
|
57
|
+
</MasonryGridItem>
|
|
58
|
+
<MasonryGridItem>
|
|
59
|
+
<div>Item 3</div>
|
|
60
|
+
</MasonryGridItem>
|
|
61
|
+
</MasonryGrid>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Custom Gap
|
|
65
|
+
|
|
66
|
+
```jsx
|
|
67
|
+
<MasonryGrid xs={1} sm={2} md={3} lg={4} gap={24}>
|
|
68
|
+
<MasonryGridItem>
|
|
69
|
+
<div>Item 1</div>
|
|
70
|
+
</MasonryGridItem>
|
|
71
|
+
<MasonryGridItem>
|
|
72
|
+
<div>Item 2</div>
|
|
73
|
+
</MasonryGridItem>
|
|
74
|
+
</MasonryGrid>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Custom Column Configuration
|
|
78
|
+
|
|
79
|
+
```jsx
|
|
80
|
+
<MasonryGrid xs={1} sm={2} md={2} lg={3} xl={4} xxl={5}>
|
|
81
|
+
<MasonryGridItem>
|
|
82
|
+
<div>Item 1</div>
|
|
83
|
+
</MasonryGridItem>
|
|
84
|
+
<MasonryGridItem>
|
|
85
|
+
<div>Item 2</div>
|
|
86
|
+
</MasonryGridItem>
|
|
87
|
+
</MasonryGrid>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Styling
|
|
91
|
+
|
|
92
|
+
The MasonryGrid component uses CSS Grid to create the masonry layout. You can customize the appearance by modifying the following SCSS variables:
|
|
93
|
+
|
|
94
|
+
```scss
|
|
95
|
+
// In your theme file or custom styles
|
|
96
|
+
$masonry-grid-gap: 16px;
|
|
97
|
+
$masonry-grid-gap-sm: 8px;
|
|
98
|
+
$masonry-grid-gap-lg: 24px;
|
|
99
|
+
$masonry-grid-columns-xs: 1;
|
|
100
|
+
$masonry-grid-columns-sm: 2;
|
|
101
|
+
$masonry-grid-columns-md: 3;
|
|
102
|
+
$masonry-grid-columns-lg: 4;
|
|
103
|
+
$masonry-grid-columns-xl: 4;
|
|
104
|
+
$masonry-grid-columns-xxl: 5;
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Accessibility
|
|
108
|
+
|
|
109
|
+
The MasonryGrid component is built with accessibility in mind:
|
|
110
|
+
|
|
111
|
+
- It uses semantic HTML elements
|
|
112
|
+
- It maintains proper focus management
|
|
113
|
+
- It ensures content is readable at various screen sizes
|
|
114
|
+
|
|
115
|
+
## Browser Support
|
|
116
|
+
|
|
117
|
+
The MasonryGrid component uses CSS Grid, which is supported in all modern browsers. For older browsers, it will gracefully degrade to a single-column layout.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Export Grid components
|
|
2
|
+
export { Grid, GridCol, Container, Row } from './Grid';
|
|
3
|
+
export type { GridProps, GridColProps, ContainerProps, RowProps } from './Grid';
|
|
4
|
+
|
|
5
|
+
// Export MasonryGrid components
|
|
6
|
+
export { MasonryGrid, MasonryGridItem } from './MasonryGrid';
|
|
7
|
+
export type { MasonryGridProps, MasonryGridItemProps } from './MasonryGrid';
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Component Library TypeScript Functionality
|
|
2
|
+
|
|
3
|
+
This directory contains TypeScript functionality for component behaviors, interactions, and utilities.
|
|
4
|
+
|
|
5
|
+
## Directory Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/
|
|
9
|
+
├── components/ # UI Components
|
|
10
|
+
│ ├── ComponentName/ # Individual component folders
|
|
11
|
+
│ │ ├── scripts/ # Component-specific scripts
|
|
12
|
+
│ │ │ ├── index.ts # Exports all component functionality
|
|
13
|
+
│ │ │ └── componentInteractions.ts # Component-specific interactions
|
|
14
|
+
│ │ ├── ComponentName.tsx # Component React implementation
|
|
15
|
+
│ │ └── ComponentName.stories.tsx # Storybook stories
|
|
16
|
+
│ └── ...
|
|
17
|
+
│
|
|
18
|
+
├── lib/ # Shared functionality
|
|
19
|
+
│ ├── composables/ # Reusable component logic hooks
|
|
20
|
+
│ │ ├── index.ts # Export all composables
|
|
21
|
+
│ │ └── useComponent.ts # Component-specific composable
|
|
22
|
+
│ │
|
|
23
|
+
│ ├── utils/ # Utility functions
|
|
24
|
+
│ │ ├── index.ts # Export all utilities
|
|
25
|
+
│ │ └── dom.ts # DOM manipulation utilities
|
|
26
|
+
│ │
|
|
27
|
+
│ ├── types/ # TypeScript type definitions
|
|
28
|
+
│ │ ├── index.ts # Export all types
|
|
29
|
+
│ │ └── components.ts # Component-related type definitions
|
|
30
|
+
│ │
|
|
31
|
+
│ └── constants/ # Constant values
|
|
32
|
+
│ ├── index.ts # Export all constants
|
|
33
|
+
│ └── components.ts # Component-related constants
|
|
34
|
+
│
|
|
35
|
+
└── main.ts # Entry point that initializes components
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
### Composables
|
|
41
|
+
|
|
42
|
+
Composables are reusable pieces of component logic that can be shared across components.
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { useButton } from '../lib/composables/useButton';
|
|
46
|
+
|
|
47
|
+
// In your component
|
|
48
|
+
const { generateButtonClass, handleClick } = useButton();
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Component Interactions
|
|
52
|
+
|
|
53
|
+
Component scripts handle direct DOM interactions:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { initializeButton } from './components/Button/scripts';
|
|
57
|
+
|
|
58
|
+
// Initialize a button element
|
|
59
|
+
const buttonElement = document.querySelector('.c-btn');
|
|
60
|
+
if (buttonElement) {
|
|
61
|
+
initializeButton(buttonElement);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Utilities
|
|
66
|
+
|
|
67
|
+
Utility functions provide common functionality:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { addClass, removeClass } from '../lib/utils/dom';
|
|
71
|
+
|
|
72
|
+
// Add a class to an element
|
|
73
|
+
addClass(element, 'is-active');
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Adding New Component Functionality
|
|
77
|
+
|
|
78
|
+
1. Create composables for reusable logic
|
|
79
|
+
2. Add component-specific scripts in the component folder
|
|
80
|
+
3. Define types in the types folder
|
|
81
|
+
4. Update main.ts to initialize your component
|
|
82
|
+
|
|
83
|
+
## Best Practices
|
|
84
|
+
|
|
85
|
+
- Keep functionality modular and focused
|
|
86
|
+
- Follow the established folder structure
|
|
87
|
+
- Document functions with JSDoc comments
|
|
88
|
+
- Use TypeScript types for better code completion
|
|
89
|
+
- Export components through index files
|