pull/5677/head
mertsincan 2024-04-25 00:37:23 +01:00
parent a2524ed21a
commit 305af028fc
6 changed files with 173 additions and 88 deletions

View File

@ -1,46 +1,41 @@
<template> <template>
<div ref="list" :class="cx('root')" v-bind="ptmi('root')"> <div ref="list" :class="cx('root')" v-bind="ptmi('root')">
<Button <button
v-if="showNavigators && isPrevButtonEnabled" v-if="showNavigators && isPrevButtonEnabled"
ref="prevButton" ref="prevButton"
v-ripple
:class="cx('previousButton')" :class="cx('previousButton')"
:aria-label="prevButtonAriaLabel" :aria-label="prevButtonAriaLabel"
:unstyled="$pcTabs.unstyled"
:tabindex="$pcTabs.tabindex" :tabindex="$pcTabs.tabindex"
@click="onPrevButtonClick" @click="onPrevButtonClick"
v-bind="$pcTabs.previousButtonProps" v-bind="ptm('previousButton')"
:pt="ptm('previousButton')"
data-pc-group-section="navigator" data-pc-group-section="navigator"
> >
<template #icon="slotProps"> <component :is="templates.previousicon || 'ChevronLeftIcon'" aria-hidden="true" v-bind="ptm('previousIcon')" />
<component :is="templates.previousicon || 'ChevronLeftIcon'" aria-hidden="true" :class="slotProps.icon" v-bind="ptm('previousButton.icon')" /> </button>
</template> <div ref="content" :class="cx('content')" @scroll="onScroll" v-bind="ptm('content')">
</Button> <div ref="tabs" :class="cx('tabs')" role="tablist" :aria-orientation="$pcTabs.orientation" v-bind="ptm('tabs')">
<div ref="content" :class="cx('content')" role="tablist" :aria-orientation="$pcTabs.orientation" @scroll="onScroll" v-bind="ptm('content')"> <slot></slot>
<slot></slot> <span ref="inkbar" :class="cx('inkbar')" role="presentation" aria-hidden="true" v-bind="ptm('inkbar')"></span>
<span ref="inkbar" :class="cx('inkbar')" role="presentation" aria-hidden="true" v-bind="ptm('inkbar')"></span> </div>
</div> </div>
<Button <button
v-if="showNavigators && isNextButtonEnabled" v-if="showNavigators && isNextButtonEnabled"
ref="nextButton" ref="nextButton"
v-ripple
:class="cx('nextButton')" :class="cx('nextButton')"
:aria-label="nextButtonAriaLabel" :aria-label="nextButtonAriaLabel"
:unstyled="$pcTabs.unstyled"
:tabindex="$pcTabs.tabindex" :tabindex="$pcTabs.tabindex"
@click="onNextButtonClick" @click="onNextButtonClick"
v-bind="$pcTabs.nextButtonProps" v-bind="ptm('nextButton')"
:pt="ptm('nextButton')"
data-pc-group-section="navigator" data-pc-group-section="navigator"
> >
<template #icon="slotProps"> <component :is="templates.nexticon || 'ChevronRightIcon'" aria-hidden="true" v-bind="ptm('nextIcon')" />
<component :is="templates.nexticon || 'ChevronRightIcon'" aria-hidden="true" :class="slotProps.icon" v-bind="ptm('nextButton.icon')" /> </button>
</template>
</Button>
</div> </div>
</template> </template>
<script> <script>
import Button from 'primevue/button';
import ChevronLeftIcon from 'primevue/icons/chevronleft'; import ChevronLeftIcon from 'primevue/icons/chevronleft';
import ChevronRightIcon from 'primevue/icons/chevronright'; import ChevronRightIcon from 'primevue/icons/chevronright';
import { DomHandler } from 'primevue/utils'; import { DomHandler } from 'primevue/utils';
@ -115,11 +110,11 @@ export default {
this.resizeObserver = undefined; this.resizeObserver = undefined;
}, },
updateInkBar() { updateInkBar() {
const { content, inkbar } = this.$refs; const { content, inkbar, tabs } = this.$refs;
const activeTab = DomHandler.findSingle(content, '[data-pc-name="tab"][data-p-active="true"]'); const activeTab = DomHandler.findSingle(content, '[data-pc-name="tab"][data-p-active="true"]');
inkbar.style.width = DomHandler.getOuterWidth(activeTab) + 'px'; inkbar.style.width = DomHandler.getOuterWidth(activeTab) + 'px';
inkbar.style.left = DomHandler.getOffset(activeTab).left - DomHandler.getOffset(content).left + 'px'; inkbar.style.left = DomHandler.getOffset(activeTab).left - DomHandler.getOffset(tabs).left + 'px';
}, },
updateButtonState() { updateButtonState() {
const { list, content } = this.$refs; const { list, content } = this.$refs;
@ -153,7 +148,6 @@ export default {
} }
}, },
components: { components: {
Button,
ChevronLeftIcon, ChevronLeftIcon,
ChevronRightIcon ChevronRightIcon
} }

