Files
speckle-server/packages/frontend-2/lib/common/composables/window.ts
T
Kristaps Fabians Geikins 83d8035dc2 chore: upgrade to eslint 9 (#2348)
* root + server

* frontend

* frontend-2

* dui3

* dui3

* tailwind theme

* ui-components

* preview service

* viewer

* viewer-sandbox

* fileimport-service

* webhook service

* objectloader

* shared

* ui-components-nuxt

* WIP full config

* WIP full linter

* eslint projectwide util

* minor fix

* removing redundant ci

* clean up test errors

* fixed prettier formatting

* CI improvements

* TSC lint fix

* 'buildBatch' needs to be async since some batch types (like Text) require it. Removed a disabled liniting rule from ObjLoader

* removed unnecessary void

---------

Co-authored-by: AlexandruPopovici <alexandrupopoviciioan@gmail.com>
2024-06-12 14:38:02 +03:00

106 lines
2.6 KiB
TypeScript

import { useStorage } from '@vueuse/core'
import { isString, uniq } from 'lodash-es'
export {
ThrottleOrDebounce,
HorizontalDirection,
useWindowResizeHandler,
useOnBeforeWindowUnload,
useResponsiveHorizontalDirectionCalculation
} from '@speckle/ui-components'
export function useDisableGlobalTextSelection() {
const disableTextSelection = ref(false)
if (import.meta.client) {
watch(disableTextSelection, (newVal, oldVal) => {
if (!!newVal === !!oldVal) return
if (newVal) {
document.body.classList.add('select-none')
} else {
document.body.classList.remove('select-none')
}
})
}
return { disableTextSelection }
}
export function useItemsExpandedState(params: { stateName: string }) {
const initializer = () => ({
expandedIds: [] as string[]
})
const fakeState = ref(initializer())
const storageState = import.meta.server
? fakeState
: useStorage('useItemsExpandedState-' + params.stateName, initializer)
const hasMounted = ref(false)
const useRealState = computed(() => import.meta.client && hasMounted.value)
const state = computed({
get: () => {
const shouldUseRealState = useRealState.value
return !shouldUseRealState ? fakeState.value : storageState.value
},
set: (newVal) => {
const shouldUseRealState = useRealState.value
if (!shouldUseRealState) {
fakeState.value = newVal
} else {
storageState.value = newVal
}
}
})
const isExpanded = (id: string | ((id: string) => boolean)): boolean =>
!!(isString(id)
? state.value.expandedIds.includes(id)
: state.value.expandedIds.find(id))
const toggleExpanded = (id: string, newState: boolean) => {
if (!newState) {
state.value = {
...state.value,
expandedIds: state.value.expandedIds.filter((i) => i !== id)
}
} else {
state.value = {
...state.value,
expandedIds: uniq([...state.value.expandedIds, id])
}
}
}
onMounted(() => {
// Only doing this after onMounted to avoid hydration mismatches
hasMounted.value = true
})
return { isExpanded, toggleExpanded }
}
export const useIsItemExpanded = (params: {
stateName: string
id: MaybeRef<string>
}) => {
const { stateName, id } = params
const { isExpanded, toggleExpanded } = useItemsExpandedState({ stateName })
const expanded = computed({
get: () => isExpanded(unref(id)),
set: (newVal) => toggleExpanded(unref(id), newVal)
})
// Re-calculate on mounted, when we actually have the id
onMounted(() => {
expanded.value = isExpanded(unref(id))
})
return {
isExpanded: expanded
}
}