To move the devices around on mobile, target the sds-snetGuide__tabDeviceInner elements and move them either horizontally or vertically through the transform: translateX/Y property, depending on which part is hidden.
<!-- Error rendering component -->
<!-- (unknown path)
Error: Could not render component '@btn-secondary--big-icon-left' - component not found. -->
<!-- Template render error: (unknown path)
Error: Could not render component '@btn-secondary--big-icon-left' - component not found.
at Object._prettifyError (/home/apart/fractal_projects/spuerkeess-design-system-production/node_modules/nunjucks/src/lib.js:32:11)
at /home/apart/fractal_projects/spuerkeess-design-system-production/node_modules/nunjucks/src/environment.js:464:19
at eval (eval at _compile (/home/apart/fractal_projects/spuerkeess-design-system-production/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:121:12)
at eval (eval at _compile (/home/apart/fractal_projects/spuerkeess-design-system-production/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:99:12)
at /home/apart/fractal_projects/spuerkeess-design-system-production/node_modules/@frctl/nunjucks/src/extensions/render.js:47:25
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) -->
{% extends "@spk-page-layout" %}
{% block header %}
{% render "@spk-header--main" %}
{% endblock %}
{% block breadcrumbs %}
<div class="container-fluid">
{% render "@spk-breadcrumbs" %}
</div>
{% endblock %}
{% block main %}
<div class="{{ namespace }}snetGuide">
<section class="{{ namespace }}section">
<div class="{{ namespace }}section__innerWrapper">
<div class="{{ namespace }}section__inner">
<div class="container-fluid">
<div class="{{ namespace }}pageCover">
<div class="row">
<div class="col-12 col-xl-6 d-flex">
<div class="{{ namespace }}pageCover__textContainer {{ namespace }}stackXl container-half-xl d-flex flex-column">
<div class="{{ namespace }}snetGuide__navigation d-flex align-items-center">
{% render "@icon-btn-secondary",{
icon: "icon-arrowprevious"
},true %}
{% render "@btn-secondary--big-icon-left",{
classes: ["-block", "justify-content-start"],
text: "Rechercher un article",
icon: "icon-search",
attrs: {
"data-toggle": "modal",
"data-target": "#searchModal"
}
},true %}
</div>
<div class="{{ namespace }}pageCover__text {{ namespace }}stackMd mt-auto mb-auto">
<h1 class="h1 {{ namespace }}pageCover__title">Renommer un compte</h1>
<p class="h2 {{ namespace }}headingLight {{ namespace }}pageCover__subTitle">Vous ne vous y retrouvez plus entre tous vos comptes dans S-Net ? Afin d’améliorer leur visibilité, renommez-les !</p>
</div>
</div>
</div>
<div class="col-12 col-xl-6">
<div class="d-flex flex-column-reverse">
<div class="d-flex justify-content-center">
{% render "@toggle-tab--tabs",toggletabsOptions,true %}
</div>
<div class="{{ namespace }}snetGuide__tabContent tab-content" id="onboarding-tabs">
<div class="{{ namespace }}snetGuide__tab -mobile tab-pane fade show active" id="{{ toggletabsOptions.toggleTabItems[0].target }}" role="tabpanel" aria-labelledby="{{ toggletabsOptions.toggleTabItems[0].target }}">
<div class="{{ namespace }}snetGuide__tabDevice -mobile">
<div class="{{ namespace }}snetGuide__tabDeviceInner">
{% render "@spk-device" %}
</div>
</div>
<div class="{{ namespace }}snetGuide__slider">
{% render "@popover", {
first: true,
classes: [namespace + "snetGuide__popover"],
step: "1",
placement: "bottom",
imgSrc: (mediaPath + "/snet/components/snet-guide/mobile-example.png") | path,
popoverAttrsPrevious: {
disabled: true,
"data-guide-popover-previous": "step1"
},
popoverAttrsNext: {
"data-guide-popover-next": "step2"
}
},true %}
{% render "@popover",{
step: "2",
placement: "top",
imgSrc: (mediaPath + "/snet/components/snet-guide/mobile-example-2.png") | path,
modifiers: [],
classes: [namespace + "snetGuide__popover"],
popoverAttrsPrevious: {
"data-guide-popover-previous": "step1"
},
popoverAttrsNext: {
"data-guide-popover-next": "step3"
}
},true %}
{% render "@popover",{
step: "3",
placement: "left",
imgSrc: (mediaPath + "/snet/components/snet-guide/mobile-example-3.png") | path,
modifiers: [],
classes: [namespace + "snetGuide__popover"],
popoverAttrsPrevious: {
"data-guide-popover-previous": "step2"
},
popoverAttrsNext: {
"data-guide-popover-next": "step4"
}
},true %}
{% render "@popover",{
step: "4",
placement: "right",
imgSrc: (mediaPath + "/snet/components/snet-guide/mobile-example-4.png") | path,
modifiers: [],
classes: [namespace + "snetGuide__popover"],
popoverAttrsPrevious: {
"data-guide-popover-previous": "step3"
},
popoverAttrsNext: {
"data-guide-popover-next": "step5"
}
},true %}
{% render "@popover--feedback",{
step: "5",
placement: "bottom",
modifiers: [],
classes: [namespace + "snetGuide__popover"],
captchaOptions: {
ctaCaptchaAttrs: {
"data-guide-popover-next": "step6"
}
}
},true %}
{% render "@popover--reset",{
step: "6",
placement: "top",
modifiers: [],
classes: [namespace + "snetGuide__popover"],
popoverAttrsPrevious: {
"data-guide-popover-previous": "step1",
"data-reset": ""
}
},true %}
</div>
</div>
<div class="{{ namespace }}snetGuide__tab -desktop tab-pane fade" id="{{ toggletabsOptions.toggleTabItems[1].target }}" role="tabpanel" aria-labelledby="{{ toggletabsOptions.toggleTabItems[1].target }}">
<div class="{{ namespace }}snetGuide__tabDevice -desktop">
<div class="{{ namespace }}snetGuide__tabDeviceInner">
{% render "@spk-device--desktop" %}
</div>
</div>
<div class="{{ namespace }}snetGuide__slider">
{% render "@popover", {
first: true,
classes: [namespace + "snetGuide__popover"],
step: "1",
placement: "bottom",
imgSrc: (mediaPath + "/snet/components/snet-guide/desktop-example.png") | path,
popoverAttrsPrevious: {
disabled: true,
"data-guide-popover-previous": "step1"
},
popoverAttrsNext: {
"data-guide-popover-next": "step2"
}
},true %}
{% render "@popover",{
step: "2",
placement: "top",
imgSrc: (mediaPath + "/snet/components/snet-guide/desktop-example-2.png") | path,
modifiers: [],
classes: [namespace + "snetGuide__popover"],
popoverAttrsPrevious: {
"data-guide-popover-previous": "step1"
},
popoverAttrsNext: {
"data-guide-popover-next": "step3"
}
},true %}
{% render "@popover",{
step: "3",
placement: "left",
imgSrc: (mediaPath + "/snet/components/snet-guide/desktop-example-3.png") | path,
modifiers: [],
classes: [namespace + "snetGuide__popover"],
popoverAttrsPrevious: {
"data-guide-popover-previous": "step2"
},
popoverAttrsNext: {
"data-guide-popover-next": "step4"
}
},true %}
{% render "@popover",{
step: "4",
placement: "right",
imgSrc: (mediaPath + "/snet/components/snet-guide/desktop-example-4.png") | path,
modifiers: [],
classes: [namespace + "snetGuide__popover"],
popoverAttrsPrevious: {
"data-guide-popover-previous": "step3"
},
popoverAttrsNext: {
"data-guide-popover-next": "step5"
}
},true %}
{% render "@popover--feedback",{
step: "5",
placement: "bottom",
imgSrc: (mediaPath + "/snet/components/snet-guide/desktop-example-5.png") | path,
modifiers: [],
classes: [namespace + "snetGuide__popover"],
captchaOptions: {
ctaCaptchaAttrs: {
"data-guide-popover-next": "step6"
}
}
},true %}
{% render "@popover--reset",{
step: "6",
placement: "top",
modifiers: [],
classes: [namespace + "snetGuide__popover"],
popoverAttrsPrevious: {
"data-guide-popover-previous": "step1",
"data-reset": ""
}
},true %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
<script src="https://unpkg.com/@popperjs/core@2"></script>
{% endblock %}
{% block footer %}
{% render "@footer" %}
{% endblock %}
export default class SnetGuide {
constructor() {
this.initTour()
}
initTour() {
const devices = document.querySelectorAll('.sds-snetGuide__tab');
const popperOptions = function (position) {
return {
placement: position,
modifiers: [
{
name: 'offset',
options: {
offset: [0, 32]
}
}
]
}
}
function moveIndicator(indicator) {
indicator.style.top = Math.floor(Math.random() * 100) + 1 + '%';
indicator.style.left = Math.floor(Math.random() * 100) + 1 + '%';
}
devices.forEach(function (element, index) {
const popovers = element.querySelectorAll('.sds-popover');
const indicator = element.querySelector('.sds-snetGuide__indicator');
const img = element.querySelector('.sds-snetGuide__deviceImg img');
const step1 = element.querySelector('.sds-popover[data-step="step1"]');
const popperInstance = Popper.createPopper(indicator, step1, popperOptions(step1.dataset.placement));
$('button[data-toggle="tab"]').on('shown.bs.tab', function (event) {
popperInstance.update();
})
popovers.forEach(function (popover, index) {
popover.querySelector("[data-guide-popover-next]")?.addEventListener("click", (e) => {
moveIndicator(indicator);
let target = element.querySelector("[data-step="+ e.currentTarget.dataset.guidePopoverNext +"]");
if(popover.nextElementSibling.dataset.imgSrc) {
img.src = popover.nextElementSibling.dataset.imgSrc;
}
popover.classList.remove("show");
indicator.addEventListener("transitionend", (e) => {
popover.classList.remove("show");
target.classList.add("show");
Popper.createPopper(indicator, target, popperOptions(popover.nextElementSibling.dataset.placement));
})
})
popover.querySelector("[data-guide-popover-previous]")?.addEventListener("click", (e) => {
moveIndicator(indicator);
if(popover.previousElementSibling.dataset.imgSrc) {
img.src = popover.previousElementSibling.dataset.imgSrc;
}
let target = element.querySelector("[data-step="+ e.currentTarget.dataset.guidePopoverPrevious +"]");
popover.classList.remove("show");
indicator.addEventListener("transitionend", (e) => {
popover.classList.remove("show");
target.classList.add("show");
Popper.createPopper(indicator, target, popperOptions(popover.previousElementSibling.dataset.placement));
})
})
popover.querySelector("[data-reset]")?.addEventListener("click", (e) => {
img.src = element.querySelector("[data-step='step1']").dataset.imgSrc;
});
});
});
}
}
/* variables specific to current element */
$snet-guide-device-img-max-height: 60vh;
$snet-guide-device-desktop-header-desktop-height: map-deep-get($token-sizes-unit-map, "40");
$snet-guide-device-desktop-header-mobile-height: $snet-guide-device-desktop-header-desktop-height * 0.5;
$snet-guide-device-border-width: $device-border-width-global;
.#{$namespace}snetGuide {
/* Save root element context for easy access if nesting is needed */
$self: &;
/* properties of current element + media queries */
overflow: hidden;
position: relative;
z-index: z("zero");
@include media-breakpoint-up(xl) {
overflow: visible;
}
/* Pseudo Elements */
&::before {
}
&::after {
}
/*
Include elements that are linked to the current element but have to reside at the root level of the stylesheet
(e.g: keyframes)
*/
@at-root {
}
/* children - write selector in full in comments in order to facilitate search */
&__navigation {
@include spacer-component-inline("md");
margin-bottom: map-deep-get($token-spacer-stack-min-map, "3xl");
@include media-breakpoint-up(xl) {
@include spacer-component-inline("xl");
margin-bottom: 0;
}
}
// snetGuide__tab
&__tab {
// follows same logic as parent
justify-content: flex-end;
position: relative;
&.-mobile {
@include media-breakpoint-up(xl){
width: max-content;
margin: auto;
}
#{$self}__slider {
right: 100%;
}
}
}
&__tabContent {
margin-bottom: map-deep-get($token-spacer-stack-max-map, "lg");
@include media-breakpoint-up(xl){
margin-bottom: map-deep-get($token-spacer-stack-max-map, "xl");
}
}
&__tabDevice {
height: 400px;
overflow: hidden;
&.-mobile {
display: flex;
justify-content: center;
margin-left: -($grid-gutter-width*0.5);
margin-right: -($grid-gutter-width*0.5);
padding-left: $grid-gutter-width*0.5;
padding-right: $grid-gutter-width*0.5;
@include media-breakpoint-up(xl){
margin-left: 0;
margin-right: 0;
padding-left: 0;
padding-right: 0;
}
IMG {
@include media-breakpoint-up(xl) {
max-height: calc(#{$snet-guide-device-img-max-height} - (#{$snet-guide-device-border-width*2})); // multiply by to because of border top and bottom
}
}
}
&.-desktop {
display: flex;
align-items: flex-end;
width: 500px;
margin: auto;
@include media-breakpoint-up(xl) {
width: auto;
max-width: 100%;
}
IMG {
max-height: calc(#{$snet-guide-device-img-max-height} - #{$snet-guide-device-desktop-header-mobile-height} - (#{$snet-guide-device-border-width*2})); // multiply by to because of border top and bottom
@include media-breakpoint-up("md") {
max-height: calc(#{$snet-guide-device-img-max-height} - #{$snet-guide-device-desktop-header-desktop-height} - (#{$snet-guide-device-border-width*2})); // multiply by to because of border top and bottom
}
}
}
@include media-breakpoint-up(xl) {
height: calc(#{$snet-guide-device-img-max-height});
overflow: visible;
display: flex;
align-items: flex-end;
> * {
max-height: 100%;
margin-left: auto;
margin-right: auto;
}
}
}
&__tabDeviceInner {
display: flex;
justify-content: center;
max-width: 100%;
position: relative;
transition: top 0.15s ease-in-out;
}
&__device {
$device: &;
width: max-content;
&.-mobile {
max-width: 328px;
}
&.-desktop {
#{$device}Header {
border-top-left-radius: map-deep-get($token-radius-map, "16");
border-top-right-radius: map-deep-get($token-radius-map, "16");
@include custom-prop-fallback("background-color", "sys-color-background-neutral-black");
height: $snet-guide-device-desktop-header-mobile-height;
display: flex;
align-items: center;
@include spacer-component-inline("sm");
padding-left: map-deep-get($token-spacer-inset-map, "md");
@include media-breakpoint-up("md") {
height: $snet-guide-device-desktop-header-desktop-height;
border-top-left-radius: map-deep-get($token-radius-map, "24");
border-top-right-radius: map-deep-get($token-radius-map, "24");
}
+ #{$device}Img {
border-top-left-radius: 0;
border-top-right-radius: 0;
border-top-width: 0;
}
SPAN {
width: map-deep-get($token-sizes-unit-map, "8")*0.75;
height: map-deep-get($token-sizes-unit-map, "8")*0.75;
@include custom-prop-fallback("background-color", "sys-color-background-primary-100");
border-radius: map-deep-get($token-radius-map, "circle");
@include media-breakpoint-up("md") {
width: map-deep-get($token-sizes-unit-map, "16")*0.75;
height: map-deep-get($token-sizes-unit-map, "16")*0.75;
}
}
}
#{$device}Img {
border-radius: map-deep-get($token-radius-map, "16");
@include media-breakpoint-up("md") {
border-radius: map-deep-get($token-radius-map, "24");
}
}
}
@include media-breakpoint-up(xl) {
display: inline-flex;
flex-direction: column;
}
}
&__deviceImg {
position: relative;
overflow: hidden;
border: $border-width*4 solid;
@include custom-prop-fallback("border-color", "sys-color-background-neutral-black");
border-radius: map-deep-get($token-radius-map, "32");
}
&__slider {
display: flex;
align-items: flex-start;
margin-top: -$popover-body-padding-y;
padding-left: $grid-gutter-width*0.5;
padding-right: $grid-gutter-width*0.5;
min-height: 156px;
@include media-breakpoint-up(xl) {
position: absolute;
top: 0;
bottom: 0;
margin-top: 0;
min-height: 0;
}
> * {
min-width: 0;
width: 320px;
max-width: 100%;
@include media-breakpoint-up(xl) {
position: absolute !important;
max-width: none;
}
}
}
&__popover {
display: none;
@include media-breakpoint-between(xs,lg){
transform: none !important;
position: static !important;
margin-left: auto !important;
margin-right: auto !important;
}
@include media-breakpoint-up(xl){
display: block;
visibility: hidden;
}
&.show {
display: block;
@include media-breakpoint-up(xl){
visibility: visible;
}
}
.arrow {
margin: 0;
display: none;
@include media-breakpoint-up(xl){
display: block;
}
}
}
&__indicator {
width: map-deep-get($token-sizes-unit-map, "12");
height: map-deep-get($token-sizes-unit-map, "12");
border-radius: map-deep-get($token-radius-map, "circle");
@include custom-prop-fallback("background-color", "sys-color-background-secondary-100");
position: absolute;
z-index: z("low");
transition: top 0.5s linear, left 0.5s linear;
@at-root {
@keyframes ripple {
0%{transform: translate(-50%,-50%) scale(.1);opacity: 0;}
50%{ opacity: 0.2;}
100%{transform: translate(-50%,-50%) scale(1); opacity: 0;}
}
}
&::before,
&::after {
content: "";
opacity: 0.2;
background-color: inherit;
border-radius: inherit;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: map-deep-get($token-sizes-unit-map, "48");
height: map-deep-get($token-sizes-unit-map, "48");
}
&::before {
z-index: z("medium");
animation: ripple 2s infinite 0.3s;
}
&::after {
z-index: z("high");
animation: ripple 2s infinite 0.6s;
}
}
&__indicator SPAN {
width: map-deep-get($token-sizes-unit-map, "48");
height: map-deep-get($token-sizes-unit-map, "48");
border-radius: inherit;
background-color: inherit;
opacity: 0.2;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
z-index: z("low");
animation: ripple 2s infinite;
}
/* modifiers */
// snetGuide -altStyle
&.-altStyle {
// follows same logic as base element
}
/* random parent element */
/*
*
* Syntax : .randomParentElt & {}
*
*/
/* Pseudo Classes */
&:hover {
@media (hover: hover) {
}
}
&:focus {
}
&:active {
}
&:focus,
&:active {
}
}