Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d19fab4

Browse filesBrowse files
committed
feat: Add CDropdown and child components.
1 parent f9ff39a commit d19fab4
Copy full SHA for d19fab4

File tree

6 files changed

+204
-0
lines changed
Filter options

6 files changed

+204
-0
lines changed

‎src/components/Dropdown/CDropdown.vue

Copy file name to clipboard
+124Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<template>
2+
<li :class="computedDropdownClasses">
3+
<a href="#"
4+
aria-haspopup="true"
5+
:aria-expanded="visible"
6+
:class="computedToggleClasses"
7+
@click="click($event)"
8+
ref="toggle"
9+
>
10+
<slot name="button">
11+
<button class="btn btn-outline-primary dropdown-toggle">{{text}}</button>
12+
</slot>
13+
</a>
14+
<div :class="computedMenuClasses" ref="menu" v-on-clickaway="hide">
15+
<slot></slot>
16+
</div>
17+
</li>
18+
</template>
19+
<script>
20+
import Popper from 'popper.js'
21+
import { mixin as clickaway } from 'vue-clickaway'
22+
23+
export default {
24+
name: 'CDropdown',
25+
mixins: [ clickaway ],
26+
data () {
27+
return {
28+
visible: this.show
29+
}
30+
},
31+
props: {
32+
text: {
33+
type: String,
34+
default: 'Dropdown'
35+
},
36+
show: Boolean,
37+
dropup: Boolean,
38+
disabled: Boolean,
39+
right: Boolean,
40+
menuClasses: String,
41+
toggleClasses: String,
42+
popperConfig: Object
43+
// popperConfig: {
44+
// type: Object,
45+
// default () {
46+
// return {
47+
// modifiers: {
48+
// placement: 'bottom-end',
49+
// offset: {
50+
// offset: '20px'
51+
// },
52+
// computeStyle: {
53+
// enabled: true
54+
// },
55+
// flip: {
56+
// enabled: true
57+
// }
58+
// }
59+
// }
60+
// }
61+
// }
62+
},
63+
mounted () {
64+
this.checkForPopper()
65+
},
66+
methods:{
67+
hide () {
68+
if(this.$refs.menu.classList.contains('show'))
69+
this.toggle(false)
70+
},
71+
click (e) {
72+
e.preventDefault()
73+
this.toggle(!this.visible)
74+
},
75+
toggle (visible) {
76+
if(this.disabled)
77+
return
78+
this.visible = visible
79+
this.checkForPopper()
80+
},
81+
checkForPopper () {
82+
if(this.popperConfig)
83+
setTimeout(() => this.visible ? this.createPopper() : this.removePopper(), 0)
84+
},
85+
removePopper () {
86+
if (this._popper) {
87+
this._popper.destroy()
88+
}
89+
this._popper = null
90+
},
91+
createPopper () {
92+
this.removePopper()
93+
this._popper = new Popper(this.$refs.toggle, this.$refs.menu, this.popperConfig)
94+
}
95+
},
96+
computed: {
97+
computedDropdownClasses () {
98+
return [
99+
'dropdown',
100+
{
101+
'dropup': this.dropup,
102+
'show': this.visible
103+
}
104+
]
105+
},
106+
computedToggleClasses () {
107+
return [
108+
this.toggleClasses,
109+
{
110+
'disabled' : this.disabled
111+
}
112+
]
113+
},
114+
computedMenuClasses () {
115+
return [
116+
this.menuClasses,
117+
'dropdown-menu',
118+
this.right ? 'dropdown-menu-right' : 'dropdown-menu-left',
119+
{ 'show': this.visible }
120+
]
121+
}
122+
},
123+
}
124+
</script>
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { mergeData } from 'vue-functional-data-merge'
2+
3+
export const props = {
4+
tag: {
5+
type: String,
6+
default: 'div'
7+
}
8+
}
9+
10+
export default {
11+
functional: true,
12+
name: 'CDropdownDivider',
13+
props,
14+
render (h, { props, data }) {
15+
return h(
16+
props.tag,
17+
mergeData(data, {
18+
staticClass: 'dropdown-divider',
19+
attrs: { role: 'separator' }
20+
})
21+
)
22+
}
23+
}
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { mergeData } from 'vue-functional-data-merge'
2+
3+
export const props = {
4+
tag: {
5+
type: String,
6+
default: 'h6'
7+
}
8+
}
9+
10+
export default {
11+
functional: true,
12+
name: 'CDropdownHeader',
13+
props,
14+
render (h, { props, data, children }) {
15+
return h(
16+
props.tag,
17+
mergeData(data, {
18+
staticClass: 'dropdown-header',
19+
}),
20+
children
21+
)
22+
}
23+
}
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { mergeData } from 'vue-functional-data-merge'
2+
import CLink, { propsFactory as linkPropsFactory } from '../Link/CLink'
3+
4+
export const props = linkPropsFactory()
5+
6+
export default {
7+
functional: true,
8+
name: 'CDropdownItem',
9+
props,
10+
render (h, { props, data, children }) {
11+
return h(
12+
CLink,
13+
mergeData(data, {
14+
props,
15+
staticClass: 'dropdown-item',
16+
attrs: { role: 'menuitem' }
17+
}),
18+
children
19+
)
20+
}
21+
}

‎src/components/Dropdown/index.js

Copy file name to clipboard
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import CDropdown from './CDropdown'
2+
import CDropdownHeader from './CDropdownHeader'
3+
import CDropdownDivider from './CDropdownDivider'
4+
import CDropdownItem from './CDropdownItem'
5+
6+
7+
export {
8+
CDropdown,
9+
CDropdownHeader,
10+
CDropdownDivider,
11+
CDropdownItem
12+
}

‎src/components/index.js

Copy file name to clipboardExpand all lines: src/components/index.js
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ export * from './Progress'
1414
export * from './Alert'
1515
export * from './Button'
1616
export * from './Card'
17+
export * from './Dropdown'

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.