# Componente
# Introducción
Componente que mostrará un selector de pestañas.
# Uso
Es importante recalcar el nombre del componente IrTabs 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 IrTabs, 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. |
| icon-attrs | Object |
| Atributos que se pasaran al componente v-icon del ir-tabs. |
# Más propiedades de vuetify para el componente
Aquí se detallan más propiedades disponibles para el componente.
# Propiedades de items
| Propiedad | Tipo | Default | Descripción |
| icon | String | '' | Determina el ícono que se renderizará dentro del tab, aquí puede encontrar una lista de los íconos disponibles. |
# 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-tabs-bone
v-bind="$attrs"
:initial-items="$attrs.items"
:items.sync="items"
@update-value="updateSelectValue"
>
<div slot-scope="{ readonly, linked }">
<v-card>
<v-toolbar
height="auto"
flat
>
<v-tabs
:ref="irTabsRef"
v-bind="getFilteredProps"
:value="activeTabComputed"
class="pt-0 align-center"
height="46px"
show-arrows
v-on="$listeners"
>
<v-tabs-slider color="primary" />
<v-tab
v-for="(item, i) in items"
:key="i"
class="tab"
:disabled="readonly"
v-bind="item"
:tab-value="item.value"
@click="(e) => updateValue(item.value, linked)"
>
<div class="d-flex tab--container ma-0">
<v-icon
v-if="item.icon"
v-bind="iconAttrs"
>
{{ item.icon }}
</v-icon>
<span
class="tab--text"
:class="
value === item.value
? 'tab--text-selected'
: 'tab--text-unselected'
"
>{{ item.text }}
</span>
</div>
</v-tab>
</v-tabs>
</v-toolbar>
</v-card>
</div>
</ir-tabs-bone>
</template>
<script>
import IrTabsBone from './IrTabsBone.vue'
import { tabsComponentName } from '../../../constants'
import focusAndScrollMixin from '../../../mixins/focusAndScroll'
import { filterProps } from '../../../helpers/filterProps'
export default {
name: tabsComponentName,
components: {
IrTabsBone
},
mixins: [focusAndScrollMixin],
inheritAttrs: false,
props: {
value: {
type: undefined,
required: true
},
isFocused: {
type: Boolean,
default: false
},
iconAttrs: {
type: Object,
default: () => ({})
}
},
data() {
return {
items: [],
irTabsRef: tabsComponentName,
otherProps: {},
tabsComponentName: tabsComponentName
}
},
computed: {
getFilteredProps() {
return filterProps(this.$refs[this.irTabsRef], this.otherProps, [
'data-cy'
])
},
activeTabComputed() {
let valueIndex = this.items.findIndex((item) => item.value === this.value)
return valueIndex === -1 ? 0 : valueIndex
}
},
mounted() {
if (this.isFocused) {
let element = this.$refs[this.irTabsRef].$el
this.focusAndScroll(element)
}
let aux = { ...this.$attrs }
this.updateSelectValue(this.value)
delete aux.required
delete aux.items
this.otherProps = aux
},
methods: {
updateValue(newValue, linked) {
this.$emit('input', newValue)
this.$nextTick(() => {
if (linked) this.$emit('change-linked-value')
})
},
updateSelectValue(value) {
let localValue = value ? value : this.value
this.$emit('input', localValue)
}
}
}
</script>
<style lang="scss" scoped>
.tab {
&--container {
gap: 8px;
align-items: center;
}
&--text {
text-transform: none;
&-selected {
font-weight: 600;
color: var(--v-textPrimary-base);
}
&-unselected {
font-weight: 400;
color: var(--v-textSecondary-base);
}
}
}
</style>