# Componente
# Introducción
Componente que mostrará un selector de pestañas con una línea de tiempo.
# Uso
Es importante recalcar el nombre del componente IrStepper a nivel de código, ya que este deberá usarse para llamar al componente para renderizarlo, ya sea individiualmente o en un IrForm.
# Ejemplo
# Propiedades
| Propiedad | Tipo | Default | Descripción |
| readonly | Boolean |
| El valor |
| required | Boolean |
| En valor |
| items_fcn | String |
| Establece la función de base de datos a la cual se consultará para completar la información de la propiedad En caso de que la consulta a la BD devuelva un objeto con propiedades del |
| args_items_fcn | Array |
| Establece los argumentos que recibirá la función provista en |
| items | Array |
| Array de objectos con la estructura: que determinará de cada tab (pestaña) del IrStepper, el texto a mostrar y el valor que tomará la propiedad |
| value | Any | Propiedad que almacenará el value del item seleccionado. | |
| linked | Boolean | false | Determina la actualización del formulario contenedor. |
| showStep | Boolean | true | Determina si se muestra los números correspondientes a los steps. |
# Más propiedades de vuetify para el componente
Aquí se detallan más propiedades disponibles para el componente.
# Propiedades de los items
| Propiedad | Tipo | Default | Descripción |
| icon | String | '' | Determina el ícono que se renderizará dentro del step, aquí puede encontrar una lista de los íconos disponibles. |
| icon-color | String | '#000000' | Determina el color del ícono. |
| button-color | String | '#ffffff' | Determina el color del botón. |
# Más propiedades de vuetify para los items
Aquí se detallan más propiedades disponibles para los items del componente.
# Código fuente
<template>
<ir-stepper-bone
v-bind="$attrs"
@updateValue="updateSelectValue"
>
<div slot-scope="{ items, linked, showStep }">
<v-stepper
:ref="irStepperRef"
v-model="activeTab"
v-bind="getFilteredProps"
alt-labels
v-on="$listeners"
>
<v-stepper-header>
<template v-for="(item, i) in items">
<button
v-if="item.icon"
:key="'custom-step' + i"
v-bind="item"
type="button"
class="d-flex flex-column align-center justify-start button--step pt-4"
:style="
value === item.value ? 'background-color: #0000001c;' : ''
"
@click="(e) => updateValue(item.value, linked, items)"
>
<!--icon y elevation quedan fijas por el estilo del componente-->
<v-btn
icon
elevation="2"
:style="
'background-color: ' +
(item['button-color'] ? item['button-color'] : '#ffffff') +
';'
"
:color="item['icon-color'] ? item['icon-color'] : '#000000'"
@click="(e) => updateValue(item.value, linked, items)"
>
<v-icon>{{ item.icon }}</v-icon>
</v-btn>
<p style="text-align: center">{{ item.text.toUpperCase() }}</p>
</button>
<v-stepper-step
v-else
:key="'step' + i"
:step="showStep ? i + 1 : ''"
v-bind="item"
style="z-index: 2; cursor: pointer"
@click="(e) => updateValue(item.value, linked, items)"
>
{{ item.text }}
</v-stepper-step>
<v-divider
v-if="i + 1 !== items.length"
:key="'divider' + i"
style="z-index: 1"
/>
</template>
</v-stepper-header>
</v-stepper>
</div>
</ir-stepper-bone>
</template>
<script>
import IrStepperBone from './IrStepperBone.vue'
import { stepperComponentName } from '../../../constants'
import { setHintTag } from '../../../helpers/hint'
import focusAndScrollMixin from '../../../mixins/focusAndScroll'
import { filterProps } from '../../../helpers/filterProps'
export default {
name: stepperComponentName,
components: {
IrStepperBone
},
mixins: [focusAndScrollMixin],
inheritAttrs: false,
props: {
value: {
type: undefined,
required: true
},
isFocused: {
type: Boolean,
default: false
},
hint: {
type: [String, Object],
default: ''
}
},
data() {
return {
irStepperRef: stepperComponentName,
otherProps: {},
stepperComponentName: stepperComponentName,
activeTab: -1
}
},
computed: {
getFilteredProps() {
return filterProps(this.$refs[this.irStepperRef], this.handledAttrs, [
'data-cy'
])
},
handledAttrs() {
const hint = setHintTag(this.otherProps, this.hint)
let aux = { ...this.otherProps, ...this.$attrs }
delete aux.hint
if (hint) {
aux = { ...aux, hint }
}
delete aux.required
delete aux.items
delete aux.width
return aux
}
},
mounted() {
if (this.isFocused) {
let element = this.$refs[this.irStepperRef].$el
this.focusAndScroll(element)
}
let aux = { ...this.$attrs }
this.updateSelectValue({ value: this.value, items: aux.items })
this.otherProps = { ...this.$attrs }
},
methods: {
updateValue(newValue, linked, items) {
let valueIndex = items.findIndex((item) => item.value === newValue)
this.activeTab = valueIndex === -1 ? 1 : valueIndex + 1
this.$emit('input', newValue)
this.$nextTick(() => {
if (linked) this.$emit('change-linked-value')
})
},
updateSelectValue({ value, items }) {
let localValue = value ? value : this.value
let valueIndex
if (items)
valueIndex = items.findIndex((item) => item.value === localValue)
this.$nextTick(() => {
this.activeTab = valueIndex === -1 ? 1 : valueIndex + 1
})
this.$emit('input', localValue)
}
}
}
</script>
<style lang="css" scoped>
.button--step {
min-height: 100px;
width: 100px;
z-index: 2;
row-gap: 10px;
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
</style>