UNPKG

naive-ui

Version:

A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript, Fast

230 lines 8.33 kB
import { repeat } from 'seemly'; import { useCompitable } from 'vooks'; import { computed, defineComponent, h } from 'vue'; import { useConfig, useTheme, useThemeClass } from "../../_mixins/index.mjs"; import { createKey, flatten, getSlot, getVNodeChildren, warn } from "../../_utils/index.mjs"; import { descriptionsLight } from "../styles/index.mjs"; import style from "./styles/index.cssr.mjs"; import { isDescriptionsItem } from "./utils.mjs"; export const descriptionsProps = Object.assign(Object.assign({}, useTheme.props), { title: String, column: { type: Number, default: 3 }, columns: Number, labelPlacement: { type: String, default: 'top' }, labelAlign: { type: String, default: 'left' }, separator: { type: String, default: ':' }, size: { type: String, default: 'medium' }, bordered: Boolean, labelClass: String, labelStyle: [Object, String], contentClass: String, contentStyle: [Object, String] }); export default defineComponent({ name: 'Descriptions', props: descriptionsProps, slots: Object, setup(props) { const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props); const themeRef = useTheme('Descriptions', '-descriptions', style, descriptionsLight, props, mergedClsPrefixRef); const cssVarsRef = computed(() => { const { size, bordered } = props; const { common: { cubicBezierEaseInOut }, self: { titleTextColor, thColor, thColorModal, thColorPopover, thTextColor, thFontWeight, tdTextColor, tdColor, tdColorModal, tdColorPopover, borderColor, borderColorModal, borderColorPopover, borderRadius, lineHeight, [createKey('fontSize', size)]: fontSize, [createKey(bordered ? 'thPaddingBordered' : 'thPadding', size)]: thPadding, [createKey(bordered ? 'tdPaddingBordered' : 'tdPadding', size)]: tdPadding } } = themeRef.value; return { '--n-title-text-color': titleTextColor, '--n-th-padding': thPadding, '--n-td-padding': tdPadding, '--n-font-size': fontSize, '--n-bezier': cubicBezierEaseInOut, '--n-th-font-weight': thFontWeight, '--n-line-height': lineHeight, '--n-th-text-color': thTextColor, '--n-td-text-color': tdTextColor, '--n-th-color': thColor, '--n-th-color-modal': thColorModal, '--n-th-color-popover': thColorPopover, '--n-td-color': tdColor, '--n-td-color-modal': tdColorModal, '--n-td-color-popover': tdColorPopover, '--n-border-radius': borderRadius, '--n-border-color': borderColor, '--n-border-color-modal': borderColorModal, '--n-border-color-popover': borderColorPopover }; }); const themeClassHandle = inlineThemeDisabled ? useThemeClass('descriptions', computed(() => { let hash = ''; const { size, bordered } = props; if (bordered) hash += 'a'; hash += size[0]; return hash; }), cssVarsRef, props) : undefined; return { mergedClsPrefix: mergedClsPrefixRef, cssVars: inlineThemeDisabled ? undefined : cssVarsRef, themeClass: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.themeClass, onRender: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.onRender, compitableColumn: useCompitable(props, ['columns', 'column']), inlineThemeDisabled }; }, render() { const defaultSlots = this.$slots.default; const children = defaultSlots ? flatten(defaultSlots()) : []; const memorizedLength = children.length; const { contentClass, labelClass, compitableColumn, labelPlacement, labelAlign, size, bordered, title, cssVars, mergedClsPrefix, separator, onRender } = this; onRender === null || onRender === void 0 ? void 0 : onRender(); const filteredChildren = children.filter(child => isDescriptionsItem(child)); if (process.env.NODE_ENV !== 'production' && memorizedLength !== filteredChildren.length) { warn('descriptions', '`n-descriptions` only takes `n-descriptions-item` as children.'); } const defaultState = { span: 0, row: [], secondRow: [], rows: [] }; const itemState = filteredChildren.reduce((state, vNode, index) => { const props = vNode.props || {}; const isLastIteration = filteredChildren.length - 1 === index; const itemLabel = ['label' in props ? props.label : getVNodeChildren(vNode, 'label')]; const itemChildren = [getVNodeChildren(vNode)]; const itemSpan = props.span || 1; const memorizedSpan = state.span; state.span += itemSpan; const labelStyle = props.labelStyle || props['label-style'] || this.labelStyle; const contentStyle = props.contentStyle || props['content-style'] || this.contentStyle; if (labelPlacement === 'left') { if (bordered) { state.row.push(h("th", { class: [`${mergedClsPrefix}-descriptions-table-header`, labelClass], colspan: 1, style: labelStyle }, itemLabel), h("td", { class: [`${mergedClsPrefix}-descriptions-table-content`, contentClass], colspan: isLastIteration ? (compitableColumn - memorizedSpan) * 2 + 1 : itemSpan * 2 - 1, style: contentStyle }, itemChildren)); } else { state.row.push(h("td", { class: `${mergedClsPrefix}-descriptions-table-content`, colspan: isLastIteration ? (compitableColumn - memorizedSpan) * 2 : itemSpan * 2 }, h("span", { class: [`${mergedClsPrefix}-descriptions-table-content__label`, labelClass], style: labelStyle }, [...itemLabel, separator && h("span", { class: `${mergedClsPrefix}-descriptions-separator` }, separator)]), h("span", { class: [`${mergedClsPrefix}-descriptions-table-content__content`, contentClass], style: contentStyle }, itemChildren))); } } else { const colspan = isLastIteration ? (compitableColumn - memorizedSpan) * 2 : itemSpan * 2; state.row.push(h("th", { class: [`${mergedClsPrefix}-descriptions-table-header`, labelClass], colspan: colspan, style: labelStyle }, itemLabel)); state.secondRow.push(h("td", { class: [`${mergedClsPrefix}-descriptions-table-content`, contentClass], colspan: colspan, style: contentStyle }, itemChildren)); } if (state.span >= compitableColumn || isLastIteration) { state.span = 0; if (state.row.length) { state.rows.push(state.row); state.row = []; } if (labelPlacement !== 'left') { if (state.secondRow.length) { state.rows.push(state.secondRow); state.secondRow = []; } } } return state; }, defaultState); const rows = itemState.rows.map(row => h("tr", { class: `${mergedClsPrefix}-descriptions-table-row` }, row)); return h("div", { style: cssVars, class: [`${mergedClsPrefix}-descriptions`, this.themeClass, `${mergedClsPrefix}-descriptions--${labelPlacement}-label-placement`, `${mergedClsPrefix}-descriptions--${labelAlign}-label-align`, `${mergedClsPrefix}-descriptions--${size}-size`, bordered && `${mergedClsPrefix}-descriptions--bordered`] }, title || this.$slots.header ? h("div", { class: `${mergedClsPrefix}-descriptions-header` }, title || getSlot(this, 'header')) : null, h("div", { class: `${mergedClsPrefix}-descriptions-table-wrapper` }, h("table", { class: `${mergedClsPrefix}-descriptions-table` }, h("tbody", null, labelPlacement === 'top' && h("tr", { class: `${mergedClsPrefix}-descriptions-table-row`, style: { visibility: 'collapse' } }, repeat(compitableColumn * 2, h("td", null))), rows)))); } });