View File

@ -5,9 +5,10 @@ const classes = {
content: ({ instance }) => [ content: ({ instance }) => [
'p-tablist-content', 'p-tablist-content',
{ {
'p-tablist-scroll-container': instance.$pcTabs.scrollable 'p-tablist-scroller': instance.$pcTabs.scrollable
} }
], ],
tabs: 'p-tablist-tabs',
inkbar: 'p-tablist-ink-bar', inkbar: 'p-tablist-ink-bar',
previousButton: 'p-tablist-prev-button p-tablist-navigator', previousButton: 'p-tablist-prev-button p-tablist-navigator',
nextButton: 'p-tablist-next-button p-tablist-navigator' nextButton: 'p-tablist-next-button p-tablist-navigator'

View File

@ -33,18 +33,6 @@ export default {
selectOnFocus: { selectOnFocus: {
type: Boolean, type: Boolean,
default: false default: false
},
previousButtonProps: {
type: Object,
default: () => {
return { severity: 'secondary', text: true };
}
},
nextButtonProps: {
type: Object,
default: () => {
return { severity: 'secondary', text: true };
}
} }
}, },
style: TabsStyle, style: TabsStyle,

View File

@ -9,7 +9,6 @@
*/ */
import { VNode } from 'vue'; import { VNode } from 'vue';
import { ComponentHooks } from '../basecomponent'; import { ComponentHooks } from '../basecomponent';
import { ButtonProps } from '../button';
import { PassThroughOptions } from '../passthrough'; import { PassThroughOptions } from '../passthrough';
import { ClassComponent, DesignToken, GlobalComponentConstructor, PassThrough } from '../ts-helpers'; import { ClassComponent, DesignToken, GlobalComponentConstructor, PassThrough } from '../ts-helpers';
@ -120,14 +119,6 @@ export interface TabsProps {
* @defaultValue false * @defaultValue false
*/ */
selectOnFocus?: boolean | undefined; selectOnFocus?: boolean | undefined;
/**
* Used to pass all properties of the HTMLButtonElement to the previous button.
*/
previousButtonProps?: ButtonProps | undefined;
/**
* Used to pass all properties of the HTMLButtonElement to the next button.
*/
nextButtonProps?: ButtonProps | undefined;
/** /**
* It generates scoped CSS variables using design tokens for the component. * It generates scoped CSS variables using design tokens for the component.
*/ */

View File

@ -5,7 +5,15 @@ export default {
flex-direction: column; flex-direction: column;
} }
.p-tablist-scroll-container { .p-tablist {
position: relative;
}
.p-tabs-scrollable > .p-tablist {
overflow: hidden;
}
.p-tablist-scroller {
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
scroll-behavior: smooth; scroll-behavior: smooth;
@ -13,34 +21,49 @@ export default {
overscroll-behavior: contain auto; overscroll-behavior: contain auto;
} }
.p-tablist-scroll-container::-webkit-scrollbar { .p-tablist-scroller::-webkit-scrollbar {
display: none; display: none;
} }
.p-tablist { .p-tablist-tabs {
position: relative;
background: ${dt('tabs.nav.background')};
}
.p-tablist-content {
position: relative; position: relative;
display: flex; display: flex;
background: ${dt('tabs.nav.background')};
border: 1px solid ${dt('tabs.nav.border.color')}; border: 1px solid ${dt('tabs.nav.border.color')};
border-width: 0 0 1px 0; border-width: 0 0 1px 0;
} }
.p-tablist-navigator.p-button { .p-tablist-navigator {
all: unset;
position: absolute; position: absolute;
top: 0;
z-index: 2; z-index: 2;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: ${dt('tabs.navigator.icon.background')};
color: ${dt('tabs.navigator.icon.color')};
width: 2.5rem;
transition: color ${dt('transition.duration')}, outline-color ${dt('transition.duration')};
box-shadow: ${dt('tabs.navigator.icon.box.shadow')};
cursor: pointer;
} }
.p-tablist-navigator.p-tablist-prev-button { .p-tablist-navigator:focus-visible {
top: 0; outline: ${dt('focus.ring.width')} ${dt('focus.ring.style')} ${dt('focus.ring.color')};
outline-offset: ${dt('focus.ring.offset')};
}
.p-tablist-navigator:hover {
color: ${dt('tabs.navigator.icon.hover.color')};
}
.p-tablist-prev-button {
left: 0; left: 0;
} }
.p-tablist-navigator.p-tablist-next-button { .p-tablist-next-button {
top: 0;
right: 0; right: 0;
} }

View File

@ -170,7 +170,8 @@
"readonly": false, "readonly": false,
"type": "AccordionTabPassThroughOptionType", "type": "AccordionTabPassThroughOptionType",
"default": "", "default": "",
"description": "Used to pass attributes to AccordionTab helper components." "description": "Used to pass attributes to AccordionTab helper components.",
"deprecated": "since v4. Use new structure instead."
}, },
{ {
"name": "hooks", "name": "hooks",
@ -209,12 +210,12 @@
"description": "Current id state as a string" "description": "Current id state as a string"
}, },
{ {
"name": "d_activeIndex", "name": "d_value",
"optional": false, "optional": false,
"readonly": false, "readonly": false,
"type": "number | number[]", "type": "string | string[]",
"default": "", "default": "",
"description": "Current active index state." "description": "Current active value state."
} }
], ],
"methods": [] "methods": []
@ -223,6 +224,14 @@
"description": "Defines valid properties in Accordion component.", "description": "Defines valid properties in Accordion component.",
"relatedProp": "", "relatedProp": "",
"props": [ "props": [
{
"name": "value",
"optional": true,
"readonly": false,
"type": "null | string | string[]",
"default": "null",
"description": "Value of the active panel or an array of values in multiple mode."
},
{ {
"name": "multiple", "name": "multiple",
"optional": true, "optional": true,
@ -237,7 +246,8 @@
"readonly": false, "readonly": false,
"type": "null | number | number[]", "type": "null | number | number[]",
"default": "null", "default": "null",
"description": "Index of the active tab or an array of indexes in multiple mode." "description": "Index of the active tab or an array of indexes in multiple mode.",
"deprecated": "since v4. Use value property instead."
}, },
{ {
"name": "lazy", "name": "lazy",
@ -344,6 +354,19 @@
"relatedProp": "", "relatedProp": "",
"props": [], "props": [],
"methods": [ "methods": [
{
"name": "update:value",
"parameters": [
{
"name": "value",
"optional": false,
"type": "undefined | null | string | string[]",
"description": "Value of new active panel."
}
],
"returnType": "void",
"description": "Emitted when the active panel changes."
},
{ {
"name": "update:activeIndex", "name": "update:activeIndex",
"parameters": [ "parameters": [
@ -355,7 +378,8 @@
} }
], ],
"returnType": "void", "returnType": "void",
"description": "Emitted when the active tab changes." "description": "Emitted when the active tab changes.",
"deprecated": "since v4. Use update:value emit instead."
}, },
{ {
"name": "tab-open", "name": "tab-open",
@ -368,7 +392,8 @@
} }
], ],
"returnType": "void", "returnType": "void",
"description": "Callback to invoke when a tab gets expanded." "description": "Callback to invoke when a tab gets expanded.",
"deprecated": "since v4."
}, },
{ {
"name": "tab-close", "name": "tab-close",
@ -381,7 +406,8 @@
} }
], ],
"returnType": "void", "returnType": "void",
"description": "Callback to invoke when an active tab is collapsed by clicking on the header." "description": "Callback to invoke when an active tab is collapsed by clicking on the header.",
"deprecated": "since v4."
}, },
{ {
"name": "tab-click", "name": "tab-click",
@ -394,7 +420,8 @@
} }
], ],
"returnType": "void", "returnType": "void",
"description": "Callback to invoke when an active tab is clicked." "description": "Callback to invoke when an active tab is clicked.",
"deprecated": "since v4."
} }
] ]
} }
@ -552,6 +579,22 @@
"default": "", "default": "",
"description": "Used to pass attributes to the root's DOM element." "description": "Used to pass attributes to the root's DOM element."
}, },
{
"name": "transition",
"optional": true,
"readonly": false,
"type": "AccordionContentPassThroughOptionType",
"default": "",
"description": "Used to pass attributes to the transition's DOM element."
},
{
"name": "content",
"optional": true,
"readonly": false,
"type": "AccordionContentPassThroughOptionType",
"default": "",
"description": "Used to pass attributes to the content's DOM element."
},
{ {
"name": "hooks", "name": "hooks",
"optional": true, "optional": true,
@ -809,6 +852,14 @@
"default": "", "default": "",
"description": "Used to pass attributes to the root's DOM element." "description": "Used to pass attributes to the root's DOM element."
}, },
{
"name": "toggleicon",
"optional": true,
"readonly": false,
"type": "AccordionHeaderPassThroughOptionType",
"default": "",
"description": "Used to pass attributes to the root's DOM element."
},
{ {
"name": "hooks", "name": "hooks",
"optional": true, "optional": true,
@ -1260,10 +1311,10 @@
} }
}, },
"accordiontab": { "accordiontab": {
"description": "AccordionTab is a helper component for Accordion.\n\n[Live Demo](https://www.primevue.org/accordion/)", "description": "",
"components": { "components": {
"default": { "default": {
"description": "AccordionTab is a helper component for Accordion..", "description": "",
"methods": { "methods": {
"description": "Defines methods that can be accessed by the component's reference.", "description": "Defines methods that can be accessed by the component's reference.",
"values": [] "values": []
@ -16050,12 +16101,35 @@
"type": "DefaultPassThrough<AccordionPassThroughOptions>", "type": "DefaultPassThrough<AccordionPassThroughOptions>",
"default": "" "default": ""
}, },
{
"name": "accordionpanel",
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<AccordionPanelPassThroughOptions>",
"default": ""
},
{
"name": "accordionheader",
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<AccordionHeaderPassThroughOptions>",
"default": ""
},
{
"name": "accordioncontent",
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<AccordionContentPassThroughOptions>",
"default": ""
},
{ {
"name": "accordiontab", "name": "accordiontab",
"optional": true, "optional": true,
"readonly": false, "readonly": false,
"type": "DefaultPassThrough<AccordionTabPassThroughOptions>", "type": "DefaultPassThrough<AccordionTabPassThroughOptions>",
"default": "" "default": "",
"description": "",
"deprecated": "since v4. Use the new structure of Accordion instead."
}, },
{ {
"name": "autocomplete", "name": "autocomplete",
@ -16596,6 +16670,34 @@
"type": "DefaultPassThrough<TabMenuPassThroughOptions>", "type": "DefaultPassThrough<TabMenuPassThroughOptions>",
"default": "" "default": ""
}, },
{
"name": "tabs",
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<TabsPassThroughOptions>",
"default": ""
},
{
"name": "tablist",
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<TabListPassThroughOptions>",
"default": ""
},
{
"name": "tab",
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<TabPassThroughOptions>",
"default": ""
},
{
"name": "tabpanels",
"optional": true,
"readonly": false,
"type": "DefaultPassThrough<TabPanelsPassThroughOptions>",
"default": ""
},
{ {
"name": "tabpanel", "name": "tabpanel",
"optional": true, "optional": true,
@ -16608,7 +16710,9 @@
"optional": true, "optional": true,
"readonly": false, "readonly": false,
"type": "DefaultPassThrough<TabViewPassThroughOptions>", "type": "DefaultPassThrough<TabViewPassThroughOptions>",
"default": "" "default": "",
"description": "",
"deprecated": "since v4. Use tabs instead."
}, },
{ {
"name": "tag", "name": "tag",
@ -59207,22 +59311,6 @@
"default": "false", "default": "false",
"description": "When enabled, the focused tab is activated." "description": "When enabled, the focused tab is activated."
}, },
{
"name": "previousButtonProps",
"optional": true,
"readonly": false,
"type": "ButtonProps",
"default": "",
"description": "Used to pass all properties of the HTMLButtonElement to the previous button."
},
{
"name": "nextButtonProps",
"optional": true,
"readonly": false,
"type": "ButtonProps",
"default": "",
"description": "Used to pass all properties of the HTMLButtonElement to the next button."
},
{ {
"name": "dt", "name": "dt",
"optional": true, "optional": true,
@ -59374,7 +59462,7 @@
} }
}, },
"tabview": { "tabview": {
"description": "TabView is a container component to group content with tabs.\n\n[Live Demo](https://www.primevue.org/tabview/)", "description": "",
"components": { "components": {
"default": { "default": {
"description": "", "description": "",