diff --git a/src/_mixins/index.ts b/src/_mixins/index.ts index 240a349e5..ba29682ba 100644 --- a/src/_mixins/index.ts +++ b/src/_mixins/index.ts @@ -1,6 +1,6 @@ export { default as useFormItem } from './use-form-item' export { default as useTheme } from './use-theme' -export type { ThemeProps, MergedTheme } from './use-theme' +export type { ThemeProps, MergedTheme, ThemePropsReactive } from './use-theme' export { default as useConfig } from './use-config' export { default as useLocale } from './use-locale' export { default as useStyle } from './use-style' diff --git a/src/_mixins/use-theme.ts b/src/_mixins/use-theme.ts index 0ec1727e9..c1935473b 100644 --- a/src/_mixins/use-theme.ts +++ b/src/_mixins/use-theme.ts @@ -136,6 +136,12 @@ export type ThemeProps = { } } +export type ThemePropsReactive = { + unstableTheme: T + unstableThemeOverrides: Record + builtinThemeOverrides: Record +} + /** * props.unstableTheme: * { common, self(), peers } diff --git a/src/_utils/vue/omit.ts b/src/_utils/vue/omit.ts index e744bc84d..b7c7223d0 100644 --- a/src/_utils/vue/omit.ts +++ b/src/_utils/vue/omit.ts @@ -1,8 +1,9 @@ -export function omit ( +export function omit ( object: T, keys: K[] = [], - rest: R -): Pick> & R { + rest?: R + // eslint-disable-next-line @typescript-eslint/ban-types +): Pick> & (R extends undefined ? {} : R) { const omitedObject: any = {} const originalKeys = Object.getOwnPropertyNames(object) originalKeys.forEach((originalKey) => { diff --git a/src/descriptions/index.js b/src/descriptions/index.ts similarity index 100% rename from src/descriptions/index.js rename to src/descriptions/index.ts diff --git a/src/descriptions/src/Descriptions.js b/src/descriptions/src/Descriptions.ts similarity index 90% rename from src/descriptions/src/Descriptions.js rename to src/descriptions/src/Descriptions.ts index 827f02d87..5f975304f 100644 --- a/src/descriptions/src/Descriptions.js +++ b/src/descriptions/src/Descriptions.ts @@ -1,15 +1,17 @@ -import { computed, h, defineComponent } from 'vue' -import { useTheme } from '../../_mixins' -import style from './styles/index.cssr.js' -import { warn, getSlot, getVNodeChildren, createKey } from '../../_utils' +import { computed, h, defineComponent, PropType, VNode } from 'vue' import { useCompitable } from 'vooks' -import { isDescriptionsItem } from './utils' +import { useTheme } from '../../_mixins' +import type { ThemeProps } from '../../_mixins' +import { warn, getSlot, getVNodeChildren, createKey } from '../../_utils' import { descriptionsLight } from '../styles' +import type { DescriptionsTheme } from '../styles' +import { isDescriptionsItem } from './utils' +import style from './styles/index.cssr' export default defineComponent({ name: 'Descriptions', props: { - ...useTheme.props, + ...(useTheme.props as ThemeProps), title: { type: String, default: undefined @@ -23,22 +25,16 @@ export default defineComponent({ default: undefined }, labelPlacement: { - default: 'top', - validator (value) { - return ['left', 'top'].includes(value) - } + type: String as PropType<'left' | 'top'>, + default: 'top' }, labelAlign: { - default: 'left', - validator (value) { - return ['left', 'right', 'center'].includes(value) - } + type: String as PropType<'left' | 'right' | 'center'>, + default: 'left' }, size: { - default: 'medium', - validator (value) { - return ['small', 'medium', 'large'].includes(value) - } + type: String as PropType<'small' | 'medium' | 'large'>, + default: 'medium' }, bordered: { type: Boolean, @@ -117,7 +113,7 @@ export default defineComponent({ '`n-descriptions` only takes `n-descriptions-item` as children.' ) } - children = children.reduce( + const itemState = children.reduce( (state, vNode, index) => { const props = vNode.props || {} const isLastIteration = children.length - 1 === index @@ -224,9 +220,14 @@ export default defineComponent({ row: [], secondRow: [], rows: [] + } as { + span: number + row: VNode[] + secondRow: VNode[] + rows: VNode[][] } ) - children = children.rows.map((row) => + const rows = itemState.rows.map((row) => h( 'tr', { @@ -270,7 +271,7 @@ export default defineComponent({ { class: 'n-descriptions-table' }, - [h('tbody', null, children)] + [h('tbody', null, rows)] ) ] ) diff --git a/src/descriptions/src/DescriptionsItem.js b/src/descriptions/src/DescriptionsItem.ts similarity index 100% rename from src/descriptions/src/DescriptionsItem.js rename to src/descriptions/src/DescriptionsItem.ts diff --git a/src/descriptions/src/styles/index.cssr.js b/src/descriptions/src/styles/index.cssr.js deleted file mode 100644 index 347fd12f2..000000000 --- a/src/descriptions/src/styles/index.cssr.js +++ /dev/null @@ -1,175 +0,0 @@ -import { c, cB, cE, cM, cNotM, insideModal } from '../../../_utils/cssr' - -// vars: -// --th-padding -// --td-padding -// --font-size -// --bezier -// --th-font-weight -// --line-height -// --th-text-color -// --td-text-color -// --th-color -// --td-color -// --td-color-modal -// --border-radius -// --border-color -export default c([ - cB('descriptions', { - fontSize: 'var(--font-size)' - }, [ - cB('descriptions-table-wrapper', [ - cB('descriptions-table', [ - cB('descriptions-table-row', [ - cB('descriptions-table-header', { - padding: 'var(--th-padding)' - }), - cB('descriptions-table-content', { - padding: 'var(--td-padding)' - }) - ]) - ]) - ]), - cNotM('bordered', [ - cB('descriptions-table-wrapper', [ - cB('descriptions-table', [ - cB('descriptions-table-row', [ - c('&:last-child', [ - cB('descriptions-table-content', { - paddingBottom: 0 - }) - ]) - ]) - ]) - ]) - ]), - cM('left-label-placement', [ - cB('descriptions-table-content', [ - c('> *', { - verticalAlign: 'top' - }) - ]) - ]), - cM('left-label-align', [ - c('th', { - textAlign: 'left' - }) - ]), - cM('center-label-align', [ - c('th', { - textAlign: 'center' - }) - ]), - cM('right-label-align', [ - c('th', { - textAlign: 'right' - }) - ]), - cM('bordered', [ - cB('descriptions-table-wrapper', ` - border-radius: var(--border-radius); - overflow: hidden; - background: var(--td-color); - border: 1px solid var(--border-color); - `, [ - cB('descriptions-table', [ - cB('descriptions-table-row', [ - c('&:not(:last-child)', [ - cB('descriptions-table-content', { - borderBottom: '1px solid var(--border-color)' - }), - cB('descriptions-table-header', { - borderBottom: '1px solid var(--border-color)' - }) - ]), - cB('descriptions-table-header', { - fontWeight: 400, - backgroundClip: 'padding-box', - backgroundColor: 'var(--th-color)' - }, [ - c('&:not(:last-child)', { - borderRight: '1px solid var(--border-color)' - }) - ]), - cB('descriptions-table-content', [ - c('&:not(:last-child)', { - borderRight: '1px solid var(--border-color)' - }) - ]) - ]) - ]) - ]) - ]), - cB('descriptions-header', ` - font-weight: var(--th-font-weight); - font-size: 18px; - transition: color .3s var(--bezier); - line-height: var(--line-height); - margin-bottom: 8px; - color: var(--th-text-color); - `), - cB('descriptions-table-wrapper', ` - transition: - background-color .3s var(--bezier), - border-color .3s var(--bezier); - `, [ - cB('descriptions-table', ` - width: 100%; - border-collapse: separate; - border-spacing: 0; - box-sizing: border-box; - `, [ - cB('descriptions-table-row', ` - box-sizing: border-box; - transition: border-color .3s var(--bezier); - `, [ - cB('descriptions-table-header', ` - font-weight: var(--th-font-weight); - line-height: var(--line-height); - display: table-cell; - box-sizing: border-box; - color: var(--th-text-color); - transition: - color .3s var(--bezier), - background-color .3s var(--bezier), - border-color .3s var(--bezier); - `), - cB('descriptions-table-content', ` - vertical-align: top; - line-height: var(--line-height); - display: table-cell; - box-sizing: border-box; - color: var(--td-text-color); - transition: - color .3s var(--bezier), - background-color .3s var(--bezier), - border-color .3s var(--bezier); - `, [ - cE('content', ` - transition: color .3s var(--bezier); - display: inline-block; - color: var(--td-text-color); - `) - ]), - cE('label', ` - font-weight: var(--th-font-weight); - transition: color .3s var(--bezier); - display: inline-block; - margin-right: 14px; - color: var(--th-text-color); - `) - ]) - ]) - ]) - ] - ), - insideModal( - cB('descriptions', [ - cM('bordered', [ - cB('descriptions-table-wrapper', { - background: 'var(--td-color-modal)' - }) - ]) - ]) - ) -]) diff --git a/src/descriptions/src/styles/index.cssr.ts b/src/descriptions/src/styles/index.cssr.ts new file mode 100644 index 000000000..04acd0e61 --- /dev/null +++ b/src/descriptions/src/styles/index.cssr.ts @@ -0,0 +1,214 @@ +import { c, cB, cE, cM, cNotM, insideModal } from '../../../_utils/cssr' + +// vars: +// --th-padding +// --td-padding +// --font-size +// --bezier +// --th-font-weight +// --line-height +// --th-text-color +// --td-text-color +// --th-color +// --td-color +// --td-color-modal +// --border-radius +// --border-color +export default c([ + cB( + 'descriptions', + { + fontSize: 'var(--font-size)' + }, + [ + cB('descriptions-table-wrapper', [ + cB('descriptions-table', [ + cB('descriptions-table-row', [ + cB('descriptions-table-header', { + padding: 'var(--th-padding)' + }), + cB('descriptions-table-content', { + padding: 'var(--td-padding)' + }) + ]) + ]) + ]), + cNotM('bordered', [ + cB('descriptions-table-wrapper', [ + cB('descriptions-table', [ + cB('descriptions-table-row', [ + c('&:last-child', [ + cB('descriptions-table-content', { + paddingBottom: 0 + }) + ]) + ]) + ]) + ]) + ]), + cM('left-label-placement', [ + cB('descriptions-table-content', [ + c('> *', { + verticalAlign: 'top' + }) + ]) + ]), + cM('left-label-align', [ + c('th', { + textAlign: 'left' + }) + ]), + cM('center-label-align', [ + c('th', { + textAlign: 'center' + }) + ]), + cM('right-label-align', [ + c('th', { + textAlign: 'right' + }) + ]), + cM('bordered', [ + cB( + 'descriptions-table-wrapper', + ` + border-radius: var(--border-radius); + overflow: hidden; + background: var(--td-color); + border: 1px solid var(--border-color); + `, + [ + cB('descriptions-table', [ + cB('descriptions-table-row', [ + c('&:not(:last-child)', [ + cB('descriptions-table-content', { + borderBottom: '1px solid var(--border-color)' + }), + cB('descriptions-table-header', { + borderBottom: '1px solid var(--border-color)' + }) + ]), + cB( + 'descriptions-table-header', + { + fontWeight: 400, + backgroundClip: 'padding-box', + backgroundColor: 'var(--th-color)' + }, + [ + c('&:not(:last-child)', { + borderRight: '1px solid var(--border-color)' + }) + ] + ), + cB('descriptions-table-content', [ + c('&:not(:last-child)', { + borderRight: '1px solid var(--border-color)' + }) + ]) + ]) + ]) + ] + ) + ]), + cB( + 'descriptions-header', + ` + font-weight: var(--th-font-weight); + font-size: 18px; + transition: color .3s var(--bezier); + line-height: var(--line-height); + margin-bottom: 8px; + color: var(--th-text-color); + ` + ), + cB( + 'descriptions-table-wrapper', + ` + transition: + background-color .3s var(--bezier), + border-color .3s var(--bezier); + `, + [ + cB( + 'descriptions-table', + ` + width: 100%; + border-collapse: separate; + border-spacing: 0; + box-sizing: border-box; + `, + [ + cB( + 'descriptions-table-row', + ` + box-sizing: border-box; + transition: border-color .3s var(--bezier); + `, + [ + cB( + 'descriptions-table-header', + ` + font-weight: var(--th-font-weight); + line-height: var(--line-height); + display: table-cell; + box-sizing: border-box; + color: var(--th-text-color); + transition: + color .3s var(--bezier), + background-color .3s var(--bezier), + border-color .3s var(--bezier); + ` + ), + cB( + 'descriptions-table-content', + ` + vertical-align: top; + line-height: var(--line-height); + display: table-cell; + box-sizing: border-box; + color: var(--td-text-color); + transition: + color .3s var(--bezier), + background-color .3s var(--bezier), + border-color .3s var(--bezier); + `, + [ + cE( + 'content', + ` + transition: color .3s var(--bezier); + display: inline-block; + color: var(--td-text-color); + ` + ) + ] + ), + cE( + 'label', + ` + font-weight: var(--th-font-weight); + transition: color .3s var(--bezier); + display: inline-block; + margin-right: 14px; + color: var(--th-text-color); + ` + ) + ] + ) + ] + ) + ] + ) + ] + ), + insideModal( + cB('descriptions', [ + cM('bordered', [ + cB('descriptions-table-wrapper', { + background: 'var(--td-color-modal)' + }) + ]) + ]) + ) +]) diff --git a/src/descriptions/src/utils.js b/src/descriptions/src/utils.js deleted file mode 100644 index 82cf0e0fd..000000000 --- a/src/descriptions/src/utils.js +++ /dev/null @@ -1,5 +0,0 @@ -export const DESCRIPTION_ITEM_FLAG = Symbol('DESCRIPTION_ITEM_FLAG') - -export function isDescriptionsItem (vNode) { - return vNode.type && vNode.type[DESCRIPTION_ITEM_FLAG] -} diff --git a/src/descriptions/src/utils.ts b/src/descriptions/src/utils.ts new file mode 100644 index 000000000..36cd3b8f3 --- /dev/null +++ b/src/descriptions/src/utils.ts @@ -0,0 +1,7 @@ +import { VNode } from 'vue' + +export const DESCRIPTION_ITEM_FLAG = Symbol('DESCRIPTION_ITEM_FLAG') + +export function isDescriptionsItem (vNode: VNode): boolean { + return vNode.type && (vNode.type as any)[DESCRIPTION_ITEM_FLAG] +} diff --git a/src/descriptions/styles/_common.js b/src/descriptions/styles/_common.ts similarity index 100% rename from src/descriptions/styles/_common.js rename to src/descriptions/styles/_common.ts diff --git a/src/descriptions/styles/dark.js b/src/descriptions/styles/dark.ts similarity index 87% rename from src/descriptions/styles/dark.js rename to src/descriptions/styles/dark.ts index 7c9b2c468..a38fa9b36 100644 --- a/src/descriptions/styles/dark.js +++ b/src/descriptions/styles/dark.ts @@ -1,7 +1,8 @@ import commonVariables from './_common' import { commonDark } from '../../_styles/new-common' +import type { DescriptionsTheme } from './light' -export default { +const descriptionsDark: DescriptionsTheme = { name: 'Descriptions', common: commonDark, self (vars) { @@ -36,3 +37,5 @@ export default { } } } + +export default descriptionsDark diff --git a/src/descriptions/styles/index.js b/src/descriptions/styles/index.js deleted file mode 100644 index 9dd5813cc..000000000 --- a/src/descriptions/styles/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default as descriptionsDark } from './dark.js' -export { default as descriptionsLight } from './light.js' diff --git a/src/descriptions/styles/index.ts b/src/descriptions/styles/index.ts new file mode 100644 index 000000000..8c97a7817 --- /dev/null +++ b/src/descriptions/styles/index.ts @@ -0,0 +1,3 @@ +export { default as descriptionsDark } from './dark' +export { default as descriptionsLight } from './light' +export type { DescriptionsTheme, DescriptionsThemeVars } from './light' diff --git a/src/descriptions/styles/light.js b/src/descriptions/styles/light.js deleted file mode 100644 index 425c4fc65..000000000 --- a/src/descriptions/styles/light.js +++ /dev/null @@ -1,39 +0,0 @@ -import { composite } from 'seemly' -import commonVariables from './_common' -import { commonLight } from '../../_styles/new-common' - -export default { - name: 'Descriptions', - common: commonLight, - self (vars) { - const { - tableHeaderColorOverlay, - textColor1Overlay, - textColor2Overlay, - cardColor, - modalColor, - dividerColorOverlay, - borderRadius, - fontWeightStrong, - lineHeight, - fontSizeSmall, - fontSizeMedium, - fontSizeLarge - } = vars - return { - ...commonVariables, - lineHeight, - fontSizeSmall, - fontSizeMedium, - fontSizeLarge, - thColor: composite(cardColor, tableHeaderColorOverlay), - thTextColor: textColor1Overlay, - thFontWeight: fontWeightStrong, - tdTextColor: textColor2Overlay, - tdColor: cardColor, - tdColorModal: modalColor, - borderColor: dividerColorOverlay, - borderRadius: borderRadius - } - } -} diff --git a/src/descriptions/styles/light.ts b/src/descriptions/styles/light.ts new file mode 100644 index 000000000..f86dab46a --- /dev/null +++ b/src/descriptions/styles/light.ts @@ -0,0 +1,47 @@ +import { composite } from 'seemly' +import commonVariables from './_common' +import { commonLight, ThemeCommonVars } from '../../_styles/new-common' +import { Theme } from '../../_mixins/use-theme' + +const self = (vars: ThemeCommonVars) => { + const { + tableHeaderColorOverlay, + textColor1Overlay, + textColor2Overlay, + cardColor, + modalColor, + dividerColorOverlay, + borderRadius, + fontWeightStrong, + lineHeight, + fontSizeSmall, + fontSizeMedium, + fontSizeLarge + } = vars + return { + ...commonVariables, + lineHeight, + fontSizeSmall, + fontSizeMedium, + fontSizeLarge, + thColor: composite(cardColor, tableHeaderColorOverlay), + thTextColor: textColor1Overlay, + thFontWeight: fontWeightStrong, + tdTextColor: textColor2Overlay, + tdColor: cardColor, + tdColorModal: modalColor, + borderColor: dividerColorOverlay, + borderRadius: borderRadius + } +} + +export type DescriptionsThemeVars = ReturnType + +const descriptionsLight: Theme = { + name: 'Descriptions', + common: commonLight, + self +} + +export default descriptionsLight +export type DescriptionsTheme = typeof descriptionsLight