Skip to content

Commit 2fa0c3c

Browse files
committed
fix(masory-wall): update rtl handling to support variable column widths
1 parent 141ec22 commit 2fa0c3c

File tree

3 files changed

+23
-14
lines changed

3 files changed

+23
-14
lines changed

.changeset/wacky-meteors-eat.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@yeger/vue-masonry-wall': patch
3+
---
4+
5+
update rtl handling to support variable column widths

packages/vue-masonry-wall/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ For images, specifying aspect ratios can prevent unbalanced distributions.
104104
All columns have the same width, specified by the `column-width` property.
105105
In addition, the elements of items should not set a specific width and instead be full-width, e.g., use `width: 100%`.
106106

107-
### Nuxt 3
107+
### Nuxt
108108

109109
See <https://github.com/DerYeger/yeger/issues/43>.
110110

packages/vue-masonry-wall/src/masonry-wall.vue

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="ts" generic="T">
22
import { debounce } from '@yeger/debounce'
3-
import type { Ref, VNode } from 'vue'
4-
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
3+
import type { VNode } from 'vue'
4+
import { nextTick, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue'
55
66
export type NonEmptyArray<T> = [T, ...T[]]
77
@@ -51,7 +51,7 @@ defineSlots<{
5151
}>()
5252
5353
const columns = ref<Column[]>([])
54-
const wall = ref<HTMLDivElement>() as Ref<HTMLDivElement>
54+
const wall = useTemplateRef<HTMLDivElement>('wall')
5555
5656
function createColumns(count: number): Column[] {
5757
return Array.from({ length: count }).map(() => [])
@@ -72,12 +72,12 @@ function countIteratively(
7272
7373
function getColumnWidthTarget(columnIndex: number): number {
7474
const widths = Array.isArray(columnWidth) ? columnWidth : [columnWidth]
75-
return widths[columnIndex % widths.length] as number
75+
return widths[columnIndex % widths.length]!
7676
}
7777
7878
function columnCount(): number {
7979
const count = countIteratively(
80-
wall.value.getBoundingClientRect().width,
80+
wall.value!.getBoundingClientRect().width,
8181
gap,
8282
0,
8383
// Needs to be offset my negative gap to prevent gap counts being off by one
@@ -118,10 +118,7 @@ async function fillColumns(itemIndex: number, assignedRedrawId: number) {
118118
// e.g., in an onMounted hook during initial render
119119
return
120120
}
121-
const columnDivs = [...wall.value.children] as HTMLDivElement[]
122-
if (rtl) {
123-
columnDivs.reverse()
124-
}
121+
const columnDivs = [...wall.value!.children] as HTMLDivElement[]
125122
const target = columnDivs.reduce((prev, curr) =>
126123
curr.getBoundingClientRect().height < prev.getBoundingClientRect().height ? curr : prev,
127124
)
@@ -151,17 +148,24 @@ const resizeObserver =
151148
152149
onMounted(async () => {
153150
await redraw()
154-
resizeObserver?.observe(wall.value)
151+
resizeObserver?.observe(wall.value!)
155152
})
156153
157-
onBeforeUnmount(() => resizeObserver?.unobserve(wall.value))
154+
onBeforeUnmount(() => resizeObserver?.unobserve(wall.value!))
158155
159-
watch([() => items, () => rtl], () => redraw(true))
156+
watch(
157+
() => items,
158+
() => redraw(true),
159+
)
160160
watch([() => columnWidth, () => gap, () => minColumns, () => maxColumns], () => redraw())
161161
</script>
162162

163163
<template>
164-
<div ref="wall" class="masonry-wall" :style="{ display: 'flex', gap: `${gap}px` }">
164+
<div
165+
ref="wall"
166+
class="masonry-wall"
167+
:style="{ display: 'flex', gap: `${gap}px`, flexDirection: rtl ? 'row-reverse' : undefined }"
168+
>
165169
<div
166170
v-for="(column, columnIndex) in columns"
167171
:key="columnIndex"

0 commit comments

Comments
 (0)