Fixed #5996 - Add as and asChild property to Button

pull/6011/head
Mert Sincan 2024-07-01 13:03:12 +01:00
parent 7609a4c550
commit c2d8c17082
4 changed files with 38 additions and 2 deletions

View File

@ -1,7 +1,9 @@
import DeferredDemo from '@/components/demo/DeferredDemo.vue';
import PrimeVueNuxtLink from '@/components/layout/PrimeVueNuxtLink';
import CodeHighlight from '@/directives/CodeHighlight';
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('code', CodeHighlight);
nuxtApp.vueApp.component('DeferredDemo', DeferredDemo); // @todo
nuxtApp.vueApp.component('PrimeVueNuxtLink', PrimeVueNuxtLink);
});

View File

@ -42,6 +42,14 @@ export default {
type: String,
default: undefined
},
as: {
type: String,
default: 'BUTTON'
},
asChild: {
type: Boolean,
default: false
},
link: {
type: Boolean,
default: false

View File

@ -129,6 +129,16 @@ export interface ButtonProps extends ButtonHTMLAttributes {
* Icon to display in loading state.
*/
loadingIcon?: string | undefined;
/**
* Use to change the HTML tag of root element.
* @defaultValue BUTTON
*/
as?: string | undefined;
/**
* When enabled, it changes the default rendered element for the one passed as a child element.
* @defaultValue false
*/
asChild?: boolean | undefined;
/**
* Add a link style to the button.
* @defaultValue false

View File

@ -1,5 +1,5 @@
<template>
<button v-ripple :class="cx('root')" type="button" :aria-label="defaultAriaLabel" :disabled="disabled" v-bind="getPTOptions('root')" :data-p-severity="severity">
<component v-if="!asChild" :is="as" v-ripple :class="cx('root')" v-bind="attrs">
<slot>
<slot v-if="loading" name="loadingicon" :class="[cx('loadingIcon'), cx('icon')]">
<span v-if="loadingIcon" :class="[cx('loadingIcon'), cx('icon'), loadingIcon]" v-bind="ptm('loadingIcon')" />
@ -11,13 +11,15 @@
<span :class="cx('label')" v-bind="ptm('label')">{{ label || '&nbsp;' }}</span>
<Badge v-if="badge" :value="badge" :class="badgeClass" :severity="badgeSeverity" :unstyled="unstyled" v-bind="ptm('pcBadge')"></Badge>
</slot>
</button>
</component>
<slot v-else :class="cx('root')" :a11yAttrs="a11yAttrs"></slot>
</template>
<script>
import SpinnerIcon from '@primevue/icons/spinner';
import Badge from 'primevue/badge';
import Ripple from 'primevue/ripple';
import { mergeProps } from 'vue';
import BaseButton from './BaseButton.vue';
export default {
@ -44,6 +46,20 @@ export default {
},
hasIcon() {
return this.icon || this.$slots.icon;
},
attrs() {
return mergeProps(this.asAttrs, this.a11yAttrs, this.getPTOptions('root'));
},
asAttrs() {
return this.as === 'BUTTON' ? { type: 'button', disabled: this.disabled } : undefined;
},
a11yAttrs() {
return {
'aria-label': this.defaultAriaLabel,
'data-pc-name': 'button',
'data-p-disabled': this.disabled,
'data-p-severity': this.severity
};
}
},
components: {