mirror of
https://github.com/directus/directus.git
synced 2026-01-27 04:48:04 -05:00
Use element size (#169)
* Install resize observer * Add use-element-size composition * Rename function to match filename * Remove false statement from readme
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
"lodash": "^4.17.15",
|
||||
"nanoid": "^2.1.11",
|
||||
"pinia": "0.0.5",
|
||||
"resize-observer": "^1.0.0",
|
||||
"stylelint-config-prettier": "^8.0.1",
|
||||
"vue": "^2.6.11",
|
||||
"vue-i18n": "^8.15.5",
|
||||
|
||||
4
src/compositions/use-element-size/index.ts
Normal file
4
src/compositions/use-element-size/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import useElementSize from './use-element-size';
|
||||
|
||||
export { useElementSize };
|
||||
export default useElementSize;
|
||||
29
src/compositions/use-element-size/readme.md
Normal file
29
src/compositions/use-element-size/readme.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# `useElementSize`
|
||||
|
||||
```ts
|
||||
function useElementSize(element: Element): { width: Ref<number>, height: Ref<number> }
|
||||
```
|
||||
|
||||
Allows you to reactively watch an elements width and height.
|
||||
|
||||
## Usage
|
||||
```vue
|
||||
<template>
|
||||
<div ref="el">
|
||||
My size is: {{ width }} x {{ height }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
import { useElementSize } from '@/compositions/use-element-size';
|
||||
|
||||
export default defineComponent({
|
||||
setup(props) {
|
||||
const el = ref<Element>(null);
|
||||
const { width, height } = useElementSize(el);
|
||||
return { el, width, height };
|
||||
}
|
||||
});
|
||||
</script>
|
||||
```
|
||||
97
src/compositions/use-element-size/use-element-size.test.ts
Normal file
97
src/compositions/use-element-size/use-element-size.test.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import mountComposition from '../../../.jest/mount-composition';
|
||||
import useElementSize from './use-element-size';
|
||||
import { ResizeObserver } from 'resize-observer';
|
||||
import { ref } from '@vue/composition-api';
|
||||
|
||||
jest.mock('resize-observer');
|
||||
|
||||
const mockResizeObserver = {
|
||||
observe: jest.fn(),
|
||||
disconnect: jest.fn()
|
||||
};
|
||||
|
||||
describe('Compositions / useElementSize', () => {
|
||||
beforeEach(() => {
|
||||
(ResizeObserver as jest.Mock).mockImplementation(() => {
|
||||
return mockResizeObserver;
|
||||
});
|
||||
});
|
||||
|
||||
it('Creates a resize observer', () => {
|
||||
const el = document.createElement('div');
|
||||
|
||||
mountComposition(() => {
|
||||
useElementSize(el);
|
||||
});
|
||||
|
||||
expect(ResizeObserver).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Calls observe with the passed element on mount', () => {
|
||||
const el = document.createElement('div');
|
||||
|
||||
mountComposition(() => {
|
||||
useElementSize(el);
|
||||
});
|
||||
|
||||
expect(mockResizeObserver.observe).toHaveBeenCalledWith(el);
|
||||
});
|
||||
|
||||
it('Calls observer with element if ref is passed', () => {
|
||||
const el = document.createElement('div');
|
||||
|
||||
mountComposition(() => {
|
||||
const refEl = ref<Element>(el);
|
||||
useElementSize(refEl);
|
||||
});
|
||||
|
||||
expect(mockResizeObserver.observe).toHaveBeenCalledWith(el);
|
||||
});
|
||||
|
||||
it('Does not call observe when passed element is null or undefined', () => {
|
||||
mountComposition(() => {
|
||||
useElementSize(ref(null));
|
||||
});
|
||||
|
||||
expect(mockResizeObserver.observe).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Calls disconnect on unmount', () => {
|
||||
const el = document.createElement('div');
|
||||
|
||||
mountComposition(() => {
|
||||
useElementSize(el);
|
||||
}).destroy();
|
||||
|
||||
expect(mockResizeObserver.disconnect).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Sets the returned width and height refs on ResizeObserver handler', () => {
|
||||
let handler: (_: any) => void;
|
||||
|
||||
(ResizeObserver as jest.Mock).mockImplementation(constructorParam => {
|
||||
handler = constructorParam;
|
||||
return mockResizeObserver;
|
||||
});
|
||||
|
||||
const el = document.createElement('div');
|
||||
|
||||
mountComposition(() => {
|
||||
const { width, height } = useElementSize(el);
|
||||
expect(width.value).toBe(0);
|
||||
expect(height.value).toBe(0);
|
||||
|
||||
handler([
|
||||
{
|
||||
contentRect: {
|
||||
width: 150,
|
||||
height: 150
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
expect(width.value).toBe(150);
|
||||
expect(height.value).toBe(150);
|
||||
});
|
||||
});
|
||||
});
|
||||
27
src/compositions/use-element-size/use-element-size.ts
Normal file
27
src/compositions/use-element-size/use-element-size.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Ref, ref, isRef, onMounted, onUnmounted } from '@vue/composition-api';
|
||||
import { notEmpty } from '@/utils/is-empty';
|
||||
import { ResizeObserver } from 'resize-observer';
|
||||
|
||||
export default function useElementSize<T extends Element>(target: T | Ref<T> | Ref<null>) {
|
||||
const width = ref(0);
|
||||
const height = ref(0);
|
||||
|
||||
const resizeObserver = new ResizeObserver(([entry]) => {
|
||||
width.value = entry.contentRect.width;
|
||||
height.value = entry.contentRect.height;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
const t = isRef(target) ? target.value : target;
|
||||
|
||||
if (notEmpty(t)) {
|
||||
resizeObserver.observe(t);
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
resizeObserver.disconnect();
|
||||
});
|
||||
|
||||
return { width, height };
|
||||
}
|
||||
@@ -12237,6 +12237,11 @@ resize-observer-polyfill@^1.5.1:
|
||||
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
|
||||
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
|
||||
|
||||
resize-observer@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resize-observer/-/resize-observer-1.0.0.tgz#4f8380b73b411af4ed7d916fe85a2d59900e71ef"
|
||||
integrity sha512-D7UFShDm2TgrEDEyeg+/tTEbvOgPWlvPAfJtxiKp+qutu6HowmcGJKjECgGru0PPDIj3SAucn3ZPpOx54fF7DQ==
|
||||
|
||||
resolve-cwd@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
|
||||
|
||||
Reference in New Issue
Block a user