vuetify
Version:
Vue Material Component Framework
182 lines (179 loc) • 4.97 kB
JavaScript
// Styles
import "./VGrid.css";
// Composables
import { makeComponentProps } from "../../composables/component.js";
import { breakpoints } from "../../composables/display.js";
import { makeTagProps } from "../../composables/tag.js"; // Utilities
import { capitalize, computed, h } from 'vue';
import { genericComponent, keys, propsFactory } from "../../util/index.js"; // Types
const breakpointProps = (() => {
return breakpoints.reduce((props, val) => {
props[val] = {
type: [Boolean, String, Number],
default: false
};
return props;
}, {});
})();
const offsetProps = (() => {
return breakpoints.reduce((props, val) => {
const offsetKey = 'offset' + capitalize(val);
props[offsetKey] = {
type: [String, Number],
default: null
};
return props;
}, {});
})();
const propMap = {
col: keys(breakpointProps),
offset: keys(offsetProps),
order: ['order', 'orderSm', 'orderMd', 'orderLg', 'orderXl', 'orderXxl']
};
function parseCols(val) {
if (typeof val === 'string' && val.includes('/')) {
const [cols, size] = val.split('/');
return {
cols: Number(cols),
size: Number(size)
};
}
return {
cols: val
};
}
function parseBreakpoint(type, prop, val) {
if (val == null || val === false) {
return {};
}
const {
cols,
size
} = parseCols(val);
const breakpoint = prop.replace(type, '').toLowerCase();
if (type === 'offset') {
return {
className: `v-col--offset-${breakpoint}-${cols}`,
variables: [{
[`--v-col-offset-base-${breakpoint}`]: size
}]
};
} else if (type === 'order') {
return {
className: `order-${breakpoint}-${cols}`
};
}
// Handling the boolean style prop when accepting [Boolean, String, Number]
// means Vue will not convert <v-col sm></v-col> to sm: true for us.
// Since the default is false, an empty string indicates the prop's presence.
return {
className: cols === '' || cols === true ? `v-col--${breakpoint}` : `v-col--cols-${breakpoint}-${cols}`,
variables: [{
[`--v-col-size-base-${breakpoint}`]: size
}]
};
}
const ALIGN_SELF_VALUES = ['auto', 'start', 'end', 'center', 'baseline', 'stretch'];
const alignSelfValidator = str => ALIGN_SELF_VALUES.includes(str);
export const makeVColProps = propsFactory({
cols: {
type: [Boolean, String, Number],
default: false
},
...breakpointProps,
offset: {
type: [String, Number],
default: null
},
...offsetProps,
/** @deprecated use order-* class instead */
order: {
type: [String, Number],
default: null
},
/** @deprecated use order-sm-* class instead */
orderSm: {
type: [String, Number],
default: null
},
/** @deprecated use order-md-* class instead */
orderMd: {
type: [String, Number],
default: null
},
/** @deprecated use order-lg-* class instead */
orderLg: {
type: [String, Number],
default: null
},
/** @deprecated use order-xl-* class instead */
orderXl: {
type: [String, Number],
default: null
},
/** @deprecated use order-xxl-* class instead */
orderXxl: {
type: [String, Number],
default: null
},
/** @deprecated use align-self-* class instead */
alignSelf: {
type: String,
default: null,
validator: alignSelfValidator
},
...makeComponentProps(),
...makeTagProps()
}, 'VCol');
export const VCol = genericComponent()({
name: 'VCol',
props: makeVColProps(),
setup(props, {
slots
}) {
const sizeBaseOverride = computed(() => parseCols(props.cols).size);
const offsetBaseOverride = computed(() => parseCols(props.offset).size);
const responsive = computed(() => {
const classList = ['v-col'];
const variablesList = [];
// Loop through `col`, `offset`, `order` breakpoint props
let type;
for (type in propMap) {
propMap[type].forEach(prop => {
const value = props[prop];
const {
className,
variables
} = parseBreakpoint(type, prop, value);
if (className) classList.push(className);
if (variables) variablesList.push(...variables);
});
}
const {
cols
} = parseCols(props.cols);
const {
cols: offset
} = parseCols(props.offset);
classList.push({
[`v-col--cols-${cols}`]: cols,
[`v-col--offset-${offset}`]: offset,
[`order-${props.order}`]: props.order,
[`align-self-${props.alignSelf}`]: props.alignSelf
});
return {
classes: classList,
variables: variablesList
};
});
return () => h(props.tag, {
class: [responsive.value.classes, props.class],
style: [{
'--v-col-size-base': sizeBaseOverride.value
}, {
'--v-col-offset-base': offsetBaseOverride.value
}, responsive.value.variables, props.style]
}, slots.default?.());
}
});
//# sourceMappingURL=VCol.js.map