aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/src/composables/useFileListWidth.ts
blob: 621ef20483642471dc697e17983a95f27c981c9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*!
 * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */
import type { Ref } from 'vue'
import { onMounted, readonly, ref } from 'vue'

/** The element we observe */
let element: HTMLElement | undefined

/** The current width of the element */
const width = ref(0)

const observer = new ResizeObserver((elements) => {
	if (elements[0].contentBoxSize) {
		// use the newer `contentBoxSize` property if available
		width.value = elements[0].contentBoxSize[0].inlineSize
	} else {
		// fall back to `contentRect`
		width.value = elements[0].contentRect.width
	}
})

/**
 * Update the observed element if needed and reconfigure the observer
 */
function updateObserver() {
	const el = document.querySelector<HTMLElement>('#app-content-vue') ?? document.body
	if (el !== element) {
		// if already observing: stop observing the old element
		if (element) {
			observer.unobserve(element)
		}
		// observe the new element if needed
		observer.observe(el)
		element = el
	}
}

/**
 * Get the reactive width of the file list
 */
export function useFileListWidth(): Readonly<Ref<number>> {
	// Update the observer when the component is mounted (e.g. because this is the files app)
	onMounted(updateObserver)
	// Update the observer also in setup context, so we already have an initial value
	updateObserver()

	return readonly(width)
}