From 77b68bea184cfc184497bed2bc74d7627898f743 Mon Sep 17 00:00:00 2001 From: GaoNeng <31283122+GaoNeng-wWw@users.noreply.github.com> Date: Thu, 8 Jun 2023 10:18:17 +0800 Subject: [PATCH] feat: config-provider (#271) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: config-provider * 🐞 fix(config-provider): 开发者如果只覆盖某个design item 那么其他的常量会被覆盖为 undefined. commit主要修复该问题 * 🧪 test(config-provider): 补充单元测试 * 🐞 fix(config-provider): 修改检视意见 --- .../pc/api/zh-CN/config-provider.json | 32 +++++ .../pc/demo-config/zh-CN/config-provider.json | 18 +++ .../pc/demo/config-provider/base.vue | 48 +++++++ .../pc/demo/config-provider/text-direct.vue | 125 ++++++++++++++++++ examples/docs/resources/pc/menus.js | 6 + packages/theme/src/config-provider/index.js | 15 +++ packages/theme/src/config-provider/index.less | 12 ++ packages/theme/src/config-provider/vars.less | 12 ++ .../__tests__/config-provider.spec.ts | 92 +++++++++++++ .../src/config-provider/hooks/use-config.ts | 7 + packages/vue/src/config-provider/index.ts | 2 + .../vue/src/config-provider/src/index.vue | 101 ++++++++++++-- packages/vue/src/config-provider/src/props.ts | 23 ++++ 13 files changed, 483 insertions(+), 10 deletions(-) create mode 100644 examples/docs/resources/pc/api/zh-CN/config-provider.json create mode 100644 examples/docs/resources/pc/demo-config/zh-CN/config-provider.json create mode 100644 examples/docs/resources/pc/demo/config-provider/base.vue create mode 100644 examples/docs/resources/pc/demo/config-provider/text-direct.vue create mode 100644 packages/theme/src/config-provider/index.js create mode 100644 packages/theme/src/config-provider/index.less create mode 100644 packages/theme/src/config-provider/vars.less create mode 100644 packages/vue/src/config-provider/__tests__/config-provider.spec.ts create mode 100644 packages/vue/src/config-provider/hooks/use-config.ts create mode 100644 packages/vue/src/config-provider/src/props.ts diff --git a/examples/docs/resources/pc/api/zh-CN/config-provider.json b/examples/docs/resources/pc/api/zh-CN/config-provider.json new file mode 100644 index 000000000..0f659832a --- /dev/null +++ b/examples/docs/resources/pc/api/zh-CN/config-provider.json @@ -0,0 +1,32 @@ +{ + "attrs": [ + { + "name": "design", + "sample": "base", + "desc": "规范", + "type": "ConfigProviderProps", + "defaultValue": "" + }, + { + "name": "breakPoints", + "sample": "base", + "desc": "断点, 为Layout提供", + "type": "breakPoint", + "defaultValue": "{'xs': 480,'sm': 640,'md': 768,'lg': 1024,'xl': 1280,'2xl': 1536}" + }, + { + "name": "direction", + "sample": "text-dire", + "desc": "文字排版方向", + "type": "'ltr' | 'rtl'", + "defaultValue": "ltr" + }, + { + "name": "tag", + "type": "object", + "desc": "是否被元素包裹, 如果是vue2且没有一个单一节点, 组件会自动创建一个div", + "sample": "base", + "defaultValue": "{enable: true,name: 'div'}" + } + ] +} \ No newline at end of file diff --git a/examples/docs/resources/pc/demo-config/zh-CN/config-provider.json b/examples/docs/resources/pc/demo-config/zh-CN/config-provider.json new file mode 100644 index 000000000..82ef2c0d1 --- /dev/null +++ b/examples/docs/resources/pc/demo-config/zh-CN/config-provider.json @@ -0,0 +1,18 @@ +[ + { + "title": "基本使用", + "content": "如何使用ConfigProvider组件", + "link": "config-provider/base", + "component": " ConfigProvide 组件", + "findIntroStr": "", + "demoId": "base" + }, + { + "title": "改变文字方向", + "content": "有时, 我们需要改变文字的排列方向, 例如我们在排列阿拉伯语是就需要RTL而非LTR.config-provider也考虑到了这点,只需要覆写design.direction即可", + "link": "config-provider/text-direct", + "component": " ConfigProvide 组件", + "findIntroStr": "", + "demoId": "text-direct" + } +] \ No newline at end of file diff --git a/examples/docs/resources/pc/demo/config-provider/base.vue b/examples/docs/resources/pc/demo/config-provider/base.vue new file mode 100644 index 000000000..f19f82548 --- /dev/null +++ b/examples/docs/resources/pc/demo/config-provider/base.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/examples/docs/resources/pc/demo/config-provider/text-direct.vue b/examples/docs/resources/pc/demo/config-provider/text-direct.vue new file mode 100644 index 000000000..28fac4f60 --- /dev/null +++ b/examples/docs/resources/pc/demo/config-provider/text-direct.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/examples/docs/resources/pc/menus.js b/examples/docs/resources/pc/menus.js index f3e61b866..db4364776 100644 --- a/examples/docs/resources/pc/menus.js +++ b/examples/docs/resources/pc/menus.js @@ -1075,6 +1075,12 @@ const routerArr = [ zh: '全屏显示', enSuffix: true, path: '/fullscreen' + }, + { + en: 'ConfigProvider', + zh: '全局设置', + enSuffix: true, + path: '/config-provider' } ] } diff --git a/packages/theme/src/config-provider/index.js b/packages/theme/src/config-provider/index.js new file mode 100644 index 000000000..dbba6e544 --- /dev/null +++ b/packages/theme/src/config-provider/index.js @@ -0,0 +1,15 @@ +/** +* Copyright (c) 2022 - present TinyVue Authors. +* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd. +* +* Use of this source code is governed by an MIT-style license. +* +* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, +* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR +* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. +* +*/ + +export default { + // Config-Provider +} diff --git a/packages/theme/src/config-provider/index.less b/packages/theme/src/config-provider/index.less new file mode 100644 index 000000000..229917d52 --- /dev/null +++ b/packages/theme/src/config-provider/index.less @@ -0,0 +1,12 @@ +/** +* Copyright (c) 2022 - present TinyVue Authors. +* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd. +* +* Use of this source code is governed by an MIT-style license. +* +* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, +* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR +* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. +* +*/ + diff --git a/packages/theme/src/config-provider/vars.less b/packages/theme/src/config-provider/vars.less new file mode 100644 index 000000000..229917d52 --- /dev/null +++ b/packages/theme/src/config-provider/vars.less @@ -0,0 +1,12 @@ +/** +* Copyright (c) 2022 - present TinyVue Authors. +* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd. +* +* Use of this source code is governed by an MIT-style license. +* +* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, +* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR +* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. +* +*/ + diff --git a/packages/vue/src/config-provider/__tests__/config-provider.spec.ts b/packages/vue/src/config-provider/__tests__/config-provider.spec.ts new file mode 100644 index 000000000..5eaaef33c --- /dev/null +++ b/packages/vue/src/config-provider/__tests__/config-provider.spec.ts @@ -0,0 +1,92 @@ +import { mountPcMode } from '@opentiny-internal/vue-test-utils' +import { describe, test, expect } from 'vitest' +import ConfigProvider, { configProviderContextKey } from '@opentiny/vue-config-provider' +import { defineComponent, h, inject } from 'vue' +import type { ConfigProviderProps } from '../src/props' +import { isVue2 } from '@opentiny/vue-common' + +describe('PC Mode', () => { + const mount = mountPcMode + test('rtl', () => { + const wrapper = mount(ConfigProvider, { + props: { + direction: 'rtl' + } + }) + expect(wrapper.classes()).toContain('tiny-config-provider--rtl') + }) + describe('tag', () => { + test('no tag', () => { + const wrapper = mount(ConfigProvider, { + props: { + tag: { + enable: false, + } + }, + slots: { + default: [''], + } + }) + expect(wrapper.html()).not.contain('div') + }) + test('has tag but not div', () => { + const wrapper = mount(ConfigProvider, { + props: { + tag: { + enable: true, + name: 'custom-el' + } + } + }) + const html = wrapper.html() + expect(html).contain('custom-el') + expect(html).not.contain('div') + }) + test('mutil node', () => { + const wrapper = mount(ConfigProvider, { + props: { + tag: { + enable: false + } + }, + slots: { + default: ['', ''] + } + }) + if (isVue2) { + expect(wrapper.html()).contain('div') + expect(wrapper.classes().length).toBe(0) + } else { + expect(wrapper.html()).not.contain('div') + } + }) + }) + if (!isVue2) { + describe('inject', () => { + test('one layer', () => { + let component + if (!isVue2) { + component = defineComponent({ + name: 'CustomComponent', + setup() { + const config = inject(configProviderContextKey) + expect(config).not.toBeNull() + expect(config).not.toStrictEqual({}) + expect(config?.direction).not.toBe('ltr') + // just fix Component is missing template or render function. + return () => h('div') + } + }) + } + mount(ConfigProvider, { + slots: { + default: [component] + }, + props: { + direction: 'rtl' + } + }) + }) + }) + } +}) diff --git a/packages/vue/src/config-provider/hooks/use-config.ts b/packages/vue/src/config-provider/hooks/use-config.ts new file mode 100644 index 000000000..c73e0bd5b --- /dev/null +++ b/packages/vue/src/config-provider/hooks/use-config.ts @@ -0,0 +1,7 @@ +import type { ConfigProviderProps } from '../src/props' +import { configProviderContextKey } from '../index' +import { hooks } from '@opentiny/vue-common/src' + +export function useConfig(): ConfigProviderProps | {} { + return hooks.inject(configProviderContextKey) ?? {} +} diff --git a/packages/vue/src/config-provider/index.ts b/packages/vue/src/config-provider/index.ts index 9f8d14ea5..74a61bc1c 100644 --- a/packages/vue/src/config-provider/index.ts +++ b/packages/vue/src/config-provider/index.ts @@ -1,6 +1,8 @@ import ConfigProvider from './src/index.vue' import { version } from './package.json' +export const configProviderContextKey = Symbol('CONFIG_PROVIDER_CONTEXT_KEY') + /* istanbul ignore next */ ConfigProvider.install = function (Vue) { Vue.component(ConfigProvider.name, ConfigProvider) diff --git a/packages/vue/src/config-provider/src/index.vue b/packages/vue/src/config-provider/src/index.vue index b3a795b9b..192869e9b 100644 --- a/packages/vue/src/config-provider/src/index.vue +++ b/packages/vue/src/config-provider/src/index.vue @@ -1,21 +1,102 @@ - - + + diff --git a/packages/vue/src/config-provider/src/props.ts b/packages/vue/src/config-provider/src/props.ts new file mode 100644 index 000000000..121dc7ddc --- /dev/null +++ b/packages/vue/src/config-provider/src/props.ts @@ -0,0 +1,23 @@ +export interface breakPoint { + 'xs': number + 'sm': number + 'md': number + 'lg': number + 'xl': number + '2xl': number +} +export type TextDirection = 'rtl' | 'lrt' +export interface Tag { + enable: boolean + name: string +} + +export interface ConfigProviderProps { + breakPoints: breakPoint + direction: 'rtl' | 'ltr' + globalPrefix?: string + tag: { + enable?: boolean + name?: string + } +}