feat(legacy-grid, statistic, thing): rtl (#3326)

* feat(tree): support rtl

* feat(legacy-grid): support rtl

* feat(statistic): support rtl

* feat(thing): support rtl

Co-authored-by: 07akioni <07akioni2@gmail.com>
This commit is contained in:
Leila Ahmadi 2022-07-24 20:11:13 +04:30 committed by GitHub
parent d2344265a8
commit dffff72469
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 372 additions and 11 deletions

View File

@ -25,6 +25,9 @@
- `n-checkbox-group`'s `on-update:value` prop adds trigger checkbox's value to params, closes [#3277](https://github.com/TuSimple/naive-ui/issues/3277).
- `n-tree` supports RTL.
- `n-input` adds `scrollTo` method, closes [#3280](https://github.com/TuSimple/naive-ui/issues/3280).
- `n-legacy-grid` supports RTL.
- `n-statistic` supports RTL.
- `n-thing` supports RTL.
- `n-transfer` add `render-source-label` prop.
- `n-transfer` add `render-target-label` prop.
- `n-transfer` add `render-source-list` prop.

View File

@ -25,6 +25,9 @@
- `n-checkbox-group``on-update:value` 属性增加触发变更的 checkbox 的值到参数中,关闭 [#3277](https://github.com/TuSimple/naive-ui/issues/3277)
- `n-tree` 支持 RTL
- `n-input` 新增 `scrollTo` 方法,关闭 [#3280](https://github.com/TuSimple/naive-ui/issues/3280)
- `n-legacy-grid` 支持 RTL
- `n-statistic` 支持 RTL
- `n-thing` 支持 RTL
- `n-transfer` 新增 `render-source-label` 属性
- `n-transfer` 新增 `render-target-label` 属性
- `n-transfer` 新增 `render-source-list` 属性

View File

@ -94,6 +94,7 @@ import type { GlobalTheme, GlobalThemeOverrides } from './interface'
import type { EmptyProps } from '../../empty'
import type { CollapseTransitionTheme } from '../../collapse-transition/styles'
import type { ButtonGroupTheme } from '../../button-group/styles/light'
import type { RowTheme } from '../../legacy-grid/styles'
export interface GlobalThemeWithoutCommon {
Alert?: AlertTheme
@ -175,6 +176,7 @@ export interface GlobalThemeWithoutCommon {
Typography?: TypographyTheme
Upload?: UploadTheme
Watermark?: WatermarkTheme
Row?: RowTheme
// internal
InternalSelectMenu?: InternalSelectMenuTheme
InternalSelection?: InternalSelectionTheme

View File

@ -16,6 +16,7 @@ gutter.vue
offset.vue
push-pull.vue
wrap-debug.vue
rtl-debug.vue
```
## API

View File

@ -0,0 +1,50 @@
<markdown>
# Rtl Debug
</markdown>
<template>
<n-space vertical>
<n-space><n-switch v-model:value="rtlEnabled" />Rtl</n-space>
<n-config-provider :rtl="rtlEnabled ? rtlStyles : undefined">
<n-row gutter="12">
<n-col :span="6">
<div class="light-green" />
</n-col>
<n-col :span="6">
<div class="green" />
</n-col>
<n-col :span="6">
<div class="light-green" />
</n-col>
<n-col :span="6">
<div class="green" />
</n-col>
</n-row>
</n-config-provider>
</n-space>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
import { unstableRowRtl } from 'naive-ui'
export default defineComponent({
setup () {
return {
rtlEnabled: ref(false),
rtlStyles: [unstableRowRtl]
}
}
})
</script>
<style>
.light-green {
height: 108px;
background-color: rgba(0, 128, 0, 0.12);
}
.green {
height: 108px;
background-color: rgba(0, 128, 0, 0.24);
}
</style>

View File

@ -6,7 +6,7 @@ import {
formatLength,
keysOf
} from '../../_utils'
import { useConfig, useStyle } from '../../_mixins'
import { useConfig, useStyle, useRtl } from '../../_mixins'
import style from './styles/index.cssr'
export interface RowInjection {
@ -37,8 +37,9 @@ export default defineComponent({
name: 'Row',
props: rowProps,
setup (props) {
const { mergedClsPrefixRef } = useConfig(props)
const { mergedClsPrefixRef, mergedRtlRef } = useConfig(props)
useStyle('-legacy-grid', style, mergedClsPrefixRef)
const rtlEnabledRef = useRtl('Row', mergedRtlRef, mergedClsPrefixRef)
const verticalGutterRef = useMemo(() => {
const { gutter } = props
if (Array.isArray(gutter)) {
@ -61,6 +62,7 @@ export default defineComponent({
})
return {
mergedClsPrefix: mergedClsPrefixRef,
rtlEnabled: rtlEnabledRef,
styleMargin: useMemo(
() =>
`-${formatLength(verticalGutterRef.value, {
@ -75,7 +77,10 @@ export default defineComponent({
render () {
return (
<div
class={`${this.mergedClsPrefix}-row`}
class={[
`${this.mergedClsPrefix}-row`,
this.rtlEnabled && `${this.mergedClsPrefix}-row--rtl`
]}
style={{
margin: this.styleMargin,
width: this.styleWidth,

View File

@ -0,0 +1,34 @@
import { cB, cM } from '../../../_utils/cssr'
const positionStyles = Array
.apply(null, { length: 24 } as any)
.map((_, index) => {
const prefixIndex = index + 1
const percent = `calc(100% / 24 * ${prefixIndex})`
return [
cM(`${prefixIndex}-span`, {
width: percent
}),
cM(`${prefixIndex}-offset`, {
marginLeft: percent
}),
cM(`${prefixIndex}-push`, {
right: percent,
left: 'unset'
}),
cM(`${prefixIndex}-pull`, {
left: percent,
right: 'unset'
})
]
})
export default cB('row', [
cM('rtl', `
direction: rtl;
`, [
cB('col', [
positionStyles
])
])
])

View File

@ -0,0 +1,3 @@
export { default as inputLight } from './light'
export { rowRtl } from './rtl'
export type { RowTheme } from './light'

View File

@ -0,0 +1,10 @@
import { commonLight } from '../../_styles/common'
import type { Theme } from '../../_mixins'
const rowLight: Theme<'Row'> = {
name: 'Row',
common: commonLight
}
export default rowLight
export type RowTheme = typeof rowLight

View File

@ -0,0 +1,7 @@
import type { RtlItem } from '../../config-provider/src/internal-interface'
import rtlStyle from '../src/styles/rtl.cssr'
export const rowRtl: RtlItem = {
name: 'Row',
style: rtlStyle
}

View File

@ -6,6 +6,7 @@
```demo
basic.vue
rtl-debug.vue
```
## API

View File

@ -0,0 +1,48 @@
<markdown>
# Rtl Debug
</markdown>
<template>
<n-space vertical>
<n-space><n-switch v-model:value="rtlEnabled" />Rtl</n-space>
<n-config-provider :rtl="rtlEnabled ? rtlStyles : undefined">
<n-row>
<n-col :span="12">
<n-statistic label="Statistic" :value="99">
<template #prefix>
<n-icon>
<md-save />
</n-icon>
</template>
<template #suffix>
/ 100
</template>
</n-statistic>
</n-col>
<n-col :span="12">
<n-statistic label="Active Users">
1,234,123
</n-statistic>
</n-col>
</n-row>
</n-config-provider>
</n-space>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
import { unstableStatisticRtl, unstableRowRtl } from 'naive-ui'
import { MdSave } from '@vicons/ionicons4'
export default defineComponent({
components: {
MdSave
},
setup () {
return {
rtlEnabled: ref(false),
rtlStyles: [unstableStatisticRtl, unstableRowRtl]
}
}
})
</script>

View File

@ -1,5 +1,5 @@
import { defineComponent, computed, h } from 'vue'
import { useConfig, useTheme, useThemeClass } from '../../_mixins'
import { useConfig, useTheme, useThemeClass, useRtl } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import { resolveWrappedSlot } from '../../_utils'
import type { ExtractPublicPropTypes } from '../../_utils'
@ -20,7 +20,8 @@ export default defineComponent({
name: 'Statistic',
props: statisticProps,
setup (props) {
const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props)
const { mergedClsPrefixRef, inlineThemeDisabled, mergedRtlRef } =
useConfig(props)
const themeRef = useTheme(
'Statistic',
'-statistic',
@ -29,6 +30,7 @@ export default defineComponent({
props,
mergedClsPrefixRef
)
const rtlEnabledRef = useRtl('Statistic', mergedRtlRef, mergedClsPrefixRef)
const cssVarsRef = computed(() => {
const {
self: {
@ -57,6 +59,7 @@ export default defineComponent({
? useThemeClass('statistic', undefined, cssVarsRef, props)
: undefined
return {
rtlEnabled: rtlEnabledRef,
mergedClsPrefix: mergedClsPrefixRef,
cssVars: inlineThemeDisabled ? undefined : cssVarsRef,
themeClass: themeClassHandle?.themeClass,
@ -76,7 +79,11 @@ export default defineComponent({
this.onRender?.()
return (
<div
class={[`${mergedClsPrefix}-statistic`, this.themeClass]}
class={[
`${mergedClsPrefix}-statistic`,
this.themeClass,
this.rtlEnabled && `${mergedClsPrefix}-statistic--rtl`
]}
style={this.cssVars as any}
>
{resolveWrappedSlot(labelSlot, (children) => (

View File

@ -0,0 +1,17 @@
import { cB, cE, cM } from '../../../_utils/cssr'
export default cB('statistic', [
cM('rtl', `
direction: rtl;
text-align: right;
`, [
cB('statistic-value', [
cE('prefix', `
margin: 0 0 0 4px;
`),
cE('suffix', `
margin: 0 4px 0 0;
`)
])
])
])

View File

@ -1,3 +1,4 @@
export { default as statisticDark } from './dark'
export { default as statisticLight } from './light'
export { statisticRtl } from './rtl'
export type { StatisticTheme, StatisticThemeVars } from './light'

View File

@ -0,0 +1,7 @@
import { RtlItem } from '../../config-provider/src/internal-interface'
import rtlStyle from '../src/styles/rtl.cssr'
export const statisticRtl: RtlItem = {
name: 'Statistic',
style: rtlStyle
}

View File

@ -72,13 +72,16 @@ export { selectDark } from './select/styles'
export { sliderDark } from './slider/styles'
export { spaceDark, spaceRtl as unstableSpaceRtl } from './space/styles'
export { spinDark } from './spin/styles'
export { statisticDark } from './statistic/styles'
export {
statisticDark,
statisticRtl as unstableStatisticRtl
} from './statistic/styles'
export { stepsDark } from './steps/styles'
export { switchDark } from './switch/styles'
export { tableDark, tableRtl as unstableTableRtl } from './table/styles'
export { tabsDark } from './tabs/styles'
export { tagDark, tagRtl as unstableTagRtl } from './tag/styles'
export { thingDark } from './thing/styles'
export { thingDark, thingRtl as unstableThingRtl } from './thing/styles'
export { timePickerDark } from './time-picker/styles'
export { timelineDark } from './timeline/styles'
export { tooltipDark } from './tooltip/styles'
@ -88,6 +91,7 @@ export { treeSelectDark } from './tree-select/styles'
export { typographyDark } from './typography/styles'
export { uploadDark } from './upload/styles'
export { watermarkDark } from './watermark/styles'
export { rowRtl as unstableRowRtl } from './legacy-grid/styles'
// danger zone, internal styles
export { scrollbarDark } from './_internal/scrollbar/styles'

View File

@ -9,6 +9,7 @@
```demo
basic.vue
indent.vue
rtl-debug.vue
```
## API

View File

@ -0,0 +1,126 @@
<markdown>
# Rtl Debug
</markdown>
<template>
<n-space vertical>
<n-space><n-switch v-model:value="rtlEnabled" />Rtl</n-space>
<n-config-provider :rtl="rtlEnabled ? rtlStyles : undefined">
<n-row>
<n-col :span="12">
<n-checkbox v-model:checked="avatar">
Avatar
</n-checkbox>
</n-col>
<n-col :span="12">
<n-checkbox v-model:checked="action">
Action
</n-checkbox>
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox v-model:checked="header">
Header
</n-checkbox>
</n-col>
<n-col :span="12">
<n-checkbox v-model:checked="headerExtra">
Header Extra
</n-checkbox>
</n-col>
</n-row>
<n-row>
<n-col :span="12">
<n-checkbox v-model:checked="description">
Description
</n-checkbox>
</n-col>
<n-col :span="12">
<n-checkbox v-model:checked="footer">
Footer
</n-checkbox>
</n-col>
</n-row>
<n-divider />
<n-thing>
<template v-if="avatar" #avatar>
<n-avatar>
<n-icon>
<cash-icon />
</n-icon>
</n-avatar>
</template>
<template v-if="header" #header>
货币
</template>
<template v-if="headerExtra" #header-extra>
<n-button circle size="small">
<template #icon>
<cash-icon />
</template>
</n-button>
</template>
<template v-if="description" #description>
描述
</template>
货币是为了提高交易效率而用于交换的中介商品货币有多种形式如贝壳粮食等自然物金属纸张等加工品银行卡信用卡等磁条卡移动支付加密货币等APP
<template v-if="footer" #footer>
尾部
</template>
<template v-if="action" #action>
<n-space>
<n-button size="small">
<template #icon>
<n-icon>
<cash-icon />
</n-icon>
</template>
1 块钱
</n-button>
<n-button size="small">
<template #icon>
<n-icon>
<cash-icon />
</n-icon>
</template>
10 块钱
</n-button>
<n-button size="small">
<template #icon>
<n-icon>
<cash-icon />
</n-icon>
</template>
100 块钱
</n-button>
</n-space>
</template>
</n-thing>
</n-config-provider>
</n-space>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
import { CashOutline as CashIcon } from '@vicons/ionicons5'
import { unstableThingRtl, unstableRowRtl } from 'naive-ui'
export default defineComponent({
components: {
CashIcon
},
setup () {
return {
rtlEnabled: ref(false),
rtlStyles: [unstableThingRtl, unstableRowRtl],
avatar: ref(true),
header: ref(true),
headerExtra: ref(true),
description: ref(true),
footer: ref(true),
action: ref(true)
}
}
})
</script>

View File

@ -1,5 +1,5 @@
import { h, defineComponent, computed, CSSProperties, Fragment } from 'vue'
import { useConfig, useTheme, useThemeClass } from '../../_mixins'
import { useConfig, useTheme, useThemeClass, useRtl } from '../../_mixins'
import type { ExtractPublicPropTypes } from '../../_utils'
import type { ThemeProps } from '../../_mixins'
import { thingLight } from '../styles'
@ -24,7 +24,8 @@ export default defineComponent({
name: 'Thing',
props: thingProps,
setup (props, { slots }) {
const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props)
const { mergedClsPrefixRef, inlineThemeDisabled, mergedRtlRef } =
useConfig(props)
const themeRef = useTheme(
'Thing',
'-thing',
@ -33,6 +34,7 @@ export default defineComponent({
props,
mergedClsPrefixRef
)
const rtlEnabledRef = useRtl('Thing', mergedRtlRef, mergedClsPrefixRef)
const cssVarsRef = computed(() => {
const {
self: { titleTextColor, textColor, titleFontWeight, fontSize },
@ -52,10 +54,15 @@ export default defineComponent({
return () => {
const { value: mergedClsPrefix } = mergedClsPrefixRef
const rtlEnabled = rtlEnabledRef ? rtlEnabledRef.value : false
themeClassHandle?.onRender?.()
return (
<div
class={[`${mergedClsPrefix}-thing`, themeClassHandle?.themeClass]}
class={[
`${mergedClsPrefix}-thing`,
themeClassHandle?.themeClass,
rtlEnabled && `${mergedClsPrefix}-thing--rtl`
]}
style={
inlineThemeDisabled
? undefined

View File

@ -0,0 +1,13 @@
import { cB, cM } from '../../../_utils/cssr'
export default cB('thing', [
cM('rtl', `
direction: rtl;
text-align: right;
`, [
cB('thing-avatar', `
margin-left: 12px;
margin-right: 0;
`)
])
])

View File

@ -1,3 +1,4 @@
export { default as thingDark } from './dark'
export { default as thingLight } from './light'
export { thingRtl } from './rtl'
export type { ThingThemeVars, ThingTheme } from './light'

10
src/thing/styles/rtl.ts Normal file
View File

@ -0,0 +1,10 @@
import { RtlItem } from '../../config-provider/src/internal-interface'
import rtlStyle from '../src/styles/rtl.cssr'
import { buttonRtl } from '../../button/styles/rtl'
import { spaceRtl } from '../../space/styles/rtl'
export const thingRtl: RtlItem = {
name: 'Thing',
style: rtlStyle,
peers: [buttonRtl, spaceRtl]
}