All files / components/button-group ButtonGroup.vue

100% Statements 33/33
92.3% Branches 12/13
100% Functions 10/10
100% Lines 33/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104    3x 9x       3x     3x 3x 3x 3x 3x       3x                           15x                                           15x 15x 15x 15x 15x 15x 15x                   3x 3x 3x 3x 3x         15x 15x 15x   69x     69x     1x 18x       138x   130x              
<template>
	<div ref="rootElement" class="cdx-button-group">
		<cdx-button
			v-for="( button, index ) in buttons"
			:key="button.value"
			:ref="( ref ) => assignTemplateRef( ref, index )"
			:disabled="button.disabled || disabled"
			:aria-label="button.ariaLabel"
			@click="$emit( 'click', button.value )"
			@focus="onFocus( index )"
			@blur="onBlur"
			@keydown="onKeydown"
		>
			<!--
				@slot Content of an individual button
				@binding {ButtonGroupItem} button Object describing the button to display
			-->
			<slot :button="button">
				<cdx-icon v-if="button.icon" :icon="button.icon" />
				{{ getButtonLabel( button ) }}
			</slot>
		</cdx-button>
	</div>
</template>
 
<script lang="ts">
import { defineComponent, PropType, toRef } from 'vue';
import { ButtonGroupItem } from '../../types';
import { getButtonLabel } from '../../utils/buttonHelpers';
import useButtonGroupKeyboardNav from '../../composables/useButtonGroupKeyboardNav';
import CdxButton from '../button/Button.vue';
import CdxIcon from '../icon/Icon.vue';
 
/**
 * A set of two or more buttons representing equally important actions.
 */
export default defineComponent( {
	name: 'CdxButtonGroup',
	components: {
		CdxButton,
		CdxIcon
	},
	props: {
		/**
		 * Objects describing the buttons in the group. See the ButtonGroupItem type.
		 */
		buttons: {
			type: Array as PropType<ButtonGroupItem[]>,
			required: true,
			validator: ( value: unknown ) => Array.isArray( value ) && value.length >= 1
		},
		/**
		 * Whether the entire group is disabled.
		 *
		 * If this is set to true, all buttons in the group are disabled. Buttons can also be
		 * disabled individually by setting their `disabled` property to true.
		 */
		disabled: {
			type: Boolean,
			default: false
		}
	},
	emits: [
		/**
		 * Emitted when a button is clicked
		 *
		 * @property {string | number} value The `value` property of the button that was clicked
		 */
		'click'
	],
	setup( props ) {
		const {
			rootElement,
			assignTemplateRef,
			onFocus,
			onBlur,
			onKeydown
		} = useButtonGroupKeyboardNav( toRef( props, 'buttons' ) );
 
		return {
			rootElement,
			assignTemplateRef,
			onFocus,
			onBlur,
			onKeydown,
			getButtonLabel
		};
	}
} );
</script>
 
<style lang="less">
@import ( reference ) '@wikimedia/codex-design-tokens/theme-wikimedia-ui.less';
@import ( reference ) '../../themes/mixins/button-group.less';
 
.cdx-button-group {
	.cdx-mixin-button-group();
 
	.cdx-button {
		.cdx-mixin-button-group-button();
	}
}
</style>