123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- // Composables
- import { useResizeObserver } from "./resizeObserver.mjs"; // Utilities
- import { computed, inject, onActivated, onBeforeUnmount, onDeactivated, onMounted, provide, reactive, ref, shallowRef } from 'vue';
- import { convertToUnit, findChildrenWithProvide, getCurrentInstance, getUid, propsFactory } from "../util/index.mjs"; // Types
- export const VuetifyLayoutKey = Symbol.for('vuetify:layout');
- export const VuetifyLayoutItemKey = Symbol.for('vuetify:layout-item');
- const ROOT_ZINDEX = 1000;
- export const makeLayoutProps = propsFactory({
- overlaps: {
- type: Array,
- default: () => []
- },
- fullHeight: Boolean
- }, 'layout');
- // Composables
- export const makeLayoutItemProps = propsFactory({
- name: {
- type: String
- },
- order: {
- type: [Number, String],
- default: 0
- },
- absolute: Boolean
- }, 'layout-item');
- export function useLayout() {
- const layout = inject(VuetifyLayoutKey);
- if (!layout) throw new Error('[Vuetify] Could not find injected layout');
- return {
- getLayoutItem: layout.getLayoutItem,
- mainRect: layout.mainRect,
- mainStyles: layout.mainStyles
- };
- }
- export function useLayoutItem(options) {
- const layout = inject(VuetifyLayoutKey);
- if (!layout) throw new Error('[Vuetify] Could not find injected layout');
- const id = options.id ?? `layout-item-${getUid()}`;
- const vm = getCurrentInstance('useLayoutItem');
- provide(VuetifyLayoutItemKey, {
- id
- });
- const isKeptAlive = shallowRef(false);
- onDeactivated(() => isKeptAlive.value = true);
- onActivated(() => isKeptAlive.value = false);
- const {
- layoutItemStyles,
- layoutItemScrimStyles
- } = layout.register(vm, {
- ...options,
- active: computed(() => isKeptAlive.value ? false : options.active.value),
- id
- });
- onBeforeUnmount(() => layout.unregister(id));
- return {
- layoutItemStyles,
- layoutRect: layout.layoutRect,
- layoutItemScrimStyles
- };
- }
- const generateLayers = (layout, positions, layoutSizes, activeItems) => {
- let previousLayer = {
- top: 0,
- left: 0,
- right: 0,
- bottom: 0
- };
- const layers = [{
- id: '',
- layer: {
- ...previousLayer
- }
- }];
- for (const id of layout) {
- const position = positions.get(id);
- const amount = layoutSizes.get(id);
- const active = activeItems.get(id);
- if (!position || !amount || !active) continue;
- const layer = {
- ...previousLayer,
- [position.value]: parseInt(previousLayer[position.value], 10) + (active.value ? parseInt(amount.value, 10) : 0)
- };
- layers.push({
- id,
- layer
- });
- previousLayer = layer;
- }
- return layers;
- };
- export function createLayout(props) {
- const parentLayout = inject(VuetifyLayoutKey, null);
- const rootZIndex = computed(() => parentLayout ? parentLayout.rootZIndex.value - 100 : ROOT_ZINDEX);
- const registered = ref([]);
- const positions = reactive(new Map());
- const layoutSizes = reactive(new Map());
- const priorities = reactive(new Map());
- const activeItems = reactive(new Map());
- const disabledTransitions = reactive(new Map());
- const {
- resizeRef,
- contentRect: layoutRect
- } = useResizeObserver();
- const computedOverlaps = computed(() => {
- const map = new Map();
- const overlaps = props.overlaps ?? [];
- for (const overlap of overlaps.filter(item => item.includes(':'))) {
- const [top, bottom] = overlap.split(':');
- if (!registered.value.includes(top) || !registered.value.includes(bottom)) continue;
- const topPosition = positions.get(top);
- const bottomPosition = positions.get(bottom);
- const topAmount = layoutSizes.get(top);
- const bottomAmount = layoutSizes.get(bottom);
- if (!topPosition || !bottomPosition || !topAmount || !bottomAmount) continue;
- map.set(bottom, {
- position: topPosition.value,
- amount: parseInt(topAmount.value, 10)
- });
- map.set(top, {
- position: bottomPosition.value,
- amount: -parseInt(bottomAmount.value, 10)
- });
- }
- return map;
- });
- const layers = computed(() => {
- const uniquePriorities = [...new Set([...priorities.values()].map(p => p.value))].sort((a, b) => a - b);
- const layout = [];
- for (const p of uniquePriorities) {
- const items = registered.value.filter(id => priorities.get(id)?.value === p);
- layout.push(...items);
- }
- return generateLayers(layout, positions, layoutSizes, activeItems);
- });
- const transitionsEnabled = computed(() => {
- return !Array.from(disabledTransitions.values()).some(ref => ref.value);
- });
- const mainRect = computed(() => {
- return layers.value[layers.value.length - 1].layer;
- });
- const mainStyles = computed(() => {
- return {
- '--v-layout-left': convertToUnit(mainRect.value.left),
- '--v-layout-right': convertToUnit(mainRect.value.right),
- '--v-layout-top': convertToUnit(mainRect.value.top),
- '--v-layout-bottom': convertToUnit(mainRect.value.bottom),
- ...(transitionsEnabled.value ? undefined : {
- transition: 'none'
- })
- };
- });
- const items = computed(() => {
- return layers.value.slice(1).map((_ref, index) => {
- let {
- id
- } = _ref;
- const {
- layer
- } = layers.value[index];
- const size = layoutSizes.get(id);
- const position = positions.get(id);
- return {
- id,
- ...layer,
- size: Number(size.value),
- position: position.value
- };
- });
- });
- const getLayoutItem = id => {
- return items.value.find(item => item.id === id);
- };
- const rootVm = getCurrentInstance('createLayout');
- const isMounted = shallowRef(false);
- onMounted(() => {
- isMounted.value = true;
- });
- provide(VuetifyLayoutKey, {
- register: (vm, _ref2) => {
- let {
- id,
- order,
- position,
- layoutSize,
- elementSize,
- active,
- disableTransitions,
- absolute
- } = _ref2;
- priorities.set(id, order);
- positions.set(id, position);
- layoutSizes.set(id, layoutSize);
- activeItems.set(id, active);
- disableTransitions && disabledTransitions.set(id, disableTransitions);
- const instances = findChildrenWithProvide(VuetifyLayoutItemKey, rootVm?.vnode);
- const instanceIndex = instances.indexOf(vm);
- if (instanceIndex > -1) registered.value.splice(instanceIndex, 0, id);else registered.value.push(id);
- const index = computed(() => items.value.findIndex(i => i.id === id));
- const zIndex = computed(() => rootZIndex.value + layers.value.length * 2 - index.value * 2);
- const layoutItemStyles = computed(() => {
- const isHorizontal = position.value === 'left' || position.value === 'right';
- const isOppositeHorizontal = position.value === 'right';
- const isOppositeVertical = position.value === 'bottom';
- const styles = {
- [position.value]: 0,
- zIndex: zIndex.value,
- transform: `translate${isHorizontal ? 'X' : 'Y'}(${(active.value ? 0 : -110) * (isOppositeHorizontal || isOppositeVertical ? -1 : 1)}%)`,
- position: absolute.value || rootZIndex.value !== ROOT_ZINDEX ? 'absolute' : 'fixed',
- ...(transitionsEnabled.value ? undefined : {
- transition: 'none'
- })
- };
- if (!isMounted.value) return styles;
- const item = items.value[index.value];
- if (!item) throw new Error(`[Vuetify] Could not find layout item "${id}"`);
- const overlap = computedOverlaps.value.get(id);
- if (overlap) {
- item[overlap.position] += overlap.amount;
- }
- return {
- ...styles,
- height: isHorizontal ? `calc(100% - ${item.top}px - ${item.bottom}px)` : elementSize.value ? `${elementSize.value}px` : undefined,
- left: isOppositeHorizontal ? undefined : `${item.left}px`,
- right: isOppositeHorizontal ? `${item.right}px` : undefined,
- top: position.value !== 'bottom' ? `${item.top}px` : undefined,
- bottom: position.value !== 'top' ? `${item.bottom}px` : undefined,
- width: !isHorizontal ? `calc(100% - ${item.left}px - ${item.right}px)` : elementSize.value ? `${elementSize.value}px` : undefined
- };
- });
- const layoutItemScrimStyles = computed(() => ({
- zIndex: zIndex.value - 1
- }));
- return {
- layoutItemStyles,
- layoutItemScrimStyles,
- zIndex
- };
- },
- unregister: id => {
- priorities.delete(id);
- positions.delete(id);
- layoutSizes.delete(id);
- activeItems.delete(id);
- disabledTransitions.delete(id);
- registered.value = registered.value.filter(v => v !== id);
- },
- mainRect,
- mainStyles,
- getLayoutItem,
- items,
- layoutRect,
- rootZIndex
- });
- const layoutClasses = computed(() => ['v-layout', {
- 'v-layout--full-height': props.fullHeight
- }]);
- const layoutStyles = computed(() => ({
- zIndex: rootZIndex.value,
- position: parentLayout ? 'relative' : undefined,
- overflow: parentLayout ? 'hidden' : undefined
- }));
- return {
- layoutClasses,
- layoutStyles,
- getLayoutItem,
- items,
- layoutRect,
- layoutRef: resizeRef
- };
- }
- //# sourceMappingURL=layout.mjs.map
|