Created
March 2, 2021 14:40
-
-
Save YuraKolesnikov/0855ffb16588428c48e5e853ed646a01 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { withDesign } from 'storybook-addon-designs' | |
import { withPadding, withContainer } from '../../.storybook/helpers' | |
import VDomainCard from './VDomainCard' | |
import { domains } from './domains' | |
export default { | |
title: 'Simple Components / VDomainCard', | |
decorators: [withContainer, withPadding, withDesign] | |
} | |
export const Standard = args => ({ | |
props: Object.keys(args), | |
components: { VDomainCard }, | |
data () { | |
return { | |
domains | |
} | |
}, | |
template: ` | |
<div style="max-width: 1200px; display: grid; grid-template-columns: repeat(auto-fill, minmax(288px, 328px)); grid-column-gap: 24px"> | |
<VDomainCard view="box" v-for="domain in domains" :key="domain.id" :product="domain" v-bind="$props" /> | |
</div> | |
` | |
}) | |
Standard.args = { | |
domain: 'kekis' | |
} | |
export const List = args => ({ | |
props: Object.keys(args), | |
components: { VDomainCard }, | |
data () { | |
return { | |
domains | |
} | |
}, | |
template: ` | |
<div style="max-width: 1200px;"> | |
<VDomainCard view="list" v-for="domain in domains" :key="domain.id" :product="domain" domain="kekis" /> | |
</div> | |
` | |
}) | |
Standard.parameters = { | |
design: { | |
type: 'figma', | |
url: 'https://www.figma.com/file/3F0xMdYWmdcxVCpCRSh7lo/Components-Library-(Jino-%E2%80%A2-Shop)-(Beta)?node-id=3387%3A46430' | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<component | |
:is="selectedView" | |
:product="product" | |
:domain="domain" | |
:domainAvailabilityStatuses="domainAvailabilityStatuses" | |
/> | |
</template> | |
<script> | |
import { narrowViewportMatch, touchDeviceMatch } from '../../lib/env' | |
import VDomainCardBox from './components/VDomainCardBox' | |
import VDomainCardList from './components/VDomainCardList' | |
export default { | |
props: { | |
view: { | |
type: String, | |
default: 'box' | |
}, | |
product: { | |
type: Object, | |
default: () => ({}) | |
}, | |
domain: { | |
type: String, | |
default: null | |
}, | |
domainAvailabilityStatuses: { | |
type: Object, | |
default: () => ({}) | |
} | |
}, | |
data () { | |
return { | |
debounce: null, | |
showBox: false | |
} | |
}, | |
computed: { | |
selectedView () { | |
return this.view === 'box' || this.showBox ? VDomainCardBox : VDomainCardList | |
} | |
}, | |
mounted () { | |
window.addEventListener('resize', this.debounceGetViewportWidth) | |
}, | |
beforeDestroy () { | |
window.removeEventListener('resize', this.debounceGetViewportWidth) | |
}, | |
methods: { | |
setSelectedView () { | |
this.showBox = narrowViewportMatch().matches || touchDeviceMatch().matches | |
}, | |
debounceGetViewportWidth () { | |
clearTimeout(this.debounce) | |
this.debounce = setTimeout(() => this.setSelectedView(), 500) | |
} | |
} | |
} | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div :class="$style.DomainCardBox"> | |
<div :class="$style.DomainCardBox__badges"> | |
<div | |
v-if="product.discount" | |
:class="discountBadgeClassList" | |
> | |
−{{ product.discount }}% | |
</div> | |
<div | |
v-if="product.isCp" | |
:class="jinoDomainsBadgeClassList" | |
> | |
Джино • Домены | |
</div> | |
<div | |
v-if="product.promocodeDiscountPercent" | |
:class="promocodeDiscountBadgeClassList" | |
> | |
−{{ product.promocodeDiscountPercent }}% | |
</div> | |
</div> | |
<div :class="$style.DomainCardBox__prices"> | |
<div | |
:class="$style.DomainCardBox__mobilePrice" | |
v-if="isMobile && product.checked" | |
> | |
<span>{{ price }} ₽</span> | |
<VIcon | |
:class="$style.DomainCardBox__mobilePriceIcon" | |
name="arrow-right" | |
size="s" | |
/> | |
</div> | |
<template v-else> | |
<span | |
:class="$style.DomainCardBox__oldPrice" | |
v-if="product.price" | |
> | |
{{ product.basePrice }} ₽ | |
</span> | |
<span | |
:class="$style.DomainCardBox__newPrice" | |
> | |
{{ price }} ₽ | |
</span> | |
</template> | |
</div> | |
<div :class="$style.DomainCardBox__status"> | |
<div | |
:class="circleClassList" | |
v-if="status" | |
/> | |
<VIcon | |
:class="$style.DomainCardBox__favorite" | |
:size="isMobile ? 'm' : 's'" | |
:name="product.favorite ? 'heart-filled' : 'heart'" | |
:data-name="product.favorite ? 'heart-filled' : 'heart'" | |
v-else | |
@click.native="toggleFavorite(product.id)" | |
/> | |
<span | |
:class="$style.DomainCardBox__textTaken" | |
v-if="status === 'failed'" | |
> | |
Домен занят | |
</span> | |
</div> | |
<VUniLink | |
v-bind="linkProps" | |
:class="[ | |
$style.DomainCardBox__domain, | |
{ [$style.DomainCardBox__domain_size_s]: domain } | |
]" | |
target="_blank" | |
> | |
<span | |
:class="$style.DomainCardBox__website" | |
v-if="domain" | |
> | |
{{ domain }} | |
</span> | |
<span :class="$style.DomainCardBox__dot">.</span> | |
<span :class="$style.DomainCardBox__name">{{ displayZone }}</span> | |
</VUniLink> | |
<button :class="$style.DomainCardBox__buy"> | |
Купить | |
</button> | |
</div> | |
</template> | |
<script> | |
import { narrowViewportMatch, touchDeviceMatch } from '../../../lib/env' | |
import VIcon from '../../VIcon' | |
import VUniLink from '../../VUniLink' | |
export default { | |
components: { | |
VIcon, | |
VUniLink | |
}, | |
props: { | |
product: { | |
type: Object, | |
default: () => ({}) | |
}, | |
domain: { | |
type: String, | |
default: null | |
}, | |
checked: { | |
type: Boolean, | |
default: false | |
}, | |
domainAvailabilityStatuses: { | |
type: Object, | |
default: () => ({}) | |
} | |
}, | |
computed: { | |
discountBadgeClassList () { | |
return [ | |
this.$style.DomainCardBox__badge, | |
this.$style.DomainCardBox__badge_color_green, | |
this.$style.DomainCardBox__badge_position_left | |
] | |
}, | |
jinoDomainsBadgeClassList () { | |
return [ | |
this.$style.DomainCardBox__badge, | |
this.$style.DomainCardBox__badge_color_red, | |
this.$style.DomainCardBox__badge_position_left | |
] | |
}, | |
promocodeDiscountBadgeClassList () { | |
return [ | |
this.$style.DomainCardBox__badge, | |
this.$style.DomainCardBox__badge_color_red, | |
this.$style.DomainCardBox__badge_position_right | |
] | |
}, | |
circleClassList () { | |
return [ | |
this.$style.DomainCardBox__circle, | |
{ [this.$style.DomainCardBox__circle_color_red]: this.status === 'failed' } | |
] | |
}, | |
isMobile () { | |
return narrowViewportMatch().matches || touchDeviceMatch().matches | |
}, | |
shouldShowBadge () { | |
return (this.product.discount && this.product.basePrice) || this.product.isCp | |
}, | |
displayZone () { | |
return this.product.zone.substr(1) | |
}, | |
status () { | |
const info = this.domainAvailabilityStatuses[this.domain] | |
if (!info) { return } | |
return info.status | |
}, | |
isUnavailable () { | |
return this.status === 'failed' | |
}, | |
buyButtonLabel () { | |
if (this.status === 'succeed') { return 'Купить' } | |
if (this.status === 'failed') { return 'Недоступен' } | |
return 'Подробнее' | |
}, | |
price () { | |
const { price, promocodePrice, basePrice } = this.product | |
return price || promocodePrice || basePrice | |
}, | |
linkProps () { | |
let postfix = '' | |
if (this.displayDomain) { | |
postfix = `?domain=${this.displayDomain}` | |
} | |
const link = {} | |
if (this.product.isCp) { | |
link.href = 'https://google.com' | |
} else { | |
link.to = `/catalog/domains/${this.product.zone}/${postfix}` | |
} | |
/* if (this.product.isCp) { | |
link.href = `${this.$env.JINOSITE_URL}/domains/price/.${this.displayZone}/${postfix}` | |
} else { | |
link.to = `/catalog/domains/${this.product.zone}/${postfix}` | |
} */ | |
return link | |
} | |
}, | |
methods: { | |
toggleFavorite (id) { | |
this.$emit('toggleFavorite', id) | |
} | |
} | |
} | |
</script> | |
<style lang="scss" module> | |
@import "~/assets/scss/variables"; | |
.DomainCardBox { | |
box-sizing: border-box; | |
background: #fff; | |
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.08); | |
border-radius: 12px; | |
position: relative; | |
overflow: hidden; | |
max-width: 320px; | |
min-width: 250px; | |
display: grid; | |
padding: 12px 12px 12px 16px; | |
grid-template-rows: 28px 22px 28px; | |
height: 96px; | |
margin-bottom: 24px; | |
} | |
.DomainCardBox__badges { | |
position: absolute; | |
top: 0; | |
left: 0; | |
display: flex; | |
} | |
.DomainCardBox__badge { | |
padding: 4px 8px; | |
font-size: $text-12; | |
line-height: $text-16; | |
text-align: center; | |
font-weight: 400; | |
} | |
.DomainCardBox__badge_color_green { | |
color: $secondary-green; | |
background-color: $tertiary-green-light; | |
} | |
.DomainCardBox__badge_color_red { | |
color: $primary; | |
background-color: $tertiary-red-light; | |
} | |
.DomainCardBox__badge_position_left { | |
border-radius: 12px 0; | |
margin-right: 2px; | |
} | |
.DomainCardBox__badge_position_right { | |
border-radius: 0 0 12px 12px; | |
} | |
.DomainCardBox__circle { | |
--bg-color: #{$secondary-green}; | |
width: 10px; | |
height: 10px; | |
border-radius: 50%; | |
background-color: var(--bg-color); | |
} | |
.DomainCardBox__circle_color_red { | |
--bg-color: #{$text-negative}; | |
} | |
.DomainCardBox__prices { | |
justify-self: end; | |
display: flex; | |
align-items: flex-start; | |
transition: opacity 0.3s $animation-timing; | |
} | |
.DomainCardBox__oldPrice { | |
text-decoration-line: line-through; | |
font-size: $text-18; | |
font-weight: 700; | |
color: $text-03; | |
line-height: $text-24; | |
margin-right: 4px; | |
} | |
.DomainCardBox__newPrice { | |
font-size: $text-24; | |
line-height: $text-28; | |
font-weight: 700; | |
font-family: 'PT Sans Caption', sans-serif; | |
color: $text-01; | |
} | |
.DomainCardBox__status { | |
font-size: $text-12; | |
height: 13px; | |
display: flex; | |
align-items: center; | |
} | |
.DomainCardBox__textTaken { | |
color: $text-negative; | |
font-size: $text-12; | |
line-height: 16px; | |
text-transform: uppercase; | |
margin-left: 4px; | |
} | |
.DomainCardBox__domain { | |
display: flex; | |
align-items: flex-end; | |
font-weight: bold; | |
font-size: $text-20; | |
line-height: 28px; | |
position: relative; | |
text-decoration: none; | |
max-width: 100%; | |
overflow: hidden; | |
&::before { | |
content: ""; | |
position: absolute; | |
width: calc(100% + 24px); | |
height: 96px; | |
bottom: -8px; | |
left: -16px; | |
} | |
} | |
.DomainCardBox__website { | |
color: $text-02; | |
} | |
.DomainCardBox__dot { | |
color: $primary; | |
font-size: $text-24; | |
} | |
.DomainCardBox__name { | |
color: $text-01; | |
} | |
.DomainCardBox__favorite { | |
--fill: #{$base-04}; | |
cursor: pointer; | |
position: relative; | |
z-index: 10; | |
&[data-name="heart-filled"] { | |
--fill: #{$base-05}; | |
} | |
&:hover { | |
--fill: #{$base-05}; | |
} | |
} | |
.DomainCardBox__buy { | |
box-sizing: border-box; | |
position: absolute; | |
border: 0; | |
padding: 0; | |
z-index: 10; | |
right: 0; | |
top: 0; | |
bottom: 0; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
width: 96px; | |
height: 96px; | |
background-color: $secondary-green; | |
color: #fff; | |
cursor: pointer; | |
transform: translate3d(100px, 0, 0); | |
transition: transform 0.3s $animation-timing; | |
&:focus, | |
&:active { | |
outline: 0; | |
} | |
} | |
.DomainCardBox:hover { | |
.DomainCardBox__buy { | |
transform: translate3d(0, 0, 0); | |
} | |
.DomainCardBox__prices { | |
opacity: 0; | |
} | |
} | |
@media (max-width: 878px) { | |
.DomainCardBox { | |
padding: 8px 8px 8px 16px; | |
height: 80px; | |
grid-template-rows: 30px 10px 28px; | |
&:hover { | |
.DomainCardBox__buy { | |
transform: translate3d(100px, 0, 0); | |
} | |
.DomainCardBox__prices { | |
opacity: 1; | |
} | |
} | |
} | |
.DomainCardBox__domain { | |
font-size: $text-24; | |
&::before { | |
height: 80px; | |
} | |
} | |
.DomainCardBox__newPrice { | |
font-size: $text-20; | |
} | |
.DomainCardBox__domain_size_s { | |
font-size: $text-16; | |
} | |
.DomainCardBox__dot { | |
transform: translateY(-1px); | |
} | |
.DomainCardBox__favorite { | |
position: absolute; | |
bottom: 6px; | |
right: 8px; | |
z-index: 5; | |
} | |
.DomainCardBox__mobilePrice { | |
display: flex; | |
align-items: center; | |
font-size: $text-14; | |
line-height: 20px; | |
background: $secondary-green; | |
border-radius: 12px; | |
color: #fff; | |
padding: 6px 14px 6px 16px; | |
&Icon { | |
--fill: #fff; | |
margin-left: 6px; | |
} | |
} | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment