Skip to content

Commit

Permalink
feat(configprovider): add theme & dark style
Browse files Browse the repository at this point in the history
  • Loading branch information
richard1015 committed Jun 20, 2022
1 parent 41659ec commit d1feca9
Show file tree
Hide file tree
Showing 35 changed files with 833 additions and 6 deletions.
14 changes: 13 additions & 1 deletion src/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,17 @@
"show": true,
"desc": "弹出层容器,用于展示弹窗、信息提示等内容,支持多个弹出层叠加展示",
"author": "szg2008"
},
{
"version": "3.0.0",
"name": "ConfigProvider",
"cType": "基础组件",
"cName": "全局配置",
"desc": "用于配置NutUI组件全局",
"show": true,
"tarodoc": false,
"type": "component",
"author": "richard1015"
}
]
},
Expand Down Expand Up @@ -1171,7 +1182,8 @@
"exportEmpty": true,
"author": "liqiong43",
"taro": true
},{
},
{
"name": "Comment",
"cType": "特色组件",
"cName": "商品评论",
Expand Down
8 changes: 7 additions & 1 deletion src/packages/__VUE/cell/index.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
.nut-theme-dark {
.nut-cell {
background: $dark-background;
color: $dark-color;
}
}
.nut-cell {
position: relative;
display: flex;
width: 100%;
line-height: $cell-line-height;
padding: $cell-padding;
background: $white;
background: $cell-background;
border-radius: $cell-border-radius;
box-shadow: 0px 1px 7px 0px rgba(237, 238, 241, 1);
font-size: $cell-title-font;
Expand Down
10 changes: 10 additions & 0 deletions src/packages/__VUE/checkbox/index.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
.nut-theme-dark {
.nut-checkbox {
&__label {
color: $dark-color;
&--disabled {
color: $checkbox-label-disable-color;
}
}
}
}
.nut-checkbox {
display: flex;
align-items: center;
Expand Down
13 changes: 13 additions & 0 deletions src/packages/__VUE/configprovider/__tests__/configprovider.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { mount } from '@vue/test-utils';
import ConfigProvider from '../index.vue';

test('prop theme & tag', async () => {
const wrapper = mount(ConfigProvider, {
props: {
theme: 'dark',
tag: 'div'
}
});
const html = expect(wrapper.html());
expect(wrapper.find<HTMLElement>('.nut-theme-dark'));
});
18 changes: 18 additions & 0 deletions src/packages/__VUE/configprovider/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { h, PropType } from 'vue';
export const component = {
props: {
theme: { type: String, default: '' },
tag: { type: String as PropType<keyof HTMLElementTagNameMap>, default: 'div' }
},
setup(props: any, { slots }: any) {
return () => {
return h(
props.tag,
{
class: `nut-theme-${props.theme}`
},
slots.default?.()
);
};
}
};
206 changes: 206 additions & 0 deletions src/packages/__VUE/configprovider/demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
<template>
<div class="demo">
<h2>{{ translate('basic') }}</h2>
<nut-config-provider :theme="theme">
<nut-cell :title="translate('title1')">
<template v-slot:link>
<nut-switch v-model="switchChecked" @change="switchChange" />
</template>
</nut-cell>
<nut-cell :title="translate('title2')" :sub-title="translate('title3')" :desc="translate('desc')"></nut-cell>

<nut-form>
<nut-form-item :label="translate('switch')">
<nut-switch v-model="formData2.switch"></nut-switch>
</nut-form-item>
<nut-form-item :label="translate('checkbox')">
<nut-checkbox v-model="formData2.checkbox">{{ translate('checkbox') }}</nut-checkbox>
</nut-form-item>
<nut-form-item :label="translate('radiogroup')">
<nut-radiogroup direction="horizontal" v-model="formData2.radio">
<nut-radio label="1">{{ translate('option', 1) }}</nut-radio>
<nut-radio disabled label="2">{{ translate('option', 2) }}</nut-radio>
<nut-radio label="3">{{ translate('option', 3) }}</nut-radio>
</nut-radiogroup>
</nut-form-item>
<nut-form-item :label="translate('rate')">
<nut-rate v-model="formData2.rate" />
</nut-form-item>
<nut-form-item :label="translate('inputnumber')">
<nut-inputnumber v-model="formData2.number" />
</nut-form-item>
<nut-form-item :label="translate('range')">
<nut-range hidden-tag v-model="formData2.range"></nut-range>
</nut-form-item>
<nut-form-item :label="translate('uploader')">
<nut-uploader url="http://apiurl" v-model:file-list="formData2.defaultFileList" maximum="3" multiple>
</nut-uploader>
</nut-form-item>
<nut-form-item :label="translate('address')">
<input
class="nut-input-text"
v-model="formData2.address"
@click="addressModule.methods.show"
readonly
:placeholder="translate('addressTip1')"
type="text"
/>
<!-- nut-address -->
<nut-address
v-model:visible="addressModule.state.show"
:province="addressModule.state.province"
:city="addressModule.state.city"
:country="addressModule.state.country"
:town="addressModule.state.town"
@change="addressModule.methods.onChange"
:custom-address-title="translate('addressTip2')"
></nut-address>
</nut-form-item>
</nut-form>
</nut-config-provider>
</div>
</template>
<script lang="ts">
import { createComponent } from '@/packages/utils/create';
const { createDemo, translate } = createComponent('configprovider');
import { useTranslate } from '@/sites/assets/util/useTranslate';
import { reactive, ref } from 'vue';
useTranslate({
'zh-CN': {
basic: '基本用法',
title1: '切换暗黑',
title2: '我是标题',
title3: '副标题描述',
desc: '描述文字',
address: '地址',
addressTip: '请输入地址',
addressTip1: '请选择地址',
addressTip2: '请选择所在地区',
remarks: '备注',
remarksTip: '请输入备注',
switch: '开关',
checkbox: '复选框',
radiogroup: '单选按钮',
option: (v: string) => '选项' + v,
rate: '评分',
inputnumber: '步进器',
range: '滑块',
uploader: '文件上传',
success: '上传成功',
uploading: '上传中...',
asyncValidator: '模拟异步验证中'
},
'en-US': {
basic: 'Basic Usage',
title1: 'Switch Dark Mode',
title2: 'Title',
title3: 'Subtitle Description',
desc: 'Description',
nameTip: 'Please enter your name',
address: 'Address',
addressTip: 'Please enter address',
addressTip1: 'Please select an address',
addressTip2: 'Please select your region',
remarks: 'Remarks',
remarksTip: 'Please enter remarks',
switch: 'Switch',
checkbox: 'Checkbox',
radiogroup: 'Radiogroup',
option: (v: string) => 'Option' + v,
rate: 'Rate',
inputnumber: 'Inputnumber',
range: 'Range',
uploader: 'Upload file',
success: 'Upload successful',
uploading: 'Uploading',
asyncValidator: 'Simulating asynchronous verification'
}
});
export default createDemo({
props: {},
setup() {
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: []
},
methods: {
show() {
addressModule.state.show = !addressModule.state.show;
if (addressModule.state.show) {
formData2.address = '';
}
},
onChange({ custom, next, value }: any) {
formData2.address += value.name;
const name = addressModule.state[next];
if (name.length < 1) {
addressModule.state.show = false;
}
}
}
});
return {
formData2,
addressModule,
switchChecked,
switchChange,
theme,
translate
};
}
});
</script>
<style lang="scss" scoped>
.demo {
}
</style>
89 changes: 89 additions & 0 deletions src/packages/__VUE/configprovider/doc.en-US.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# ConfigProvider

