Update #3965 - For Steps

pull/4011/head
Tuğçe Küçükoğlu 2023-05-30 14:58:41 +03:00
parent fb89a7368a
commit 11935c4204
3 changed files with 131 additions and 110 deletions

View File

@ -0,0 +1,112 @@
<script>
import BaseComponent from 'primevue/basecomponent';
import { useStyle } from 'primevue/usestyle';
const styles = `
.p-steps {
position: relative;
}
.p-steps .p-steps-list {
padding: 0;
margin: 0;
list-style-type: none;
display: flex;
}
.p-steps-item {
position: relative;
display: flex;
justify-content: center;
flex: 1 1 auto;
overflow: hidden;
}
.p-steps-item .p-menuitem-link {
display: inline-flex;
flex-direction: column;
align-items: center;
overflow: hidden;
text-decoration: none;
}
.p-steps.p-steps-readonly .p-steps-item {
cursor: auto;
}
.p-steps-item.p-steps-current .p-menuitem-link {
cursor: default;
}
.p-steps-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.p-steps-number {
display: flex;
align-items: center;
justify-content: center;
}
.p-steps-title {
display: block;
}
`;
const classes = {
root: ({ instance }) => ['p-steps p-component', { 'p-readonly': instance.readonly }],
menu: 'p-steps-list',
menuitem: ({ instance, item }) => [
'p-steps-item',
{
'p-highlight p-steps-current': instance.isActive(item),
'p-disabled': instance.isItemDisabled(item)
}
],
action: ({ props, isActive, isExactActive }) => [
'p-menuitem-link',
{
'router-link-active': isActive,
'router-link-active-exact': props.exact && isExactActive
}
],
step: 'p-steps-number',
label: 'p-steps-title'
};
const { load: loadStyle } = useStyle(styles, { id: 'primevue_steps_style', manual: true });
export default {
name: 'BaseSteps',
extends: BaseComponent,
props: {
id: {
type: String
},
model: {
type: Array,
default: null
},
readonly: {
type: Boolean,
default: true
},
exact: {
type: Boolean,
default: true
}
},
css: {
classes,
loadStyle
},
provide() {
return {
$parentInstance: this
};
}
};
</script>

View File

