Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(configprovider): move common logic to common file #2540

Merged
merged 4 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`ConfigProvider: props themeVars 1`] = `
"<div class=\\"nut-theme-\\" style=\\"--nut-address-region-tab-line: linear-gradient(90deg, #fff 0%, rgba(255,255,255,0.15) 100%) ; --nut-tabs-horizontal-tab-line-color: linear-gradient(90deg, #fff 0%, rgba(255,255,255,0.15)100%); --nut-tabs-vertical-tab-line-color: linear-gradient(180deg, #fff 0%, rgba(255,255,255,0.15) 100%) ; --nut-primary-color: #fff; --nut-title-color: blue; --nut-help-color: #f5f5f5;\\"><svg class=\\"nut-icon nut-icon-close\\" xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 1026 1024\\" role=\\"presentation\\">
"<div class=\\"nut-theme-\\" style=\\"--nut-address-region-tab-line: linear-gradient(90deg, #fff 0%, rgba(255,255,255, 0.15) 100%); --nut-tabs-horizontal-tab-line-color: linear-gradient(90deg, #fff 0%, rgba(255,255,255, 0.15) 100%); --nut-tabs-vertical-tab-line-color: linear-gradient(180deg, #fff 0%, rgba(255,255,255, 0.15) 100%); --nut-primary-color: #fff; --nut-title-color: blue; --nut-help-color: #f5f5f5;\\"><svg class=\\"nut-icon nut-icon-close\\" xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 1026 1024\\" role=\\"presentation\\">
<path d=\\"M981.577 1024c-11.703 0-23.406-2.926-32.183-11.703L13.166 76.07c-14.629-17.555-14.629-46.812 0-64.366 17.554-14.629 46.811-14.629 64.365 0L1013.76 947.93c17.554 17.555 17.554 43.886 0 61.44-8.777 11.703-20.48 14.629-32.183 14.629zm-936.228 0c-11.703 0-23.406-2.926-32.183-11.703-17.555-17.554-17.555-43.886 0-61.44L949.394 14.63c17.555-17.555 43.886-17.555 61.44 0 17.555 17.554 17.555 43.885 0 61.44L74.606 1012.297C68.754 1021.074 57.05 1024 45.349 1024z\\" fill=\\"currentColor\\" fill-opacity=\\"0.9\\"></path>
</svg></div>"
`;

exports[`ConfigProvider: props themeVars 2`] = `
"<div class=\\"nut-theme-\\" style=\\"--nut-address-region-tab-line: linear-gradient(90deg, #ff 0%, rgba(, 0.15) 100%); --nut-tabs-horizontal-tab-line-color: linear-gradient(90deg, #ff 0%, rgba(, 0.15) 100%); --nut-tabs-vertical-tab-line-color: linear-gradient(180deg, #ff 0%, rgba(, 0.15) 100%); --nut-primary-color: #ff;\\"><svg class=\\"nut-icon nut-icon-close\\" xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 1026 1024\\" role=\\"presentation\\">
<path d=\\"M981.577 1024c-11.703 0-23.406-2.926-32.183-11.703L13.166 76.07c-14.629-17.555-14.629-46.812 0-64.366 17.554-14.629 46.811-14.629 64.365 0L1013.76 947.93c17.554 17.555 17.554 43.886 0 61.44-8.777 11.703-20.48 14.629-32.183 14.629zm-936.228 0c-11.703 0-23.406-2.926-32.183-11.703-17.555-17.554-17.555-43.886 0-61.44L949.394 14.63c17.555-17.555 43.886-17.555 61.44 0 17.555 17.554 17.555 43.885 0 61.44L74.606 1012.297C68.754 1021.074 57.05 1024 45.349 1024z\\" fill=\\"currentColor\\" fill-opacity=\\"0.9\\"></path>
</svg></div>"
`;
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,11 @@ test('ConfigProvider: props themeVars', async () => {
}
});
expect(wrapper.html()).toMatchSnapshot();

await wrapper.setProps({
themeVars: {
primaryColor: '#ff'
}
});
expect(wrapper.html()).toMatchSnapshot();
});
80 changes: 80 additions & 0 deletions src/packages/__VUE/configprovider/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { h, computed } from 'vue';

