128 lines
3.6 KiB
JavaScript
128 lines
3.6 KiB
JavaScript
// Styles
|
|
import "./VGrid.css";
|
|
|
|
// Composables
|
|
import { makeComponentProps } from "../../composables/component.mjs";
|
|
import { breakpoints } from "../../composables/display.mjs";
|
|
import { makeTagProps } from "../../composables/tag.mjs"; // Utilities
|
|
import { capitalize, computed, h } from 'vue';
|
|
import { genericComponent, propsFactory } from "../../util/index.mjs"; // 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 orderProps = (() => {
|
|
return breakpoints.reduce((props, val) => {
|
|
const orderKey = 'order' + capitalize(val);
|
|
props[orderKey] = {
|
|
type: [String, Number],
|
|
default: null
|
|
};
|
|
return props;
|
|
}, {});
|
|
})();
|
|
const propMap = {
|
|
col: Object.keys(breakpointProps),
|
|
offset: Object.keys(offsetProps),
|
|
order: Object.keys(orderProps)
|
|
};
|
|
function breakpointClass(type, prop, val) {
|
|
let className = type;
|
|
if (val == null || val === false) {
|
|
return undefined;
|
|
}
|
|
if (prop) {
|
|
const breakpoint = prop.replace(type, '');
|
|
className += `-${breakpoint}`;
|
|
}
|
|
if (type === 'col') {
|
|
className = 'v-' + className;
|
|
}
|
|
// 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.
|
|
if (type === 'col' && (val === '' || val === true)) {
|
|
// .v-col-md
|
|
return className.toLowerCase();
|
|
}
|
|
// .order-md-6
|
|
className += `-${val}`;
|
|
return className.toLowerCase();
|
|
}
|
|
const ALIGN_SELF_VALUES = ['auto', 'start', 'end', 'center', 'baseline', 'stretch'];
|
|
export const makeVColProps = propsFactory({
|
|
cols: {
|
|
type: [Boolean, String, Number],
|
|
default: false
|
|
},
|
|
...breakpointProps,
|
|
offset: {
|
|
type: [String, Number],
|
|
default: null
|
|
},
|
|
...offsetProps,
|
|
order: {
|
|
type: [String, Number],
|
|
default: null
|
|
},
|
|
...orderProps,
|
|
alignSelf: {
|
|
type: String,
|
|
default: null,
|
|
validator: str => ALIGN_SELF_VALUES.includes(str)
|
|
},
|
|
...makeComponentProps(),
|
|
...makeTagProps()
|
|
}, 'VCol');
|
|
export const VCol = genericComponent()({
|
|
name: 'VCol',
|
|
props: makeVColProps(),
|
|
setup(props, _ref) {
|
|
let {
|
|
slots
|
|
} = _ref;
|
|
const classes = computed(() => {
|
|
const classList = [];
|
|
|
|
// Loop through `col`, `offset`, `order` breakpoint props
|
|
let type;
|
|
for (type in propMap) {
|
|
propMap[type].forEach(prop => {
|
|
const value = props[prop];
|
|
const className = breakpointClass(type, prop, value);
|
|
if (className) classList.push(className);
|
|
});
|
|
}
|
|
const hasColClasses = classList.some(className => className.startsWith('v-col-'));
|
|
classList.push({
|
|
// Default to .v-col if no other col-{bp}-* classes generated nor `cols` specified.
|
|
'v-col': !hasColClasses || !props.cols,
|
|
[`v-col-${props.cols}`]: props.cols,
|
|
[`offset-${props.offset}`]: props.offset,
|
|
[`order-${props.order}`]: props.order,
|
|
[`align-self-${props.alignSelf}`]: props.alignSelf
|
|
});
|
|
return classList;
|
|
});
|
|
return () => h(props.tag, {
|
|
class: [classes.value, props.class],
|
|
style: props.style
|
|
}, slots.default?.());
|
|
}
|
|
});
|
|
//# sourceMappingURL=VCol.mjs.map
|