@aplus-frontend/antdv
Version:
Vue basic component library maintained based on ant-design-vue
113 lines • 3.06 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import ResizeObserver from 'resize-observer-polyfill';
import { defineComponent, getCurrentInstance, onMounted, onUnmounted, onUpdated, reactive, watch } from 'vue';
import { findDOMNode } from '../_util/props-util';
export default defineComponent({
compatConfig: {
MODE: 3
},
name: 'ResizeObserver',
props: {
disabled: Boolean,
onResize: Function
},
emits: ['resize'],
setup(props, _ref) {
let {
slots
} = _ref;
const state = reactive({
width: 0,
height: 0,
offsetHeight: 0,
offsetWidth: 0
});
let currentElement = null;
let resizeObserver = null;
const destroyObserver = () => {
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = null;
}
};
const onResize = entries => {
const {
onResize
} = props;
const target = entries[0].target;
const {
width,
height
} = target.getBoundingClientRect();
const {
offsetWidth,
offsetHeight
} = target;
/**
* Resize observer trigger when content size changed.
* In most case we just care about element size,
* let's use `boundary` instead of `contentRect` here to avoid shaking.
*/
const fixedWidth = Math.floor(width);
const fixedHeight = Math.floor(height);
if (state.width !== fixedWidth || state.height !== fixedHeight || state.offsetWidth !== offsetWidth || state.offsetHeight !== offsetHeight) {
const size = {
width: fixedWidth,
height: fixedHeight,
offsetWidth,
offsetHeight
};
_extends(state, size);
if (onResize) {
// defer the callback but not defer to next frame
Promise.resolve().then(() => {
onResize(_extends(_extends({}, size), {
offsetWidth,
offsetHeight
}), target);
});
}
}
};
const instance = getCurrentInstance();
const registerObserver = () => {
const {
disabled
} = props;
// Unregister if disabled
if (disabled) {
destroyObserver();
return;
}
// Unregister if element changed
const element = findDOMNode(instance);
const elementChanged = element !== currentElement;
if (elementChanged) {
destroyObserver();
currentElement = element;
}
if (!resizeObserver && element) {
resizeObserver = new ResizeObserver(onResize);
resizeObserver.observe(element);
}
};
onMounted(() => {
registerObserver();
});
onUpdated(() => {
registerObserver();
});
onUnmounted(() => {
destroyObserver();
});
watch(() => props.disabled, () => {
registerObserver();
}, {
flush: 'post'
});
return () => {
var _a;
return (_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots)[0];
};
}
});