@ -85,6 +85,11 @@ export interface StepsProps {
* @type {StepsPassThroughOptions} * @type {StepsPassThroughOptions}
*/ */
pt?: StepsPassThroughOptions; pt?: StepsPassThroughOptions;
/**
* When enabled, it removes component related styles in the core.
* @defaultValue false
*/
unstyled?: boolean;
} }
/** /**

View File

@ -1,26 +1,26 @@
<template> <template>
<nav :id="id" :class="containerClass" v-bind="ptm('root')"> <nav :id="id" :class="cx('root')" v-bind="ptm('root')" data-pc-name="steps">
<ol ref="list" class="p-steps-list" v-bind="ptm('menu')"> <ol ref="list" :class="cx('menu')" v-bind="ptm('menu')">
<template v-for="(item, index) of model" :key="item.to"> <template v-for="(item, index) of model" :key="item.to">
<li v-if="visible(item)" :class="getItemClass(item)" :style="item.style" v-bind="ptm('menuitem')"> <li v-if="visible(item)" :class="[cx('menuitem', { item }), item.class]" :style="item.style" v-bind="ptm('menuitem')" :data-p-highlight="isActive(item)" :data-p-disabled="isItemDisabled(item)">
<template v-if="!$slots.item"> <template v-if="!$slots.item">
<router-link v-if="!isItemDisabled(item)" v-slot="{ navigate, href, isActive, isExactActive }" :to="item.to" custom> <router-link v-if="!isItemDisabled(item)" v-slot="{ navigate, href, isActive, isExactActive }" :to="item.to" custom>
<a <a
:href="href" :href="href"
:class="linkClass({ isActive, isExactActive })" :class="cx('action', { isActive, isExactActive })"
:tabindex="-1" :tabindex="-1"
:aria-current="isExactActive ? 'step' : undefined" :aria-current="isExactActive ? 'step' : undefined"
@click="onItemClick($event, item, navigate)" @click="onItemClick($event, item, navigate)"
@keydown="onItemKeydown($event, item, navigate)" @keydown="onItemKeydown($event, item, navigate)"
v-bind="ptm('action')" v-bind="ptm('action')"
> >
<span class="p-steps-number" v-bind="ptm('step')">{{ index + 1 }}</span> <span :class="cx('step')" v-bind="ptm('step')">{{ index + 1 }}</span>
<span class="p-steps-title" v-bind="ptm('label')">{{ label(item) }}</span> <span :class="cx('label')" v-bind="ptm('label')">{{ label(item) }}</span>
</a> </a>
</router-link> </router-link>
<span v-else :class="linkClass()" @keydown="onItemKeydown($event, item)" v-bind="ptm('action')"> <span v-else :class="cx('action')" @keydown="onItemKeydown($event, item)" v-bind="ptm('action')">
<span class="p-steps-number" v-bind="ptm('step')">{{ index + 1 }}</span> <span :class="cx('step')" v-bind="ptm('step')">{{ index + 1 }}</span>
<span class="p-steps-title" v-bind="ptm('label')">{{ label(item) }}</span> <span :class="cx('label')" v-bind="ptm('label')">{{ label(item) }}</span>
</span> </span>
</template> </template>
<component v-else :is="$slots.item" :item="item"></component> <component v-else :is="$slots.item" :item="item"></component>
@ -31,30 +31,12 @@
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent'; import { DomHandler } from 'primevue/utils';
import { DomHandler, UniqueComponentId } from 'primevue/utils'; import BaseSteps from './BaseSteps.vue';
export default { export default {
name: 'Steps', name: 'Steps',
extends: BaseComponent, extends: BaseSteps,
props: {
id: {
type: String,
default: UniqueComponentId()
},
model: {
type: Array,
default: null
},
readonly: {
type: Boolean,
default: true
},
exact: {
type: Boolean,
default: true
}
},
mounted() { mounted() {
const firstItem = this.findFirstItem(); const firstItem = this.findFirstItem();
@ -152,12 +134,12 @@ export default {
return prevItem ? prevItem.children[0] : null; return prevItem ? prevItem.children[0] : null;
}, },
findFirstItem() { findFirstItem() {
const firstSibling = DomHandler.findSingle(this.$refs.list, '.p-steps-item'); const firstSibling = DomHandler.findSingle(this.$refs.list, '[data-pc-section="menuitem"]');
return firstSibling ? firstSibling.children[0] : null; return firstSibling ? firstSibling.children[0] : null;
}, },
findLastItem() { findLastItem() {
const siblings = DomHandler.find(this.$refs.list, '.p-steps-item'); const siblings = DomHandler.find(this.$refs.list, '[data-pc-section="menuitem"]');
return siblings ? siblings[siblings.length - 1].children[0] : null; return siblings ? siblings[siblings.length - 1].children[0] : null;
}, },
@ -169,25 +151,6 @@ export default {
isActive(item) { isActive(item) {
return item.to ? this.$router.resolve(item.to).path === this.$route.path : false; return item.to ? this.$router.resolve(item.to).path === this.$route.path : false;
}, },
getItemClass(item) {
return [
'p-steps-item',
item.class,
{
'p-highlight p-steps-current': this.isActive(item),
'p-disabled': this.isItemDisabled(item)
}
];
},
linkClass(routerProps) {
return [
'p-menuitem-link',
{
'router-link-active': routerProps && routerProps.isActive,
'router-link-active-exact': this.exact && routerProps && routerProps.isExactActive
}
];
},
isItemDisabled(item) { isItemDisabled(item) {
return this.disabled(item) || (this.readonly && !this.isActive(item)); return this.disabled(item) || (this.readonly && !this.isActive(item));
}, },
@ -200,65 +163,6 @@ export default {
label(item) { label(item) {
return typeof item.label === 'function' ? item.label() : item.label; return typeof item.label === 'function' ? item.label() : item.label;
} }
},
computed: {
containerClass() {
return ['p-steps p-component', { 'p-readonly': this.readonly }];
}
} }
}; };
</script> </script>
<style>
.p-steps {
position: relative;
}
.p-steps .p-steps-list {
padding: 0;
margin: 0;
list-style-type: none;
display: flex;
}
.p-steps-item {
position: relative;
display: flex;
justify-content: center;
flex: 1 1 auto;
overflow: hidden;
}
.p-steps-item .p-menuitem-link {
display: inline-flex;
flex-direction: column;
align-items: center;
overflow: hidden;
text-decoration: none;
}
.p-steps.p-steps-readonly .p-steps-item {
cursor: auto;
}
.p-steps-item.p-steps-current .p-menuitem-link {
cursor: default;
}
.p-steps-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.p-steps-number {
display: flex;
align-items: center;
justify-content: center;
}
.p-steps-title {
display: block;
}
</style>