feat: add advance table

This commit is contained in:
JiwenBai 2019-06-26 20:16:11 +08:00
parent 14e1def361
commit 9182289256
15 changed files with 419 additions and 31 deletions

4
.babelrc Normal file
View File

@ -0,0 +1,4 @@
{
"presets": ["@babel/preset-env"],
"plugins": ["transform-vue-jsx"]
}

View File

@ -1,7 +1,7 @@
module.exports = {
'env': {
'test': {
'plugins': ['istanbul']
env: {
test: {
plugins: ['istanbul']
}
}
}

View File

@ -41,13 +41,14 @@ const webpackConfig = {
}
}
},
{
test: /\.(js|jsx)$/,
exclude: [/node_modules/],
loader: 'babel-loader'
},
{
test: /\.(scss|css)$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/,

View File

@ -41,13 +41,14 @@ const webpackConfig = {
}
}
},
{
test: /\.(js|jsx)$/,
exclude: [/node_modules/],
loader: 'babel-loader'
},
{
test: /\.(scss|css)$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/,

View File

@ -0,0 +1,77 @@
<template>
<div ref="doc" class="n-doc">
<div class="n-doc-header">
<n-gradient-text :font-size="20">
AdvanceTable
</n-gradient-text>
</div>
<div class="n-doc-body">
<div class="n-doc-section">
<div class="n-doc-section__header">
Basic Usage
</div>
<div class="n-doc-section__view">
<n-advance-table :columns="columns" :data="data" />
</div>
<div class="n-doc-section__source">
<textarea>scaffold</textarea>
</div>
</div>
</div>
</div>
</template>
<script>
import docCodeEditorMixin from './docCodeEditorMixin'
export default {
mixins: [docCodeEditorMixin],
data () {
return {
columns: [
{
title: 'Name',
key: 'name',
sortable: true
},
{
title: 'Age',
key: 'age',
sortable: true,
render: (h, params) => {
return <b>{params.row.age}</b>
}
},
{
title: '',
render: (h, params) => {
return (
<n-button
style="margin:0;"
size="small"
onClick={() => this.handleClick()}
>
delete
</n-button>
)
}
}
],
data: [
{
name: 'xiaobai',
age: 10
},
{
name: 'xiaobai2',
age: 12
}
]
}
},
methods: {
handleClick () {
alert('delete')
}
}
}
</script>

View File

@ -24,7 +24,6 @@ export default {
name: 'Nimbus',
path: '/',
childItems: [
{
name: 'Nimbus Service Layout',
path: '/n-nimbus-service-layout'
@ -95,6 +94,10 @@ export default {
name: 'Table',
path: '/n-table'
},
{
name: 'AdvanceTable',
path: '/n-advance-table'
},
{
name: 'Tooltip',
path: '/n-tooltip'
@ -119,16 +122,16 @@ export default {
<style lang="scss">
.CodeMirror {
border: 2px solid #5C657EFF;
height: auto!important;
border: 2px solid #5c657eff;
height: auto !important;
z-index: 0;
border-radius: 8px;
padding: 8px;
margin-bottom: 18px;
}
.CodeMirror-scroll {
overflow-y: hidden!important;
overflow-x: auto!important;
overflow-y: hidden !important;
overflow-x: auto !important;
}
.n-doc {
width: 780px;
@ -149,7 +152,7 @@ export default {
margin-bottom: 12px;
}
.n-doc-section__view {
background: #5C657EFF;
background: #5c657eff;
padding: 18px;
border-radius: 8px;
justify-content: center;
@ -158,7 +161,6 @@ export default {
flex-wrap: wrap;
}
.n-doc-section__source {
}
}
}

View File

@ -12,6 +12,8 @@ import WithPadding from 'packages/common/WithPadding'
import WithMargin from 'packages/common/WithMargin'
import MasonryGroup from 'packages/common/MasonryGroup'
import Table from 'packages/common/Table'
import AdvanceTable from 'packages/common/AdvanceTable'
import Checkbox from 'packages/common/Checkbox'
import RoundButton from 'packages/common/Button'
import Switch from '../packages/common/Switch'
@ -38,6 +40,7 @@ import checkboxDemo from './components/checkboxDemo'
import buttonDemo from './components/buttonDemo'
import switchDemo from './components/switchDemo'
import tableDemo from './components/tableDemo'
import advanceTableDemo from './components/advanceTableDemo'
import inputDemo from './components/inputDemo'
import selectDemo from './components/selectDemo'
import modalDemo from './components/modalDemo'
@ -64,6 +67,7 @@ WithPadding.install(Vue)
ServiceCard.install(Vue)
MasonryGroup.install(Vue)
Table.install(Vue)
AdvanceTable.install(Vue)
WithMargin.install(Vue)
Checkbox.install(Vue)
RoundButton.install(Vue)
@ -79,7 +83,8 @@ NimbusConfirmCard.install(Vue)
Pagination.install(Vue)
const routes = [
{ path: '/start',
{
path: '/start',
component: demo,
children: [
{ path: '/start', component: startPage },
@ -91,6 +96,7 @@ const routes = [
{ path: '/n-button', component: buttonDemo },
{ path: '/n-switch', component: switchDemo },
{ path: '/n-table', component: tableDemo },
{ path: '/n-advance-table', component: advanceTableDemo },
{ path: '/n-input', component: inputDemo },
{ path: '/n-select', component: selectDemo },
{ path: '/n-modal', component: modalDemo },
@ -112,6 +118,6 @@ const router = new VueRouter({
routes
})
;(new Vue({
new Vue({
router
})).$mount('#app')
}).$mount('#app')

View File

@ -7,6 +7,7 @@ import WithPadding from './packages/common/WithPadding'
import WithMargin from './packages/common/WithMargin'
import MasonryGroup from './packages/common/MasonryGroup'
import Table from './packages/common/Table'
import AdvanceTable from './packages/common/AdvanceTable'
import CheckBox from './packages/common/Checkbox'
import RoundButton from './packages/common/Button'
import Switch from './packages/common/Switch'
@ -38,6 +39,7 @@ function installUiToVue (Vue) {
ServiceCard.install(Vue)
MasonryGroup.install(Vue)
Table.install(Vue)
AdvanceTable.install(Vue)
WithMargin.install(Vue)
CheckBox.install(Vue)
RoundButton.install(Vue)

View File

@ -19,13 +19,17 @@
"registry": "https://registry.npmjs.org/"
},
"devDependencies": {
"@babel/core": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"@vue/babel-preset-app": "^3.8.0",
"@vue/eslint-config-standard": "^4.0.0",
"@vue/test-utils": "^1.0.0-beta.29",
"babel-loader": "^8.0.5",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^8.0.6",
"babel-plugin-istanbul": "^5.1.4",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-vue-jsx": "^3.7.0",
"babel-preset-env": "^1.7.0",
"chai": "^4.2.0",
"codemirror": "^5.47.0",
"copy-webpack-plugin": "^5.0.3",
@ -52,6 +56,7 @@
"karma-spec-reporter": "0.0.32",
"karma-webpack": "^3.0.5",
"mocha": "^6.1.4",
"prettier-eslint": "^9.0.0",
"progress-bar-webpack-plugin": "^1.12.1",
"sinon": "^7.3.2",
"sinon-chai": "^3.3.0",
@ -66,9 +71,11 @@
"webpack-dev-server": "^3.4.1"
},
"dependencies": {
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
"@vue/babel-preset-jsx": "^1.0.0",
"ionicons": "^4.5.8",
"masonry-layout": "^4.2.2",
"sass-loader": "^7.1.0",
"node-sass": "^4.12.0"
"node-sass": "^4.12.0",
"sass-loader": "^7.1.0"
}
}

View File

@ -0,0 +1,27 @@
<template>
<span class="ts-funnel-container">
<n-icon
style="vertical-align: middle;color: #63e2b7;"
type="ios-funnel"
size="12"
></n-icon>
</span>
</template>
<style scoped>
.ts-funnel-container {
display: inline-block;
width: 14px;
cursor: pointer;
position: relative;
height: 16px;
line-height: 16px;
}
.ts-funnel-container i {
opacity: 0.3;
}
.ts-funnel-container:hover i {
opacity: 1;
}
</style>

View File

@ -0,0 +1,7 @@
import Scaffold from './src/main.vue'
Scaffold.install = function (Vue) {
Vue.component(Scaffold.name, Scaffold)
}
export default Scaffold

View File

@ -0,0 +1,21 @@
export default {
name: 'Row',
functional: true,
props: {
render: Function,
row: Object,
index: Number,
keyName: String
},
render: (h, ctx) => {
const params = {
row: ctx.props.row,
index: ctx.props.index
}
const { keyName, render, row } = ctx.props
if (render) {
return <div>{render(h, params)}</div>
} else return <div>{row[keyName]}</div>
}
}

View File

@ -0,0 +1,122 @@
<template>
<span class="ts-sort-container">
<n-icon
type="md-arrow-dropdown"
:style="{
fontSize: fontSize,
opacity: downOpacity,
transform: 'scale(0.8)'
}"
@click.native="changeDownSort()"
/>
<n-icon
type="md-arrow-dropup"
:style="{
fontSize: fontSize,
opacity: upOpacity,
transform: 'scale(0.8)'
}"
@click.native="changeUpSort()"
/>
</span>
</template>
<script>
// refer to https://github.com/TuSimple/infra-ecos-webui/blob/develop/src/components/SortIcon.vue
export default {
name: 'SortIcon',
props: {
fontSize: {
type: String,
default: '12px'
},
value: {
type: Number
}
},
data () {
return {
upOpacity: 0.3,
downOpacity: 0.3
}
},
watch: {
value (val) {
this.setSort(val)
}
},
methods: {
changeDownSort () {
let v = this.value
if (v === -1) {
v = 0
} else {
v = -1
}
this.$emit('input', v)
},
changeUpSort () {
let v = this.value
if (v === 1) {
v = 0
} else {
v = 1
}
this.$emit('input', v)
},
setSort (val) {
let self = this
this.$emit('onSortTypeChange', this.value)
switch (val) {
case 0:
self.upOpacity = 0.3
self.downOpacity = 0.3
break
case 1:
self.upOpacity = 1
self.downOpacity = 0.3
break
case -1:
self.upOpacity = 0.3
self.downOpacity = 1
}
}
},
mounted () {
this.setSort(this.value)
// console.log('value', this.value, this.upOpacity, this.downOpacity)
}
}
</script>
<style scoped>
.ts-sort-container {
display: inline-block;
width: 14px;
height: 12px;
margin-top: -1px;
vertical-align: middle;
cursor: pointer;
position: relative;
}
.ts-sort-container i:first-child {
top: 0;
}
.ts-sort-container i {
display: block;
height: 19px;
position: absolute;
color: #63e2b7 !important;
transition: color 0.2s ease-in-out;
font-size: 19px !important;
font-weight: 400;
vertical-align: middle;
}
.ts-sort-container i:last-child {
bottom: 0;
}
.ts-sort-container i:hover {
opacity: 1 !important;
}
</style>

View File

@ -0,0 +1,108 @@
<template>
<n-table>
<n-thead>
<n-tr>
<n-th v-for="(column, i) in columns" :key="column.key"
>{{ column.title }}
<SortIcon
v-if="column.sortable"
v-model="sortIndexs[i]"
class="table-head-icon"
@onSortTypeChange="
type =>
onSortTypeChange(i, column.sortable, column.key, type, column)
"
/>
<filterIcon></filterIcon>
</n-th>
</n-tr>
</n-thead>
<n-tbody>
<n-tr v-for="(rowData, i) in copyData" :key="i">
<n-td v-for="column in columns" :key="column.key"
><row
:index="i"
:row="rowData"
:keyName="column.key"
:render="column.render"
></row
></n-td>
</n-tr>
</n-tbody>
</n-table>
</template>
<script>
import row from '../row/index.jsx'
import SortIcon from '../sortIcon'
import filterIcon from '../filterIcon'
export default {
name: 'NAdvanceTable',
components: {
row,
SortIcon,
filterIcon
},
props: {
hoverColor: {
default: '#323850',
type: String
},
columns: {
type: Array,
required: true
},
data: {
type: Array,
default: () => []
}
},
watch: {
data () {
this.copyData = this.data.slice(0)
}
},
data () {
const sortIndexs = new Array(this.columns.length).fill(0)
return { copyData: this.data.slice(0), sortIndexs }
},
methods: {
onSortTypeChange (i, sortable, key, type, column) {
if (sortable === 'custom') {
this.$emit('on-sort-change', {
key,
type,
column
})
} else if (sortable === true) {
this.copyData = this.copyData.sort((a, b) => {
return type >= 0
? ('' + a[key]).localeCompare('' + b[key])
: ('' + b[key]).localeCompare('' + a[key])
})
}
if (type !== 0) {
this.sortIndexs = this.sortIndexs.map((item, idx) => {
if (idx !== i) {
return 0
} else {
return this.sortIndexs[idx]
}
})
}
}
}
}
</script>
<style scoped>
.ts-sort-container {
display: inline-block;
width: 14px;
height: 12px;
margin-top: -1px;
cursor: pointer;
position: relative;
}
</style>

View File

@ -1,5 +1,5 @@
@import './mixins/mixins.scss';
@import './theme/default.scss';
@import "./mixins/mixins.scss";
@import "./theme/default.scss";
@include b(table) {
width: 100%;
@ -47,6 +47,9 @@
padding-left: 32px;
}
}
tr:hover {
background-color: #2b3147;
}
}
}
}
}