mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2024-11-21 01:13:16 +08:00
feat: add advance table
This commit is contained in:
parent
14e1def361
commit
9182289256
4
.babelrc
Normal file
4
.babelrc
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"presets": ["@babel/preset-env"],
|
||||
"plugins": ["transform-vue-jsx"]
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
module.exports = {
|
||||
'env': {
|
||||
'test': {
|
||||
'plugins': ['istanbul']
|
||||
env: {
|
||||
test: {
|
||||
plugins: ['istanbul']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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*)?$/,
|
||||
|
@ -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*)?$/,
|
||||
|
77
demo/components/advanceTableDemo.vue
Normal file
77
demo/components/advanceTableDemo.vue
Normal 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>
|
@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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')
|
||||
|
2
index.js
2
index.js
@ -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)
|
||||
|
17
package.json
17
package.json
@ -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"
|
||||
}
|
||||
}
|
||||
|
27
packages/common/AdvanceTable/filterIcon/index.vue
Normal file
27
packages/common/AdvanceTable/filterIcon/index.vue
Normal 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>
|
||||
|
7
packages/common/AdvanceTable/index.js
Normal file
7
packages/common/AdvanceTable/index.js
Normal file
@ -0,0 +1,7 @@
|
||||
import Scaffold from './src/main.vue'
|
||||
|
||||
Scaffold.install = function (Vue) {
|
||||
Vue.component(Scaffold.name, Scaffold)
|
||||
}
|
||||
|
||||
export default Scaffold
|
21
packages/common/AdvanceTable/row/index.jsx
Normal file
21
packages/common/AdvanceTable/row/index.jsx
Normal 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>
|
||||
}
|
||||
}
|
122
packages/common/AdvanceTable/sortIcon/index.vue
Normal file
122
packages/common/AdvanceTable/sortIcon/index.vue
Normal 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>
|
108
packages/common/AdvanceTable/src/main.vue
Normal file
108
packages/common/AdvanceTable/src/main.vue
Normal 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>
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user