export const component = (tag: string) => {
return {
props: {
theme: { type: String, default: '' },
themeVars: { type: Object, default: {} },
tag: { type: String, default: tag }
},

setup(props: any, { slots }: any) {
const hexToRgb = (color: string) => {
//十六进制颜色值的正则表达式
const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
if (!reg.test(color)) return '';
color = color.toLowerCase();
// 如果是16进制颜色
if (color.length === 4) {
color =
'#' +
color
.slice(1)
.split('')
.map((char) => char + char)
.join('');
}
//处理六位的颜色值
const colors = [];
for (let i = 1; i < 7; i += 2) {
colors.push(parseInt('0x' + color.slice(i, i + 2)));
}
return colors.join(',');
};

const kebabCase = (str: string): string => {
str = str.replace(str.charAt(0), str.charAt(0).toLocaleLowerCase());
return str.replace(/([a-z])([A-Z])/g, (_, p1, p2) => p1 + '-' + p2.toLowerCase());
};

const mapThemeVarsToCSSVars = (themeVars: Record<string, string>) => {
if (!themeVars) return;
const cssVars: Record<string, string> = {};
const primaryColor = themeVars?.primaryColor;
// 为了处理一些组件的rgba透明颜色
if (primaryColor) {
const primaryColorRgb = hexToRgb(primaryColor);
cssVars[
'--nut-address-region-tab-line'
] = `linear-gradient(90deg, ${primaryColor} 0%, rgba(${primaryColorRgb}, 0.15) 100%)`;
cssVars[
'--nut-tabs-horizontal-tab-line-color'
] = `linear-gradient(90deg, ${primaryColor} 0%, rgba(${primaryColorRgb}, 0.15) 100%)`;
cssVars[
'--nut-tabs-vertical-tab-line-color'
] = `linear-gradient(180deg, ${primaryColor} 0%, rgba(${primaryColorRgb}, 0.15) 100%)`;
}

Object.keys(themeVars).forEach((key) => {
cssVars[`--nut-${kebabCase(key)}`] = themeVars[key];
});

return cssVars;
};

const themeStyle = computed(() => mapThemeVarsToCSSVars(props.themeVars));
const defaultSlots = slots.default?.();

return () => {
return h(
props.tag,
{
class: `nut-theme-${props.theme}`,
style: themeStyle.value
},
defaultSlots
);
};
}
};
};
162 changes: 71 additions & 91 deletions src/packages/__VUE/configprovider/demo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,12 @@
</nut-config-provider>
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { reactive, ref } from 'vue';
import { createComponent } from '@/packages/utils/create';
const { translate } = createComponent('configprovider');
import { useTranslate } from '@/sites/assets/util/useTranslate';
import { reactive, ref, defineComponent } from 'vue';

