import { defineComponent, mergeProps } from "vue"; import type { HTMLAttributes, PropType, VNode } from "vue"; import type { Breakpoints } from "@darwin-studio/ui-codegen/dist/types/breakpoints"; import useWindowSize from "@darwin-studio/vue-ui/src/compositions/window-size"; import generateProp from "@darwin-studio/vue-ui/src/utils/generate-prop"; import generateClass from "@darwin-studio/vue-ui/src/utils/generate-class"; import config from "./config"; /** * The container provides you with an easy way to arrange child nodes in a grid template. * */ export default defineComponent({ name: config.name, props: { /** * An array of strings or VNodes */ content: { type: Array as PropType<(string | VNode)[]>, }, /** * Contains number of columns which should take every child node for specific device width.
* Expected format: number or { xs: 2, sm: 3, ..., xl: 4 }.
* By default children will take one column. */ colSpan: { type: [Number, Object] as PropType>, }, /** * Contains row gap between cells.
* Expected format: '16px' or { xs: '10px', sm: '16px', ..., xl: '24px' }.
* By default equals to column gap of the grid. */ rowGap: { type: [String, Object] as PropType>, }, /** * Defines container element type of the component */ tag: generateProp.tag(), /** * Defines transition type of the component */ transition: generateProp.transition(), }, setup() { return useWindowSize(); }, computed: { preparedColSpan(): number { let colSpan = config.colSpan; if ( typeof this.colSpan === "object" && this.size && this.colSpan[this.size] ) { colSpan = this.colSpan[this.size]; } else if (typeof this.colSpan === "number" && this.colSpan) { colSpan = this.colSpan; } return colSpan; }, preparedRowGap(): string { let rowGap = config.rowGap; if ( typeof this.rowGap === "object" && this.size && this.rowGap[this.size] ) { rowGap = this.rowGap[this.size]; } else if (typeof this.rowGap === "string" && this.rowGap) { rowGap = this.rowGap; } return rowGap; }, bindings(): HTMLAttributes { return { class: [config.class, generateClass.transition(this.transition)], style: { "--grid-col-span": this.preparedColSpan, // TODO: config "--grid-row-gap": this.preparedRowGap, // TODO: config }, }; }, renderContent(): (VNode | string)[] | undefined { if (this.$slots.default) { // TODO: find out another way ... return this.$slots.default()?.map((child) => { child.props = mergeProps(child.props || {}, { class: config.childClass, }); return child; }); } if (this.content) { // TODO: find out another way ... return this.content.map((child) => { if (typeof child !== "string") { child.props = mergeProps(child.props || {}, { class: config.childClass, }); return child; } return child; }); } return undefined; }, }, /*TODO: why vue-docgen cant' detect not default slots ???*/ /** * @slot $slots.default * Put some children to align them with the grid * */ render(): VNode { const Tag = this.tag; return {this.renderContent}; }, });