Skip to content

Commit de76990

Browse files
committed
feat: add CNav and CNavItem
1 parent 3686ef8 commit de76990

File tree

4 files changed

+164
-85
lines changed

4 files changed

+164
-85
lines changed

src/components/Nav/CNav.js

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
2+
export const props = {
3+
fill: Boolean,
4+
justified: Boolean,
5+
tabs: Boolean,
6+
pills: Boolean,
7+
vertical: Boolean,
8+
activeItem: [Number, String],
9+
tabContent: Boolean
10+
}
11+
12+
export default {
13+
name: 'CNav',
14+
props,
15+
model: {
16+
event: 'activeChanged',
17+
prop: 'activeItem'
18+
},
19+
data () {
20+
return {
21+
activeItemIndex: this.activeItem,
22+
children: []
23+
}
24+
},
25+
watch: {
26+
activeItem (val) {
27+
this.activeItemIndex = val
28+
},
29+
activeItemIndex (val) {
30+
this.getState()
31+
}
32+
},
33+
mounted () {
34+
this.children = this.$slots.default
35+
if(this.children)
36+
this.getState()
37+
},
38+
updated () {
39+
this.children = this.$slots.default
40+
},
41+
methods: {
42+
getState () {
43+
this.activateItem(this.getItem(this.activeItemIndex))
44+
},
45+
getItem (index) {
46+
let item = this.children[index]
47+
this.children.forEach((el, i) => {
48+
if(index === undefined && el.componentInstance.isActive == true)
49+
item = el
50+
else if(index !== undefined && el.componentInstance.id == index)
51+
item = el
52+
})
53+
return item
54+
},
55+
activateItem (item) {
56+
if(!item || !item.componentInstance)
57+
return
58+
this.children.forEach((el, i) => {
59+
el.componentInstance.isActive = false
60+
})
61+
item.componentInstance.isActive = true
62+
this.$emit('activated', this.activeItemIndex)
63+
64+
},
65+
onClick (e) {
66+
this.$slots.default.forEach((el, i) => {
67+
if(el.elm.contains(e.target))
68+
this.activeItemIndex = el.componentInstance.id || i
69+
})
70+
}
71+
},
72+
render (h) {
73+
const nav = h(
74+
'ul',
75+
{
76+
class: {
77+
'nav' : true,
78+
'nav-tabs': this.tabs,
79+
'nav-pills': this.pills,
80+
'flex-column': this.vertical,
81+
'nav-fill': this.fill,
82+
'nav-justified': this.justified
83+
},
84+
on: {
85+
click: this.onClick
86+
}
87+
},
88+
this.$slots.default
89+
)
90+
if (!this.tabContent)
91+
return nav
92+
93+
94+
95+
const tabs = this.children.map((tab, index) => {
96+
if(tab.componentInstance && tab.componentInstance.$slots.tab){
97+
return h(
98+
'div',
99+
{
100+
staticClass: 'tab-pane',
101+
class: {
102+
show: tab.componentInstance.isActive,
103+
active: tab.componentInstance.isActive
104+
}
105+
},
106+
tab.componentInstance.$slots.tab
107+
)
108+
}
109+
})
110+
111+
112+
const tab = h(
113+
'div',
114+
{
115+
staticClass: 'tab-content'
116+
},
117+
tabs
118+
)
119+
120+
const wrapper = h(
121+
'div',
122+
[nav, tab]
123+
)
124+
return wrapper
125+
}
126+
}

src/components/Nav/CNavItem.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import CLink, { propsFactory as linkPropsFactory } from '../Link/CLink'
2+
3+
export default {
4+
name: 'CNavItem',
5+
props: linkPropsFactory(),
6+
data () {
7+
return {
8+
isActive: this.active,
9+
id: this.$attrs.id
10+
}
11+
},
12+
computed: {
13+
computedProps () {
14+
return !this.disabled ? Object.assign({}, this.$props, { active: this.isActive } ) : this.$props
15+
},
16+
},
17+
render (h) {
18+
// console.log(this)
19+
return h(
20+
'li',
21+
{ staticClass: 'nav-item' },
22+
[
23+
h(
24+
CLink,
25+
{
26+
staticClass: 'nav-link',
27+
props: this.computedProps
28+
},
29+
this.$slots.default
30+
)
31+
]
32+
)
33+
}
34+
}

src/components/Nav/CNavItemDropdown.vue

Lines changed: 0 additions & 83 deletions
This file was deleted.

src/components/Nav/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import CNavItemDropdown from './CNavItemDropdown'
1+
import CNav from './CNav'
2+
import CNavItem from './CNavItem'
23

34
export {
4-
CNavItemDropdown
5+
CNav,
6+
CNavItem
57
}

0 commit comments

Comments
 (0)