Skip to content

Commit 6c702ef

Browse files
committed
feat: enhance Masonry component with reposition functionality
- Added a `reposition` method to the Masonry component, allowing for dynamic layout adjustments. - Updated MasonryRoot to utilize the new ref for repositioning when photos change. - Introduced a new script command "web" in package.json for easier development with Vite. Signed-off-by: Innei <tukon479@gmail.com>
1 parent 440e051 commit 6c702ef

3 files changed

Lines changed: 25 additions & 3 deletions

File tree

apps/web/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"format": "prettier --write \"src/**/*.ts\" ",
1515
"lint": "eslint --fix",
1616
"serve": "vite preview",
17-
"type-check": "tsc --noEmit"
17+
"type-check": "tsc --noEmit",
18+
"web": "vite"
1819
},
1920
"dependencies": {
2021
"@afilmory/data": "workspace:*",

apps/web/src/modules/gallery/Masonic.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import * as React from 'react'
2222

2323
import { useScrollViewElement } from '~/components/ui/scroll-areas/hooks'
2424

25+
export interface MasonryRef {
26+
reposition: () => void
27+
}
2528
/**
2629
* A "batteries included" masonry grid which includes all of the implementation details below. This component is the
2730
* easiest way to get off and running in your app, before switching to more advanced implementations, if necessary.
@@ -30,7 +33,9 @@ import { useScrollViewElement } from '~/components/ui/scroll-areas/hooks'
3033
*
3134
* @param props
3235
*/
33-
export const Masonry = <Item,>(props: MasonryProps<Item>) => {
36+
export const Masonry = <Item,>(
37+
props: MasonryProps<Item> & { ref?: React.Ref<MasonryRef> },
38+
) => {
3439
const [scrollTop, setScrollTop] = React.useState(0)
3540
const [isScrolling, setIsScrolling] = React.useState(false)
3641
const scrollElement = useScrollViewElement()
@@ -91,6 +96,14 @@ export const Masonry = <Item,>(props: MasonryProps<Item>) => {
9196
props,
9297
) as any
9398

99+
const [positionIndex, setPositionIndex] = React.useState(0)
100+
101+
React.useImperativeHandle(props.ref, () => ({
102+
reposition: () => {
103+
setPositionIndex((i) => i + 1)
104+
},
105+
}))
106+
94107
// Workaround for https://github.com/jaredLunde/masonic/issues/12
95108
const itemCounter = React.useRef<number>(props.items.length)
96109

@@ -102,7 +115,9 @@ export const Masonry = <Item,>(props: MasonryProps<Item>) => {
102115
itemCounter.current = props.items.length
103116
}
104117

105-
nextProps.positioner = usePositioner(nextProps, [shrunk && Math.random()])
118+
nextProps.positioner = usePositioner(nextProps, [
119+
shrunk ? Math.random() + positionIndex : positionIndex,
120+
])
106121

107122
nextProps.resizeObserver = useResizeObserver(nextProps.positioner)
108123
nextProps.scrollTop = scrollTop

apps/web/src/modules/gallery/MasonryRoot.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type { PhotoManifest } from '~/types/photo'
1616
import type { ActionType } from './ActionGroup'
1717
import { ActionGroup, ActionPanel } from './ActionGroup'
1818
import { FloatingActionButton } from './FloatingActionButton'
19+
import type { MasonryRef } from './Masonic'
1920
import { Masonry } from './Masonic'
2021
import { MasonryHeaderMasonryItem } from './MasonryHeaderMasonryItem'
2122
import { MasonryPhotoItem } from './MasonryPhotoItem'
@@ -51,6 +52,10 @@ export const MasonryRoot = () => {
5152
const [containerWidth, setContainerWidth] = useState(0)
5253

5354
const photos = usePhotos()
55+
const masonryRef = useRef<MasonryRef>(null)
56+
// useEffect(() => {
57+
// nextFrame(() => masonryRef.current?.reposition())
58+
// }, [photos])
5459
const { dateRange, handleRender } = useVisiblePhotosDateRange(photos)
5560
const scrollElement = useScrollViewElement()
5661

@@ -163,6 +168,7 @@ export const MasonryRoot = () => {
163168
<div className="p-1 lg:px-0 lg:pb-0 [&_*]:!select-none">
164169
{isMobile && <MasonryHeaderMasonryItem className="mb-1" />}
165170
<Masonry<MasonryItemType>
171+
ref={masonryRef}
166172
items={useMemo(
167173
() => (isMobile ? photos : [MasonryHeaderItem.default, ...photos]),
168174
[photos, isMobile],

0 commit comments

Comments
 (0)