# ZeenStreamProgramItem
Компонент расписания стрима
# Example
блок 1
live10:00-11:00Название трансляции, которое написано примерно на 3 строки или чуть меньшеИмя спикераблок 2
10:00-11:00Название трансляции, которое написано примерно на 3 строки или чуть меньшеИмя спикераИмя спикера2блок много
10:00-11:00Название трансляции, которое написано примерно на 3 строки или чуть меньше
# Source Code
<template lang="pug">
.stream-item(
:id="`stream-item-${componentId}`"
:class="{'stream-item_hold': (speech.status !== 'online')}"
)
.stream-item__top
slot(
name="top"
:speech="speech"
)
ZeenTimeLabel(
:speech="speech"
)
span.stream-item__live-label(v-if="speech.status === 'online'") {{liveTitle}}
.stream-item__title {{speech.title}}
.stream-item__speakers(v-if="speech && speech.speakers.length")
slot(name="speakers" :speech="speech")
template(v-if="speech.speakers.length < 3")
ZeenSpeakerItem.stream-item__speaker(
v-for='speaker in speech.speakers'
:speaker="speaker"
)
//- todo интегрировать пробрасывание слотов как сделано в src/blocks/ZeenPlayerBlock/ZeenPlayerBlock.vue строка 72
template(v-else)
.stream-item__speaker-deck
ZeenSpeakerItem.stream-item__speaker-avatar(
v-for='(speaker, index) in speech.speakers.slice(0, 3)',
:key="index"
:speaker="speaker"
onlyAvatar
)
ZeenButton.stream-item__speaker-btn(
theme="fill-additional"
:color={buttonAdditionalColor: "none"}
@click.prevent="$emit('open-modal', modalName)"
) {{deckOfSpeakers}}
//- todo интегрировать пробрасывание слотов как сделано в src/blocks/ZeenPlayerBlock/ZeenPlayerBlock.vue строка 72
.stream-item__action(v-if="!hideActions")
slot(name="action" :speech="speech")
template(v-if='speech.status === "done"')
slot(name="action-done" :speech="speech")
ZeenButton.stream-item__btn(
theme="outline"
@click.prevent="$emit('click-watch-record', speech)"
) {{watchRecordTitle}}
template(v-else-if='speech.status === "online"')
slot(name="action-online" :speech="speech")
ZeenButton.stream-item__btn.stream-item__btn_desctop(
@click.prevent="$emit('click-watch', speech)"
) {{watchTitle}}
ZeenButton.stream-item__btn.stream-item__btn_mob(
theme="outline"
@click.prevent="$emit('click-watch', speech)"
) {{watchTitle}}
template(v-else-if='speech.status === "hold"')
slot(name="action-hold" :speech="speech")
ZeenButton.stream-item__btn(
theme="outline"
@click.prevent="$emit('click-add-to-record', speech)"
) {{addToRecordTitle}}
</template>
<script>
import ZeenTimeLabel from '../ZeenTimeLabel/ZeenTimeLabel'
import ZeenSpeakerItem from '../ZeenSpeakerItem/ZeenSpeakerItem'
import ZeenModal from '../ZeenModal/ZeenModal'
import ZeenButton from '../ZeenButton/ZeenButton'
import ZeenHeadline from '../ZeenHeadline/ZeenHeadline'
import deckOfWord from '../../plugins/deckOfWord'
export default {
name: 'ZeenStreamProgramItem',
components: {
ZeenHeadline,
ZeenButton,
ZeenModal,
ZeenSpeakerItem,
ZeenTimeLabel,
},
props: {
speech: {
type: Object,
default: () => {
return {}
},
},
hideActions: Boolean,
liveTitle: {
type: String,
default: 'live',
},
watchRecordTitle: {
type: String,
default: 'Смотреть запись',
},
watchTitle: {
type: String,
default: 'Смотреть',
},
addToRecordTitle: {
type: String,
default: 'Добавить в расписание',
},
singleSpeaker: {
type: String,
default: 'спикер',
},
whoSpeaker: {
type: String,
default: 'спикера',
},
manySpeakers: {
type: String,
default: 'спикеров',
},
modalName: String,
},
computed: {
componentId() {
return this._uid
},
deckOfSpeakers() {
const speakersCount = this.speech.speakers.length
if (speakersCount) {
if (speakersCount === 3) {
return `${speakersCount} ${deckOfWord(speakersCount, [
this.singleSpeaker,
this.whoSpeaker,
this.manySpeakers,
])}`
} else {
return `+ ${speakersCount - 3} ${deckOfWord(speakersCount - 3, [
this.singleSpeaker,
this.whoSpeaker,
this.manySpeakers,
])}`
}
}
return false
},
},
methods: {
openModal(name) {
this.$vfm.show(name)
},
},
}
</script>
<style lang="scss">
:root {
--zeen-stream-program-item-background: var(--gray-3);
--zeen-stream-program-item-border-color: transparent;
--zeen-stream-program-item-border-radius: 20px;
--zeen-stream-program-item-title-color: var(--main-text-color);
--zeen-stream-program-item-live-color: var(--main-danger-color);
--zeen-stream-program-item-speaker-border-color: var(--zeen-stream-program-item-background);
}
</style>
<style lang="scss">
:root {
/* Размеры */
--stream-program-item-padding: 35px;
--stream-program-item-border-radius: var(--main-input-radius);
--stream-program-item-title-font-size: var(--main-bigger-size);
--stream-program-item-picture-border: 50%;
/* Цвета */
--stream-program-item-background: var(--main-light);
--stream-program-item-border-color: transparent;
--stream-program-item-border-online-color: var(--main-color);
--stream-program-item-border-hold-color: transparent;
--stream-program-item-title-color: var(--main-text-color);
--stream-program-item-live-color: var(--main-danger-color);
}
</style>
<style lang="scss" scoped>
@import './src/styles/mixins.scss';
.stream-item {
--picture-border-radius: var(--stream-program-item-picture-border);
background: var(--stream-program-item-background);
flex: 1 1 auto;
width: 100%;
display: flex;
flex-direction: column;
border-radius: var(--stream-program-item-border-radius);
border: 1px solid var(--stream-program-item-border-color);
padding: var(--stream-program-item-padding);
&_hold {
--stream-program-item-border-color: var(--stream-program-item-border-hold-color) transparent;
}
&_online {
--stream-program-item-border-color: var(--stream-program-item-border-online-color);
}
&__top {
display: flex;
justify-content: space-between;
align-items: center;
}
&__live-label {
font-family: inherit;
font-weight: 600;
line-height: 1.4;
text-transform: uppercase;
color: var(--stream-program-item-live-color);
}
&__title {
font-family: inherit;
font-weight: 600;
font-size: var(--stream-program-item-title-font-size);
line-height: 1.3;
margin-top: 30px;
color: var(--stream-program-item-title-color);
@include phones {
margin-top: 20px;
}
}
&__speakers {
display: flex;
flex: 1 1 auto;
@include phones {
flex-direction: column;
}
}
&__speaker {
margin-top: 30px;
max-width: 220px;
width: 100%;
margin-right: 18px;
@include phones {
margin-top: 20px;
}
}
&__speaker-deck {
display: flex;
align-items: center;
margin-top: 30px;
@include phones {
margin-top: 20px;
}
}
&__speaker-avatar {
margin-left: -20px;
border: 3px solid transparent;
border-radius: 50%;
box-sizing: content-box;
border-color: var(--zeen-stream-program-item-speaker-border-color);
&:first-of-type {
z-index: 3;
margin-left: 0;
}
&:nth-child(2) {
z-index: 2;
}
&:last-of-type {
z-index: 1;
}
}
&__speaker-btn {
padding: 0;
margin-left: 20px;
@include phones {
margin-left: 5px;
font-size: 11px;
}
}
&__btn {
&_desctop {
@include phones {
display: none;
}
}
&_mob {
display: none;
@include phones {
display: flex;
}
}
@include phones {
padding: 0;
border: none;
}
}
&__action {
margin-top: 30px;
}
}
</style>
<style lang="scss">
.stream-item__speaker-avatar {
.speaker-item__picture {
margin-right: 0;
}
}
</style>
# slots
# props
# Кастомные стили
Название | Тип | Обязательный | По умолчанию | Описание |
---|---|---|---|---|
streamProgramBorderRadius | Number | - | 10 | скругление |