const initTranslate = () =>
useTranslate({
'zh-CN': {
Expand Down Expand Up @@ -127,97 +128,76 @@ const initTranslate = () =>
asyncValidator: 'Simulating asynchronous verification'
}
});
export default defineComponent({
props: {},
setup() {
initTranslate();
const switchChecked = ref(false);
const theme = ref('');
const switchChange = (v: boolean) => {
theme.value = v ? 'dark' : '';
};
const formData2 = reactive({
switch: false,
checkbox: false,
radio: 0,
number: 0,
rate: 3,
range: 30,
address: '',
defaultFileList: [
{
name: 'file 1.png',
url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
status: 'success',
message: translate('success'),
type: 'image'
},
{
name: 'file 2.png',
url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
status: 'uploading',
message: translate('uploading'),
type: 'image'
}
]
});

const addressModule = reactive({
state: {
show: false,
province: [
{ id: 1, name: '北京' },
{ id: 2, name: '广西' },
{ id: 3, name: '江西' },
{ id: 4, name: '四川' }
],
city: [
{ id: 7, name: '朝阳区' },
{ id: 8, name: '崇文区' },
{ id: 9, name: '昌平区' },
{ id: 6, name: '石景山区' }
],
country: [
{ id: 3, name: '八里庄街道' },
{ id: 9, name: '北苑' },
{ id: 4, name: '常营乡' }
],
town: []
} as any,
methods: {
show() {
addressModule.state.show = !addressModule.state.show;
if (addressModule.state.show) {
formData2.address = '';
}
},
onClose({ data }: any) {
formData2.address = data.addressStr;
addressModule.state.show = false;
}
initTranslate();
const switchChecked = ref(false);
const theme = ref('');
const switchChange = (v: boolean) => {
theme.value = v ? 'dark' : '';
};
const formData2 = reactive({
switch: false,
checkbox: false,
radio: 0,
number: 0,
rate: 3,
range: 30,
address: '',
defaultFileList: [
{
name: 'file 1.png',
url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
status: 'success',
message: translate('success'),
type: 'image'
},
{
name: 'file 2.png',
url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
status: 'uploading',
message: translate('uploading'),
type: 'image'
}
]
});

const addressModule = reactive({
state: {
show: false,
province: [
{ id: 1, name: '北京' },
{ id: 2, name: '广西' },
{ id: 3, name: '江西' },
{ id: 4, name: '四川' }
],
city: [
{ id: 7, name: '朝阳区' },
{ id: 8, name: '崇文区' },
{ id: 9, name: '昌平区' },
{ id: 6, name: '石景山区' }
],
country: [
{ id: 3, name: '八里庄街道' },
{ id: 9, name: '北苑' },
{ id: 4, name: '常营乡' }
],
town: []
} as any,
methods: {
show() {
addressModule.state.show = !addressModule.state.show;
if (addressModule.state.show) {
formData2.address = '';
}
});
let color = reactive({
primaryColor: '#008000',
primaryColorEnd: '#008000'
// rangeBgColor: 'rgba(25,137,250,0.15)',
// rangeBarBgColor: '#0289fa',
// rangeBarBtnBorder: '1px solid #0289fa'
});
const themeVars = color;
return {
formData2,
addressModule,
switchChecked,
switchChange,
theme,
themeVars,
translate
};
},
onClose({ data }: any) {
formData2.address = data.addressStr;
addressModule.state.show = false;
}
}
});
const themeVars = reactive({
primaryColor: '#008000',
primaryColorEnd: '#008000'
});
</script>
<style lang="scss" scoped>
.demo {
}
</style>
72 changes: 3 additions & 69 deletions src/packages/__VUE/configprovider/index.taro.vue
Original file line number Diff line number Diff line change
@@ -1,74 +1,8 @@
<script lang="ts">
import { createComponent } from '@/packages/utils/create';
import { h } from 'vue';
import { component } from './common';

const { create } = createComponent('config-provider');
export default create({
props: {
theme: { type: String, default: '' },
themeVars: { type: Object, default: {} },
tag: { type: String, default: 'view' }
},
setup(props: any, { slots }: any) {
const kebabCase = (str: string): string => {
str = str.replace(str.charAt(0), str.charAt(0).toLocaleLowerCase());
return str.replace(/([a-z])([A-Z])/g, (_, p1, p2) => p1 + '-' + p2.toLowerCase());
};
const colorRgb = (str: string) => {
if (!str) return;
var sColor = str.toLowerCase();
//十六进制颜色值的正则表达式
var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
// 如果是16进制颜色
if (sColor && reg.test(sColor)) {
if (sColor.length === 4) {
var sColorNew = '#';
for (let i = 1; i < 4; i += 1) {
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
}
sColor = sColorNew;
}
//处理六位的颜色值
var sColorChange = [];
for (let i = 1; i < 7; i += 2) {
sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)));
}
return sColorChange.join(',');
}
return null;
};
const mapThemeVarsToCSSVars = (themeVars: Record<string, string>) => {
if (!themeVars) return;
const cssVars: Record<string, string> = {};
const primaryColor = props?.themeVars?.primaryColor;
// 为了处理一些组件的rgba透明颜色
if (primaryColor) {
cssVars[`--nut-address-region-tab-line`] = `linear-gradient(90deg, ${primaryColor} 0%, rgba(${colorRgb(
primaryColor
)},0.15) 100%) `;
cssVars[`--nut-tabs-horizontal-tab-line-color`] = `linear-gradient(90deg, ${primaryColor} 0%, rgba(${colorRgb(
primaryColor
)},0.15)100%)`;
cssVars[`--nut-tabs-vertical-tab-line-color`] = `linear-gradient(180deg, ${primaryColor} 0%, rgba(${colorRgb(
primaryColor
)},0.15) 100%) `;
}
Object.keys(themeVars).forEach((key) => {
cssVars[`--nut-${kebabCase(key)}`] = themeVars[key];
});
return cssVars;
};

return () => {
const defaultSlots = slots.default?.();
return h(
props.tag,
{
class: `nut-theme-${props.theme}`,
style: mapThemeVarsToCSSVars(props.themeVars)
},
defaultSlots
);
};
}
});
export default create(component('view'));
</script>
Loading