# 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

false

El valor readonly = true, establecerá al campo como solo lectura.

required Boolean

false

En valor true, define que el componente debe ser valorizado para ser válido.

items_fcn String

''

Establece la función de base de datos a la cual se consultará para completar la información de la propiedad items. La consulta a la base de datos reemplazará lo contenido en la propiedad items, en caso de no enviarse esta propiedad o que se reciba un string vacío no se consultará a la BD y se utilizarán los datos provistos en items.

En caso de que la consulta a la BD devuelva un objeto con propiedades del IrStepper, las mismas se utilizarán para reemplazar las propiedades actuales. Si únicamente devuelve un arreglo, el mismo se utilizará para reemplazar los items.

args_items_fcn Array

''

Establece los argumentos que recibirá la función provista en items_fcn

items Array

[]

Array de objectos con la estructura:

[
  {
    text: String,
    value: Any type,
    ...
    // más propiedades de cada step
  }
]

que determinará de cada tab (pestaña) del IrStepper, el texto a mostrar y el valor que tomará la propiedad value al seleccionar dicho step.

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>
Last Updated: 4/5/2024, 4:52:19 PM