Compare commits
10 Commits
2d4cb1c44e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 93f91a4b16 | |||
| a1d1a64aac | |||
| 4319ffef03 | |||
| 6540381f1f | |||
| 91a3cdcd06 | |||
| 03a0ab0029 | |||
| 5f194e862f | |||
| 12318caaba | |||
| b2184df074 | |||
| f6294ce0b0 |
27
README.md
27
README.md
@@ -22,7 +22,7 @@ Można użyć extends w innym miejscu (np tym razem w wydzielonym JS) żeby nadp
|
||||
|
||||
**Przykład**
|
||||
```
|
||||
class IdmRaypathHotspot extends IdmHotspot {
|
||||
IdmHotspot = class extends IdmHotspot {
|
||||
markupLabel(prod) {
|
||||
// Standardowe labelki
|
||||
let labelMarkup = super.markupLabel(prod);
|
||||
@@ -59,6 +59,7 @@ Warto gdzieś później zapisać nową nazwę klasy np w opisie komponentu, albo
|
||||
- Nie znaleziono metody graphql
|
||||
- Najniższa cena
|
||||
- Drugie Zdjęcie
|
||||
- Wystąpił błąd w trakcie dodawania produktu
|
||||
|
||||
### Przykłady UŻYCIA ###
|
||||
##### Jedna ramka - obiekt ######
|
||||
@@ -72,6 +73,9 @@ new IdmHotspot({
|
||||
},
|
||||
source: {
|
||||
productsMenu: 1649
|
||||
},
|
||||
options:{
|
||||
callbackFn: (hotspot)=>{console.log(hotspot)},
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -93,6 +97,7 @@ new IdmHotspot({
|
||||
|
||||
|
||||
* @property {object} source - Dane źródłowe dla hotspotu.
|
||||
* @property {string} [source.link] - link do listingu z którego mają być pobierane produkty (NIEZALECANE)(Reszta opcji source nie zadziała!!)
|
||||
* @property {string} [source.hotspotType] - Typ hotspotu (np. "promotion").
|
||||
* @property {number[]} [source.productsId] - Tablica ID produktów.
|
||||
* @property {number} [source.productsMenu] - Identyfikator menu produktów.
|
||||
@@ -110,13 +115,18 @@ new IdmHotspot({
|
||||
|
||||
|
||||
* @property {object} options - Ustawienia dla hotspotu (required).
|
||||
* @property {boolean} [options.limit] - Limit wczytywanych produktów
|
||||
* @property {boolean} [options.lazy] - Czy wczytywać w trybie lazy.
|
||||
* @property {boolean} [options.devMode] - Czy wczytywać ramki tylko dla stron z dev=true.
|
||||
* @property {boolean} [options.omnibusTooltip] - Czy wyświetlać omnibusa w formie tooltip
|
||||
* @property {Function} [options.callbackFn] - Funkcja callback która dzieje się po wywołaniu wszystkiego włącznie ze swiperem
|
||||
* Funkcja callback wywoływana po pełnej inicjalizacji hotspotu (łącznie ze Swiperem).
|
||||
* Jako argument przekazywana jest instancja klasy `IdmHotspot`.
|
||||
|
||||
|
||||
* @property {boolean} [options.addToFavorites] - Czy włączać dodawanie do ulubionych(DZIAŁA TYLKO PO ZMIANACH SZABLONOWYCH)
|
||||
* @property {boolean} [options.addToCompare] - Czy włączać dodawanie do porównywania
|
||||
|
||||
* @property {boolean|string} [options.addToBasket] - Obsługa koszyka:
|
||||
* - true = włącz
|
||||
* - false = wyłącz
|
||||
@@ -127,14 +137,24 @@ new IdmHotspot({
|
||||
* - false = nieaktywny
|
||||
* - object = konfiguracja Swiper
|
||||
* @property {boolean} [options.swiperScrollbar] - Czy włączać scrollbar w swiperze - DO DZIAŁANIA WYMAGA WŁĄCZONEGO SWIPERA
|
||||
|
||||
* @property {boolean} [options.showOpinions] - Czy wyświetlać opinie o produkcie w formie gwiazdek nad nazwą
|
||||
* @property {boolean} [options.showSecondImage] - Czy wyświetlać drugie zdjęcie na hover
|
||||
|
||||
* @property {boolean} [options.selectVersion] - Pokazywanie multiwersji
|
||||
*
|
||||
* @property {object} cssVariables - Obiekt z opcjami zmiennych CSS wgrywanymi do danej ramki rekomendacji
|
||||
* @property {object} [cssVariables.version] - Obiekt ze zmiennymi css dla wersji
|
||||
* @property {number} [cssVariables.version.columnDesktop] - liczba kolumn wersji na desktop
|
||||
* @property {number} [cssVariables.version.columnTablet] - liczba kolumn wersji na tablecie
|
||||
* @property {number} [cssVariables.version.columnMobile] - liczba kolumn wersji na mobile
|
||||
* @property {number} [cssVariables.nameClamp] - liczba wyświetlanych linijek tekstu nazwy produktu
|
||||
|
||||
|
||||
* @type {Hotspot[]}
|
||||
*/
|
||||
```
|
||||
|
||||
|
||||
###### Jedna ramka - HTML ######
|
||||
```
|
||||
<section id="idmBlogHotspot1"
|
||||
@@ -142,7 +162,7 @@ new IdmHotspot({
|
||||
data-products-id="589,180,181590"
|
||||
data-lazy="true"
|
||||
>
|
||||
<div class="hotspot --initialized">
|
||||
<div class="hotspot">
|
||||
<h3 class="hotspot__name headline__wrapper">
|
||||
<span class="headline">
|
||||
<span class="headline__name" aria-label="aaa">aaa</span>
|
||||
@@ -162,6 +182,7 @@ new IdmHotspot({
|
||||
* @property {string} id - Identyfikator elementu (np. "idmBlogHotspot1").
|
||||
* @property {string} class - Klasy CSS używane do stylowania.
|
||||
*
|
||||
* @attribute {string} data-link - link do listingu z którego mają być pobierane produkty (NIEZALECANE)
|
||||
* @attribute {string} data-hotspots-type - Typ hotspotu (np. "promotion").
|
||||
* @attribute {number[]} data-products-id - Lista ID produktów (rozdzielona przecinkami).
|
||||
* @attribute {number} data-products-menu - Identyfikator menu produktów.
|
||||
|
||||
24
extends.js
Normal file
24
extends.js
Normal file
@@ -0,0 +1,24 @@
|
||||
IdmHotspot = class extends IdmHotspot {
|
||||
markupLabel(prod) {
|
||||
// Standardowe labelki
|
||||
let labelMarkup = super.markupLabel(prod);
|
||||
|
||||
// Customowe labelki
|
||||
const awards = prod?.awardedParameters;
|
||||
if (awards?.length) {
|
||||
const awardParam = awards.find(award => award.name === "Idm_custom_label");
|
||||
const values = awardParam?.values?.map(v => v.name) || [];
|
||||
|
||||
const html = values
|
||||
.map(label => {
|
||||
const [text, bgColor, color] = label.split("||");
|
||||
return `<span class="label --custom" style="background-color:${bgColor}; color:${color}">${text}</span>`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
labelMarkup += html;
|
||||
}
|
||||
|
||||
return labelMarkup;
|
||||
}
|
||||
}
|
||||
15
ramka.txt
15
ramka.txt
@@ -1,8 +1,11 @@
|
||||
1. Ramka
|
||||
|
||||
- wybór rozmiaru/wersji??
|
||||
bugi selectSize + addToBasket="range"
|
||||
|
||||
- wybór rozmiaru/wersji?? Wykluczenie powtarzających się wersji
|
||||
wersja max 5 zdjęć i później + może????
|
||||
|
||||
|
||||
- zakres cen?????????????
|
||||
- Wybór kolorystyczny???
|
||||
- AAAAA - banner na hotspocie
|
||||
@@ -12,9 +15,17 @@ wersja max 5 zdjęć i później + może????
|
||||
- czy zapisywać wszystkie hotspoty do jakiegoś app_shop.fn.idmHotspots = {"#idmMainHotspot1": {}}
|
||||
- czy jakoś inteligentnie ucinać niepotrzebne query na podstawie wybranych opcji? chyba za dużo roboty i nie ma sensu
|
||||
|
||||
|
||||
- dodawanie do koszyka zestawów itp??
|
||||
- własne klasy
|
||||
|
||||
Stara ramka
|
||||
- getProductXML=t
|
||||
- slick
|
||||
|
||||
cacheowanie ramek do indexedDB
|
||||
|
||||
awaitowanie idmHotspot
|
||||
|
||||
fix cssVariables jak nie ma wesji
|
||||
|
||||
zapisywanie querySelectorów produktów
|
||||
226
style.less
226
style.less
@@ -1,6 +1,15 @@
|
||||
.idm__hotspot .add_to_basket{
|
||||
/* add to basket*/
|
||||
.idm__hotspot .add_to_basket, .idm__hotspot .add_to_basket__link{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
@media (max-width: 978px){
|
||||
.idm__hotspot .add_to_basket__button.btn:not(.--error):not(.--success)::before{
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
|
||||
.idm__hotspot .add_to_basket.--range{
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -27,27 +36,74 @@
|
||||
border-radius: 0.5rem;
|
||||
min-width: 3rem;
|
||||
}
|
||||
@keyframes idm-skeleton-loading {
|
||||
|
||||
/* SKELETON */
|
||||
@keyframes idm-skeleton-loading {
|
||||
to {
|
||||
background-position-x: -200%;
|
||||
}
|
||||
}
|
||||
.idm__hotspot.idm-loading{
|
||||
}
|
||||
|
||||
.skeleton(@width, @height, @mobileWidth, @mobileHeight, @borderRadius) {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&.idm-loading {
|
||||
transition: none;
|
||||
border-radius: 8px;
|
||||
border-radius: @borderRadius;
|
||||
background: #eee;
|
||||
background: linear-gradient(110deg, #ececec 8%, #f5f5f5 18%, #ececec 33%);
|
||||
background-size: 200% 100%;
|
||||
animation: 1.5s idm-skeleton-loading linear infinite;
|
||||
width: 100%;
|
||||
height: 50rem;
|
||||
width: @width;
|
||||
height: @height;
|
||||
|
||||
@media (max-width: 756px) {
|
||||
width: @mobileWidth;
|
||||
height: @mobileHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
.idm__hotspot.idm-loading .hotspot{
|
||||
opacity: 0;
|
||||
|
||||
.--hotspot-loading .products.hotspot__products.swiper-wrapper{
|
||||
display: block!important;
|
||||
}
|
||||
|
||||
.idm_hotspot__skeleton{
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
overflow: hidden;
|
||||
min-height: 30rem;
|
||||
&_product{
|
||||
flex-shrink: 0;
|
||||
padding-right: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
&_img{
|
||||
aspect-ratio: ~"1 / 1";
|
||||
margin-bottom: 2.5rem;
|
||||
.skeleton(100%, auto, 100%, auto, 5px);
|
||||
}
|
||||
&_opinions{
|
||||
margin-bottom: 1rem;
|
||||
.skeleton(75%, 2rem, 75%, 2rem, 0);
|
||||
}
|
||||
&_name{
|
||||
margin-bottom: 1.6rem;
|
||||
.skeleton(100%, 4.2rem, 100%, 4.2rem, 0)
|
||||
}
|
||||
&_price{
|
||||
margin-bottom: 1.6rem;
|
||||
.skeleton(50%, 2rem, 50%, 2rem, 0)
|
||||
}
|
||||
&_btn{
|
||||
.skeleton(100%, 4.6rem, 100%, 4.6rem, 5px)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media (max-width: 756px) {
|
||||
.idm__hotspot.idm-loading{
|
||||
width: 100%;
|
||||
@@ -226,17 +282,88 @@
|
||||
|
||||
|
||||
// WERSJE
|
||||
.idm__hotspot:has(.product__versions){
|
||||
@keyframes idmPulseOpacity {
|
||||
0%, 100% {
|
||||
opacity: 0.4;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
.idm__hotspot .product.--loading{
|
||||
animation: idmPulseOpacity 3s infinite;
|
||||
}
|
||||
.idm__hotspot .product:has(.product__versions){
|
||||
--idm-hotspot-version-height: 65px;
|
||||
@media (min-width: 757px){
|
||||
--idm-hotspot-version-height: 70px;
|
||||
}
|
||||
@media (min-width: 979px){
|
||||
--idm-hotspot-version-height: 55px;
|
||||
}
|
||||
.product__versions{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
grid-template-columns: repeat(var(--version-mobile-columns, 4), 1fr);
|
||||
gap: 1rem;
|
||||
z-index: 1;
|
||||
background: #fff;
|
||||
clip-path: inset(0% 0 100% 0);
|
||||
padding: 0.3rem 1rem;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
|
||||
padding: 0.3rem 1.5rem;
|
||||
@media (min-width: 757px){
|
||||
padding: 0.3rem 2.5rem;
|
||||
grid-template-columns: repeat(var(--version-tablet-columns, 3), 1fr);
|
||||
}
|
||||
@media (min-width: 979px){
|
||||
padding: 0.3rem 1rem;
|
||||
grid-template-columns: repeat(var(--version-desktop-columns, 5), 1fr);
|
||||
}
|
||||
|
||||
height: var(--idm-hotspot-version-height);
|
||||
align-items: center;
|
||||
}
|
||||
.product__version_single, .product__version_more{
|
||||
display: flex;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #ccc;
|
||||
transition: border 0.2s;
|
||||
|
||||
aspect-ratio: 1 / 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
@media (max-width: 756px){
|
||||
&:has(.--mobile-more:empty), .--tablet-more, .--desktop-more{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media (min-width: 757px) and (max-width: 978px){
|
||||
&:has(.--tablet-more:empty), .--desktop-more, .--mobile-more{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media (min-width: 979px){
|
||||
&:has(.--desktop-more:empty), .--tablet-more, .--mobile-more{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover{
|
||||
border-color: #111;
|
||||
}
|
||||
&.--active{
|
||||
border-color: var(--primary-color, #111);
|
||||
box-shadow: 0 0 0 1px var(--primary-color, #111);
|
||||
}
|
||||
}
|
||||
|
||||
.product__version_more{
|
||||
background: #f2f2f2;
|
||||
}
|
||||
.product__content_wrapper{
|
||||
position: relative;
|
||||
@@ -244,12 +371,83 @@
|
||||
.label_icons, .product__versions{
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.product:hover{
|
||||
&:hover{
|
||||
.product__versions, .label_icons{
|
||||
transform: translateY(-100%);
|
||||
transform: translateY(calc(-1 * var(--idm-hotspot-version-height)));
|
||||
}
|
||||
.product__versions{
|
||||
clip-path: inset(0 0 0 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 978px){
|
||||
.idm__hotspot .product:has(.product__versions){
|
||||
.product__versions, .label_icons{
|
||||
transform: translateY(calc(-1 * var(--idm-hotspot-version-height)));
|
||||
}
|
||||
.product__versions{
|
||||
clip-path: inset(0 0 0 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Rozmiary */
|
||||
.product__select_sizes{
|
||||
order: 3;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
padding: 0.3rem;
|
||||
background: #fff;
|
||||
input[type="radio"]{
|
||||
display: none;
|
||||
}
|
||||
.product__size_select{
|
||||
width: 4.5rem;
|
||||
height: 4.5rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
border: 1px solid #ccc;
|
||||
transition: border 0.2s;
|
||||
&:hover{
|
||||
border-color: #000;
|
||||
}
|
||||
&:not(:has(input:checked)){
|
||||
cursor: pointer;
|
||||
}
|
||||
&:has(input:checked){
|
||||
box-shadow: 0 0 0 1px #000;
|
||||
border-color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 979px){
|
||||
.product__select_sizes{
|
||||
clip-path: inset(0 0 100% 0);
|
||||
transition: all 0.2s;
|
||||
position: absolute;
|
||||
top: calc(100%);
|
||||
padding-top: 1rem;
|
||||
}
|
||||
.product:hover .product__select_sizes{
|
||||
clip-path: inset(0 0 0 0);
|
||||
}
|
||||
.idm__hotspot .swiper-wrapper:has(.product:hover .product__select_sizes){
|
||||
z-index: 51!important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Ogolne */
|
||||
.idm__hotspot{
|
||||
.product__name{
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: var(--hotspot-name-clamp, 999);
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user