UNPKG

@coreui/vue-pro

Version:

UI Components Library for Vue.js

99 lines (91 loc) 2.29 kB
import { defineComponent, h, ref, watch } from 'vue' import { CButton } from '../button/CButton' import { CSpinner } from '../spinner/CSpinner' import type { ComponentProps } from '../../utils/ComponentProps' interface CLoadingButtonProps extends ComponentProps<typeof CButton> { disabledOnLoading?: boolean loading?: boolean spinnerType?: 'border' | 'grow' timeout?: number } const CLoadingButton = defineComponent({ name: 'CLoadingButton', props: { /** * Makes button disabled when loading. */ disabledOnLoading: Boolean, /** * Loading state (set to true to start animation). */ loading: { type: Boolean, default: false, required: false, }, /** * Sets type of spinner. * * @values 'border', 'grow' * @default 'border' */ spinnerType: { type: String, default: 'border', required: false, validator: (value: string) => { return ['border', 'grow'].includes(value) }, }, /** * Automatically starts loading animation and stops after a determined amount of milliseconds. */ timeout: { type: Number, default: undefined, required: false, }, ...CButton.props, }, emits: [ /** * Event called when the user clicks on a component. */ 'click', ], setup(props: CLoadingButtonProps, { emit, slots }) { const loading = ref(props.loading) watch( () => props.loading, () => { loading.value = props.loading }, ) const handleOnClick = () => { emit('click') if (props.timeout) { loading.value = true setTimeout(() => { loading.value = false }, props.timeout) } } return () => h( CButton, { ...props, class: ['btn-loading', { ['is-loading']: loading.value }], ...(props.disabledOnLoading && loading.value && { disabled: true }), onClick: () => handleOnClick(), }, { default: () => [ h(CSpinner, { class: 'btn-loading-spinner', size: 'sm', variant: props.spinnerType }), slots.default && slots.default(), ], }, ) }, }) export { CLoadingButton }