@coreui/vue
Version:
UI Components Library for Vue.js
168 lines (165 loc) • 5.79 kB
JavaScript
import { defineComponent, ref, inject, computed, onMounted, cloneVNode, h } from 'vue';
import { CButton } from '../button/CButton.js';
import { Color, Shape } from '../../props.js';
const CDropdownToggle = defineComponent({
name: 'CDropdownToggle',
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
*/
as: {
type: String,
default: 'button',
},
/**
* Sets the color context of the component to one of CoreUI’s themed colors.
*
* @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
/**
* Enables pseudo element caret on toggler.
*/
caret: {
type: Boolean,
default: true,
},
/**
* Create a custom toggler which accepts any content.
*/
custom: Boolean,
/**
* Toggle the disabled state for the component.
*/
disabled: Boolean,
/**
* If a dropdown `variant` is set to `nav-item` then render the toggler as a link instead of a button.
*
* @since 5.0.0
*/
navLink: {
type: Boolean,
default: true,
},
/**
* @values 'rounded', 'rounded-top', 'rounded-end', 'rounded-bottom', 'rounded-start', 'rounded-circle', 'rounded-pill', 'rounded-0', 'rounded-1', 'rounded-2', 'rounded-3'
*/
shape: Shape,
/**
* Size the component small or large.
*
* @values 'sm', 'lg'
*/
size: {
type: String,
validator: (value) => {
return ['sm', 'lg'].includes(value);
},
},
/**
* Similarly, create split button dropdowns with virtually the same markup as single button dropdowns, but with the addition of `.dropdown-toggle-split` className for proper spacing around the dropdown caret.
*/
split: Boolean,
/**
* Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them.
*
* @type 'hover' | 'focus' | 'click'
*/
trigger: {
type: String,
default: 'click',
},
/**
* Set the button variant to an outlined button or a ghost button.
*
* @values 'ghost', 'outline'
*/
variant: {
type: String,
validator: (value) => {
return ['ghost', 'outline'].includes(value);
},
},
},
setup(props, { slots }) {
const togglerRef = ref();
const dropdownToggleRef = inject('dropdownToggleRef');
const dropdownVariant = inject('variant');
const visible = inject('visible');
const setVisible = inject('setVisible');
const triggers = {
...((props.trigger === 'click' || props.trigger.includes('click')) && {
onClick: (event) => {
event.preventDefault();
if (props.disabled) {
return;
}
setVisible();
},
}),
...((props.trigger === 'focus' || props.trigger.includes('focus')) && {
onfocus: () => {
if (props.disabled) {
return;
}
setVisible(true);
},
onblur: () => {
if (props.disabled) {
return;
}
setVisible(false);
},
}),
};
const togglerProps = computed(() => {
return {
class: {
'nav-link': dropdownVariant === 'nav-item' && props.navLink,
'dropdown-toggle': props.caret,
'dropdown-toggle-split': props.split,
disabled: props.disabled,
show: visible.value,
},
'aria-expanded': visible.value,
...(!props.disabled && { ...triggers }),
};
});
onMounted(() => {
if (togglerRef.value) {
dropdownToggleRef.value = togglerRef.value.$el;
}
});
return () => props.custom
? slots.default &&
slots.default().map((slot) => cloneVNode(slot, {
ref: (el) => {
togglerRef.value = el;
},
...triggers,
}))
: dropdownVariant === 'nav-item' && props.navLink
? h('a', {
href: '#',
...togglerProps.value,
role: 'button',
ref: dropdownToggleRef,
}, { default: () => slots.default && slots.default() })
: h(CButton, {
...togglerProps.value,
as: props.as,
color: props.color,
disabled: props.disabled,
shape: props.shape,
size: props.size,
variant: props.variant,
ref: (el) => {
togglerRef.value = el;
},
}, () => props.split
? h('span', { class: 'visually-hidden' }, 'Toggle Dropdown')
: slots.default && slots.default());
},
});
export { CDropdownToggle };
//# sourceMappingURL=CDropdownToggle.js.map