@viur/shop-components 0.0.1-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +54 -0
- package/src/App.vue +30 -0
- package/src/components/cart/BasketView.vue +569 -0
- package/src/components/order/category/CategoryList.vue +83 -0
- package/src/components/order/category/CategoryView.vue +103 -0
- package/src/components/order/item/ItemCard.vue +182 -0
- package/src/components/order/item/ItemView.vue +233 -0
- package/src/index.html +13 -0
- package/src/index.js +4 -0
- package/src/main.js +9 -0
- package/src/router/index.js +93 -0
- package/src/shoelaceConfig.js +54 -0
- package/src/stores/cart.js +98 -0
- package/src/style.css +79 -0
- package/src/views/ViewMissing.vue +20 -0
- package/vite.config.js +23 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<RouterLink :to="{ name: 'CategoryView', params: { identifier: 'dk' } }"
|
|
3
|
+
v-for="item in list"
|
|
4
|
+
:key="item"
|
|
5
|
+
class="item-link"
|
|
6
|
+
>
|
|
7
|
+
<sl-card class="item">
|
|
8
|
+
<img
|
|
9
|
+
slot="image"
|
|
10
|
+
src="https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80"
|
|
11
|
+
alt="A kitten."
|
|
12
|
+
class="item-img"
|
|
13
|
+
/>
|
|
14
|
+
<h2 class="item-headline"> {{ item }}</h2>
|
|
15
|
+
<div class="fake-link">Alle anzeigen »</div>
|
|
16
|
+
|
|
17
|
+
</sl-card>
|
|
18
|
+
</RouterLink>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script setup>
|
|
22
|
+
import { onBeforeMount } from "vue";
|
|
23
|
+
import ItemCard from "../item/ItemCard.vue";
|
|
24
|
+
import { useCartStore } from "../../../stores/cart";
|
|
25
|
+
|
|
26
|
+
const cartStore = useCartStore();
|
|
27
|
+
const props = defineProps({
|
|
28
|
+
list: { type: Array, required: true },
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
onBeforeMount(async () => {
|
|
32
|
+
// cartStore.init();
|
|
33
|
+
});
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<style scoped>
|
|
37
|
+
|
|
38
|
+
.item-link{
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
width: 100%;
|
|
42
|
+
|
|
43
|
+
&:hover{
|
|
44
|
+
.fake-link{
|
|
45
|
+
text-decoration: underline;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.item-img{
|
|
49
|
+
transform: scale(1.02);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.item{
|
|
55
|
+
width: 100%;
|
|
56
|
+
|
|
57
|
+
&::part(header){
|
|
58
|
+
padding: var(--sl-spacing-medium) 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&::part(body){
|
|
62
|
+
padding: var(--sl-spacing-medium) 0;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
&::part(footer){
|
|
66
|
+
padding: var(--sl-spacing-medium) 0;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.item-headline{
|
|
71
|
+
font-size: 1.4em;
|
|
72
|
+
margin-bottom: var(--sl-spacing-medium);
|
|
73
|
+
color: var(--ignt-basic-color-text);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.item-img{
|
|
77
|
+
aspect-ratio: 1;
|
|
78
|
+
object-fit: cover;
|
|
79
|
+
transition: all ease .3s;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
</style>
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="item-list">
|
|
3
|
+
<router-link
|
|
4
|
+
v-for="item in state.skellist"
|
|
5
|
+
:key="item.shop_name"
|
|
6
|
+
:to="{ name: 'itemView', params: { item: item.key } }"
|
|
7
|
+
>
|
|
8
|
+
<ItemCard :item="item"> </ItemCard>
|
|
9
|
+
</router-link>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<sl-button
|
|
13
|
+
@click="loadMore"
|
|
14
|
+
:loading="state.loading"
|
|
15
|
+
:disabled="state.isLastItem"
|
|
16
|
+
>
|
|
17
|
+
Mehr anzeigen
|
|
18
|
+
</sl-button>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script setup>
|
|
22
|
+
import { onMounted, reactive, computed } from "vue";
|
|
23
|
+
import { useCartStore } from "../../../stores/cart";
|
|
24
|
+
import { useRoute } from "vue-router";
|
|
25
|
+
import { Request, ListRequest } from "@viur/vue-utils";
|
|
26
|
+
// import { ViURShopClient } from "@viur/viur-shop-client";
|
|
27
|
+
|
|
28
|
+
// component imports
|
|
29
|
+
import ItemCard from "../item/ItemCard.vue";
|
|
30
|
+
|
|
31
|
+
const route = useRoute();
|
|
32
|
+
|
|
33
|
+
const cartStore = useCartStore();
|
|
34
|
+
|
|
35
|
+
const state = reactive({
|
|
36
|
+
skellist: [],
|
|
37
|
+
loading: true,
|
|
38
|
+
currentCursor: "",
|
|
39
|
+
isLastItem: false,
|
|
40
|
+
itemCount: 99,
|
|
41
|
+
itemType: computed(() => route.params.identifier),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const categoryList = ListRequest("categorystore", {
|
|
45
|
+
module: "variante",
|
|
46
|
+
params: { type: state.itemType, limit: state.itemCount },
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
function listItems() {
|
|
50
|
+
let params = {
|
|
51
|
+
limit: state.itemCount,
|
|
52
|
+
cursor: state.currentCursor,
|
|
53
|
+
type: state.itemType,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
state.loading = true;
|
|
57
|
+
|
|
58
|
+
Request.get("/json/variante/list", { dataObj: params }).then(async (resp) => {
|
|
59
|
+
let data = await resp.json();
|
|
60
|
+
|
|
61
|
+
if (data.cursor !== state.currentCursor && !state.isLastItem) {
|
|
62
|
+
state.currentCursor = data.cursor;
|
|
63
|
+
state.skellist.push(...data.skellist);
|
|
64
|
+
state.loading = false;
|
|
65
|
+
} else if (data.cursor === state.currentCursor) {
|
|
66
|
+
state.isLastItem = true;
|
|
67
|
+
state.loading = false;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log("hier", data);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function loadMore() {
|
|
75
|
+
state.loading = true;
|
|
76
|
+
await categoryList.next();
|
|
77
|
+
|
|
78
|
+
if (state.skellist.length < categoryList.state.skellist.length) {
|
|
79
|
+
state.skellist = categoryList.state.skellist;
|
|
80
|
+
state.loading = false;
|
|
81
|
+
} else {
|
|
82
|
+
state.loading = false;
|
|
83
|
+
state.isLastItem = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
onMounted(async () => {
|
|
88
|
+
await categoryList.fetch(true);
|
|
89
|
+
state.skellist = categoryList.state.skellist;
|
|
90
|
+
state.loading = false;
|
|
91
|
+
|
|
92
|
+
// await cartStore.init();
|
|
93
|
+
});
|
|
94
|
+
</script>
|
|
95
|
+
|
|
96
|
+
<style scoped>
|
|
97
|
+
.item-list {
|
|
98
|
+
display: grid;
|
|
99
|
+
width: 100%;
|
|
100
|
+
grid-gap: var(--sl-spacing-medium);
|
|
101
|
+
grid-template-columns: repeat(4, 1fr);
|
|
102
|
+
}
|
|
103
|
+
</style>
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<sl-card class="card">
|
|
3
|
+
<img
|
|
4
|
+
slot="image"
|
|
5
|
+
:src="getImage(item)"
|
|
6
|
+
:alt="item.shop_name"
|
|
7
|
+
class="card-image"
|
|
8
|
+
/>
|
|
9
|
+
<h3 class="card-headline"> {{ item.shop_name }}</h3>
|
|
10
|
+
<h4 class="card-subline">B 21 x H 6,5 x T 19 cm</h4>
|
|
11
|
+
<div class="price">
|
|
12
|
+
{{ item.shop_price_retail }} €
|
|
13
|
+
</div>
|
|
14
|
+
<div class="card-footer" slot="footer">
|
|
15
|
+
<!-- <sl-button-group label="Amount">
|
|
16
|
+
<sl-tooltip content="Remove">
|
|
17
|
+
<sl-icon-button
|
|
18
|
+
variant="primary"
|
|
19
|
+
name="cart-dash"
|
|
20
|
+
label="Remove Amount"
|
|
21
|
+
style="font-size: 2em"
|
|
22
|
+
>
|
|
23
|
+
</sl-icon-button>
|
|
24
|
+
</sl-tooltip>
|
|
25
|
+
<sl-tooltip content="Plus">
|
|
26
|
+
<sl-icon-button
|
|
27
|
+
variant="primary"
|
|
28
|
+
name="cart-plus"
|
|
29
|
+
label="Add Amount"
|
|
30
|
+
style="font-size: 2em"
|
|
31
|
+
>
|
|
32
|
+
</sl-icon-button>
|
|
33
|
+
</sl-tooltip>
|
|
34
|
+
<sl-tooltip content="Add to cart">
|
|
35
|
+
<sl-icon-button
|
|
36
|
+
variant="primary"
|
|
37
|
+
name="cart-check"
|
|
38
|
+
label="Add to cart"
|
|
39
|
+
style="font-size: 2em"
|
|
40
|
+
@click="
|
|
41
|
+
cartStore.addToCart(item.key, cartStore.state.currentCart)
|
|
42
|
+
"
|
|
43
|
+
>
|
|
44
|
+
</sl-icon-button>
|
|
45
|
+
</sl-tooltip>
|
|
46
|
+
</sl-button-group> -->
|
|
47
|
+
<sl-button
|
|
48
|
+
size="small"
|
|
49
|
+
class="add-to-cart-btn"
|
|
50
|
+
variant="primary"
|
|
51
|
+
title="Add to cart"
|
|
52
|
+
@click.stop="cartStore.addToCart(item.key, cartStore.state.currentCart)"
|
|
53
|
+
>
|
|
54
|
+
<sl-icon name="bag-plus"
|
|
55
|
+
slot="prefix"
|
|
56
|
+
></sl-icon>
|
|
57
|
+
|
|
58
|
+
In den Warenkorb
|
|
59
|
+
</sl-button>
|
|
60
|
+
|
|
61
|
+
<sl-button
|
|
62
|
+
size="small"
|
|
63
|
+
outline
|
|
64
|
+
class="add-to-favourites-btn"
|
|
65
|
+
variant="primary"
|
|
66
|
+
title="Add to favourites"
|
|
67
|
+
>
|
|
68
|
+
<sl-icon name="heart"
|
|
69
|
+
slot="prefix"
|
|
70
|
+
></sl-icon>
|
|
71
|
+
</sl-button>
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
</div>
|
|
75
|
+
</sl-card>
|
|
76
|
+
</template>
|
|
77
|
+
|
|
78
|
+
<script>
|
|
79
|
+
import {Request} from "@viur/vue-utils";
|
|
80
|
+
|
|
81
|
+
export default {
|
|
82
|
+
props: {
|
|
83
|
+
item: {
|
|
84
|
+
type: Object,
|
|
85
|
+
required: true
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
setup(props, context) {
|
|
89
|
+
|
|
90
|
+
function getImage(item) {
|
|
91
|
+
let imageUrl =
|
|
92
|
+
"https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80";
|
|
93
|
+
if (item.dk_artikel.dest.image) {
|
|
94
|
+
return Request.downloadUrlFor(item.dk_artikel.dest.image);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return imageUrl;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
props,
|
|
102
|
+
getImage
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
</script>
|
|
107
|
+
|
|
108
|
+
<style scoped>
|
|
109
|
+
.card {
|
|
110
|
+
width: 100%;
|
|
111
|
+
|
|
112
|
+
&::part(header){
|
|
113
|
+
padding: var(--sl-spacing-medium) 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
&::part(body){
|
|
117
|
+
padding: var(--sl-spacing-medium) 0;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
&::part(footer){
|
|
121
|
+
padding: var(--sl-spacing-medium) 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
&:hover{
|
|
125
|
+
.add-to-cart-btn{
|
|
126
|
+
opacity: 1;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.card-headline{
|
|
130
|
+
color: var(--sl-color-primary-500)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.card-image{
|
|
134
|
+
transform: scale(1.02);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.card-footer{
|
|
140
|
+
display: flex;
|
|
141
|
+
flex-direction: row;
|
|
142
|
+
align-items: center;
|
|
143
|
+
width: 100%;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.add-to-cart-btn{
|
|
147
|
+
transition: all ease .3s;
|
|
148
|
+
margin-right: var(--sl-spacing-medium);
|
|
149
|
+
opacity: 0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.add-to-favourites-btn{
|
|
153
|
+
margin-left: auto;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
.card-image {
|
|
158
|
+
aspect-ratio: 1;
|
|
159
|
+
object-fit: cover;
|
|
160
|
+
transition: all ease .3s;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.card-headline{
|
|
164
|
+
font-size: 1.1em;
|
|
165
|
+
font-weight: bold;
|
|
166
|
+
color: var(--ignt-basic-color-text);
|
|
167
|
+
margin-bottom: var(--sl-spacing-2x-small);
|
|
168
|
+
transition: all ease .3s;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.card-subline{
|
|
172
|
+
color: var(--ignt-basic-color-text);
|
|
173
|
+
margin-bottom: var(--sl-spacing-2x-small);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.price{
|
|
177
|
+
font-size: 1.1em;
|
|
178
|
+
font-weight: bold;
|
|
179
|
+
color: var(--ignt-basic-color-text);
|
|
180
|
+
margin-left: auto;
|
|
181
|
+
}
|
|
182
|
+
</style>
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="wrap">
|
|
3
|
+
<div class="image-wrap">
|
|
4
|
+
<sl-carousel class="carousel-thumbnails" navigation loop>
|
|
5
|
+
<sl-carousel-item>
|
|
6
|
+
<img
|
|
7
|
+
:alt="state.item.shop_name"
|
|
8
|
+
:src="getImage(state.item)"
|
|
9
|
+
/>
|
|
10
|
+
</sl-carousel-item>
|
|
11
|
+
</sl-carousel>
|
|
12
|
+
|
|
13
|
+
<div class="thumbnails">
|
|
14
|
+
<div class="thumbnails__scroller">
|
|
15
|
+
<img :alt="state.item.shop_name"
|
|
16
|
+
class="thumbnails__image active"
|
|
17
|
+
:src="getImage(state.item)" />
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div class="info-wrap">
|
|
23
|
+
<h1 class="headline">{{ state.item.shop_name }}</h1>
|
|
24
|
+
<h2 class="subline">B 21 x H 6,5 x T 19 cm</h2>
|
|
25
|
+
|
|
26
|
+
<div class="price">
|
|
27
|
+
{{ state.item.shop_price_retail }} €
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div class="paragraph">
|
|
31
|
+
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
|
|
32
|
+
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
|
|
33
|
+
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
|
|
34
|
+
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
|
|
35
|
+
amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
|
|
36
|
+
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
|
|
37
|
+
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd
|
|
38
|
+
gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div class="btn-wrap">
|
|
42
|
+
<sl-button
|
|
43
|
+
size="small"
|
|
44
|
+
class="add-to-cart-btn"
|
|
45
|
+
variant="primary"
|
|
46
|
+
title="Add to cart"
|
|
47
|
+
@click.stop="cartStore.addToCart(item.key, cartStore.state.currentCart)"
|
|
48
|
+
>
|
|
49
|
+
<sl-icon name="bag-plus"
|
|
50
|
+
slot="prefix"
|
|
51
|
+
></sl-icon>
|
|
52
|
+
|
|
53
|
+
In den Warenkorb
|
|
54
|
+
</sl-button>
|
|
55
|
+
|
|
56
|
+
<sl-button
|
|
57
|
+
size="small"
|
|
58
|
+
outline
|
|
59
|
+
class="add-to-favourites-btn"
|
|
60
|
+
variant="primary"
|
|
61
|
+
title="Add to favourites"
|
|
62
|
+
>
|
|
63
|
+
<sl-icon name="heart"
|
|
64
|
+
slot="prefix"
|
|
65
|
+
></sl-icon>
|
|
66
|
+
Auf die Wunschliste
|
|
67
|
+
</sl-button>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
</div>
|
|
72
|
+
<br>
|
|
73
|
+
<h1 class="headline">Ähnliche Artikel</h1>
|
|
74
|
+
<div class="item-grid">
|
|
75
|
+
<ItemCard :item="state.item">
|
|
76
|
+
</ItemCard>
|
|
77
|
+
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
</template>
|
|
81
|
+
|
|
82
|
+
<script setup>
|
|
83
|
+
import { computed, onBeforeMount, reactive } from "vue";
|
|
84
|
+
import { Request } from "@viur/vue-utils";
|
|
85
|
+
import { useRoute } from "vue-router";
|
|
86
|
+
// component imports
|
|
87
|
+
import ItemCard from "../item/ItemCard.vue";
|
|
88
|
+
import '@viur/shoelace/dist/components/carousel/carousel.js';
|
|
89
|
+
|
|
90
|
+
const route = useRoute();
|
|
91
|
+
|
|
92
|
+
const state = reactive({
|
|
93
|
+
item: {},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
function getImage(item) {
|
|
97
|
+
console.log("hier", item.dk_artikel);
|
|
98
|
+
let imageUrl =
|
|
99
|
+
"https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80";
|
|
100
|
+
if (item?.dk_artikel.dest.image) {
|
|
101
|
+
return Request.downloadUrlFor(item.dk_artikel.dest.image);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return imageUrl;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
onBeforeMount(async () => {
|
|
108
|
+
Request.get(`/json/variante/view/${route.params.item}`).then(async (resp) => {
|
|
109
|
+
let data = await resp.json();
|
|
110
|
+
|
|
111
|
+
state.item = data.values;
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
</script>
|
|
115
|
+
|
|
116
|
+
<style scoped>
|
|
117
|
+
.wrap{
|
|
118
|
+
display: grid;
|
|
119
|
+
grid-template-columns: 45% minmax(0 ,1fr);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.info-wrap{
|
|
123
|
+
padding: var(--sl-spacing-x-large);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.image-wrap{
|
|
127
|
+
display: flex;
|
|
128
|
+
flex-direction: column;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
sl-carousel{
|
|
132
|
+
aspect-ratio: 1;
|
|
133
|
+
background-color: var(--sl-color-neutral-200);
|
|
134
|
+
|
|
135
|
+
&::part(base){
|
|
136
|
+
display: flex;
|
|
137
|
+
gap: 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
&::part(scroll-container){
|
|
141
|
+
border-radius: 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
&::part(navigation-button){
|
|
145
|
+
position: absolute;
|
|
146
|
+
background-color: color-mix(in hsl, var(--sl-color-neutral-0) 85%, transparent);
|
|
147
|
+
color: var(--app-primary-color);
|
|
148
|
+
border-radius: 0;
|
|
149
|
+
transition: all ease.3s;
|
|
150
|
+
opacity: 0;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
&::part(navigation-button--previous){
|
|
154
|
+
left: 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
&::part(navigation-button--next){
|
|
158
|
+
right: 0;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
&:hover{
|
|
162
|
+
&::part(navigation-button){
|
|
163
|
+
opacity: 1;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
.thumbnails {
|
|
168
|
+
display: flex;
|
|
169
|
+
justify-content: start;
|
|
170
|
+
margin-top: vaR(--sl-spacing-medium)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.thumbnails__scroller {
|
|
174
|
+
display: flex;
|
|
175
|
+
gap: var(--sl-spacing-small);
|
|
176
|
+
overflow-x: auto;
|
|
177
|
+
scrollbar-width: none;
|
|
178
|
+
scroll-behavior: smooth;
|
|
179
|
+
scroll-padding: var(--sl-spacing-small);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.thumbnails__scroller::-webkit-scrollbar {
|
|
183
|
+
display: none;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.thumbnails__image {
|
|
187
|
+
width: 64px;
|
|
188
|
+
height: 64px;
|
|
189
|
+
object-fit: cover;
|
|
190
|
+
|
|
191
|
+
opacity: 0.3;
|
|
192
|
+
will-change: opacity;
|
|
193
|
+
transition: 250ms opacity;
|
|
194
|
+
|
|
195
|
+
cursor: pointer;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.thumbnails__image.active {
|
|
199
|
+
opacity: 1;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.headline{
|
|
203
|
+
margin-bottom: var(--sl-spacing-small);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.subline{
|
|
207
|
+
margin-bottom: var(--sl-spacing-small);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.price{
|
|
211
|
+
font-size: 1.4em;
|
|
212
|
+
margin-bottom: var(--sl-spacing-small);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.paragraph{
|
|
216
|
+
margin-bottom: var(--sl-spacing-x-large);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.btn-wrap{
|
|
220
|
+
display: flex;
|
|
221
|
+
flex-direction: column;
|
|
222
|
+
|
|
223
|
+
sl-button{
|
|
224
|
+
margin-bottom: var(--sl-spacing-x-small);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.item-grid{
|
|
229
|
+
display: grid;
|
|
230
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
231
|
+
grid-gap: var(--sl-spacing-medium);
|
|
232
|
+
}
|
|
233
|
+
</style>
|
package/src/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Vite + Vue</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/src/main.js"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/src/index.js
ADDED