### Intro

It is used to globally configure nutui components and provides dark mode.

### Install

```javascript

import { createApp } from 'vue';
// vue
import { ConfigProvider } from '@nutui/nutui';
// taro
import { ConfigProvider } from '@nutui/nutui-taro';

const app = createApp();
app.use(ConfigProvider);

```

### dark mode

Dark mode can be enabled by setting the `theme` property of the ConfigProvider component to `dark`.

Dark mode takes effect globally, making all NutUI components on the page dark.

:::demo

```html
<template>
<nut-config-provider :theme="theme">
<nut-cell title="Switch Dark Mode">
<template v-slot:link>
<nut-switch v-model="switchChecked" @change="switchChange" />
</template>
</nut-cell>
<nut-cell title="Title" sub-title="Subtitle Description" desc="Description"></nut-cell>
</nut-config-provider>
</template>
<script lang="ts">
import { ref } from 'vue';
export default {
setup() {
const switchChecked = ref(false);
const theme = ref('');
const switchChange = (v: boolean) => {
theme.value = v ? 'dark' : '';
};
return { translate, switchChecked, switchChange, theme };
}
};
</script>
```

:::

## API

### Props

| Attribute | Description | Type | Default |
|-----------|----------------------------------------------------------------------|--------|---------|
| theme | Theme style, set to `dark` to enable dark mode, take effect globally | String | - |
| tag | HTML Tag of root element | String | div |


## Dark mode adaptation progress

At present, only the following components support dark mode, other components are still being improved, please pay attention to the follow-up release:

- Button
- Cell
- Icon
- OverLay
- Popup
- Layout
- Sticky
- Divider
- Grid
- Navbar
- FixedNav
- Menu
- Tabbar
- Elevator
- Pagination
- Tabs
- Form...
Loading

0 comments on commit d1feca9

Please sign in to comment.