feat(timeline): clsPrefix

This commit is contained in:
07akioni 2021-04-16 16:35:56 +08:00
parent 4bb94d676d
commit 79ea3015af
3 changed files with 94 additions and 56 deletions

View File

@ -1,3 +1,4 @@
/* istanbul ignore file */
export { default as NTimeline } from './src/Timeline'
export { default as NTimelineItem } from './src/TimelineItem'
export type { TimelineProps } from './src/Timeline'
export type { TimelineItemProps } from './src/TimelineItem'

View File

@ -1,7 +1,18 @@
import { h, defineComponent, PropType, ExtractPropTypes, provide } from 'vue'
import { useTheme } from '../../_mixins'
import {
h,
defineComponent,
PropType,
ExtractPropTypes,
provide,
InjectionKey,
Ref
} from 'vue'
import { MergedTheme, useConfig, useTheme } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import type { TimelineTheme } from '../styles'
import type { ExtractPublicPropTypes } from '../../_utils'
import { timelineLight } from '../styles'
import style from './styles/index.cssr'
const timelineProps = {
...(useTheme.props as ThemeProps<TimelineTheme>),
@ -15,28 +26,47 @@ const timelineProps = {
}
} as const
export type TimelineInjection = ExtractPropTypes<typeof timelineProps>
export interface TimelineInjection {
props: ExtractPropTypes<typeof timelineProps>
mergedThemeRef: Ref<MergedTheme<TimelineTheme>>
cPrefixRef: Ref<string>
}
export const timelineInjectionKey: InjectionKey<TimelineInjection> = Symbol(
'timeline'
)
export type TimelineProps = ExtractPublicPropTypes<typeof timelineProps>
export default defineComponent({
name: 'Timeline',
provide () {
return {
NTimeline: this
}
},
props: timelineProps,
setup (props, { slots }) {
provide<TimelineInjection>('NTimeline', props)
return () => (
<div
class={[
'n-timeline',
`n-timeline--${props.size}-size`,
`n-timeline--${props.itemPlacement}-placement`
]}
>
{slots}
</div>
const { mergedClsPrefix } = useConfig(props)
const themeRef = useTheme(
'Timeline',
'Timeline',
style,
timelineLight,
props,
mergedClsPrefix
)
provide(timelineInjectionKey, {
props,
mergedThemeRef: themeRef,
cPrefixRef: mergedClsPrefix
})
return () => {
const { value: cPrefix } = mergedClsPrefix
return (
<div
class={[
`${cPrefix}-timeline`,
`${cPrefix}-timeline--${props.size}-size`,
`${cPrefix}-timeline--${props.itemPlacement}-placement`
]}
>
{slots}
</div>
)
}
}
})

View File

@ -7,39 +7,42 @@ import {
renderSlot,
CSSProperties
} from 'vue'
import { useTheme } from '../../_mixins'
import { createKey } from '../../_utils'
import { timelineLight } from '../styles'
import type { TimelineInjection } from './Timeline'
import style from './styles/index.cssr'
import { createKey, throwError } from '../../_utils'
import type { ExtractPublicPropTypes } from '../../_utils'
import { timelineInjectionKey } from './Timeline'
const timelineItemProps = {
time: [String, Number] as PropType<string | number>,
title: String,
content: String,
type: {
type: String as PropType<
'default' | 'success' | 'error' | 'warning' | 'info'
>,
default: 'default'
}
}
export type TimelineItemProps = ExtractPublicPropTypes<typeof timelineItemProps>
export default defineComponent({
name: 'TimelineItem',
props: {
time: [String, Number],
title: String,
content: String,
type: {
type: String as PropType<
'default' | 'success' | 'error' | 'warning' | 'info'
>,
default: 'default'
}
},
props: timelineItemProps,
setup (props) {
const NTimeline = inject<TimelineInjection>(
'NTimeline'
) as TimelineInjection
const themeRef = useTheme(
'Timeline',
'Timeline',
style,
timelineLight,
NTimeline
)
const NTimeline = inject(timelineInjectionKey)
if (!NTimeline) {
throwError(
'timeline-item',
'`n-timeline-item` must be placed inside `n-timeline`.'
)
}
return {
cPrefix: NTimeline.cPrefixRef,
cssVars: computed(() => {
const { size } = NTimeline
const {
props: { size },
mergedThemeRef
} = NTimeline
const { type } = props
const {
self: {
@ -54,7 +57,7 @@ export default defineComponent({
[createKey('circleBorder', type)]: circleBorder
},
common: { cubicBezierEaseInOut }
} = themeRef.value
} = mergedThemeRef.value
return {
'--bezier': cubicBezierEaseInOut,
'--circle-border': circleBorder,
@ -71,27 +74,31 @@ export default defineComponent({
}
},
render () {
const { cPrefix } = this
return (
<div
class={['n-timeline-item', `n-timeline-item--${this.type}-type`]}
class={[
`${cPrefix}-timeline-item`,
`${cPrefix}-timeline-item--${this.type}-type`
]}
style={this.cssVars as CSSProperties}
>
<div class="n-timeline-item-timeline">
<div class="n-timeline-item-timeline__line" />
<div class="n-timeline-item-timeline__circle" />
<div class={`${cPrefix}-timeline-item-timeline`}>
<div class={`${cPrefix}-timeline-item-timeline__line`} />
<div class={`${cPrefix}-timeline-item-timeline__circle`} />
</div>
<div class="n-timeline-item-content">
<div class={`${cPrefix}-timeline-item-content`}>
{this.title ? (
<div class="n-timeline-item-content__title">
<div class={`${cPrefix}-timeline-item-content__title`}>
{renderSlot(this.$slots, 'header', undefined, () => [this.title])}
</div>
) : null}
<div class="n-timeline-item-content__content">
<div class={`${cPrefix}-timeline-item-content__content`}>
{renderSlot(this.$slots, 'default', undefined, () => [
this.content
])}
</div>
<div class="n-timeline-item-content__meta">
<div class={`${cPrefix}-timeline-item-content__meta`}>
{renderSlot(this.$slots, 'footer', undefined, () => [this.time])}
</div>
</div>