No notes defined.
<div class="sds-box -boxSunken -insetLg sds-stackSm position-relative text-center">
<button type="button" class="sds-btn -iconBtn -btnSecondary -btnInverse stretched-link" aria-labelledby="signatureModalTriggerText" data-toggle="modal" data-target="#signatureModal">
<span aria-hidden="true" class="sds-icon sds-icon-sign"></span>
</button>
<p id="signatureModalTriggerText" class="sds-metaColor">Prendre rendez-vous</p>
</div>
<div class="{{ namespace }}box -boxSunken -insetLg {{ namespace }}stackSm position-relative text-center">
{% render "@icon-btn-secondary-inverse", {
eltType: "button",
classes: ["stretched-link"],
icon: "icon-sign",
attrs: {
"aria-labelledby": "signatureModalTriggerText",
"data-toggle": "modal",
"data-target": "#signatureModal"
}
}, true %}
<p id="signatureModalTriggerText" class="{{ namespace }}metaColor">Prendre rendez-vous</p>
</div>
import SignaturePad from "signature_pad";
export default class BoxSignature {
constructor() {
this._canvases = [];
this._resizeDebounce = new Map();
this._init();
}
_init() {
const nodes = document.querySelectorAll("[data-js-signature-pad]");
nodes.forEach((canvasEl) => {
const signaturePad = new SignaturePad(canvasEl);
const parentEl = canvasEl.closest(".sds-boxSignature");
const infosEl = parentEl.querySelector(".sds-boxSignature__infos");
const resetBtn = parentEl.querySelector(".sds-boxSignature__resetBtn");
// Stocker pour gestion centralisée
this._canvases.push({ canvasEl, signaturePad, parentEl });
// Masquer les infos au premier trait
signaturePad.addEventListener("beginStroke", () => {
infosEl.style.visibility = "hidden";
});
// Reset
resetBtn.addEventListener("click", (e) => {
e.preventDefault();
signaturePad.clear();
infosEl.style.visibility = "visible";
});
// Bouton reset désactivé si parent a -isDisabled
const updateResetBtn = () => {
resetBtn.disabled = parentEl.classList.contains("-isDisabled");
};
updateResetBtn();
new MutationObserver(updateResetBtn).observe(parentEl, {
attributes: true,
attributeFilter: ["class"],
});
});
// Central : ResizeObserver sur tous les parents
this._canvases.forEach(({ parentEl }) => {
const ro = new ResizeObserver(() => this._debouncedResizeAll());
ro.observe(parentEl);
});
// Central : écouter Collapse et Tabs Bootstrap
document.addEventListener("shown.bs.collapse", () => this._debouncedResizeAll());
document.addEventListener("shown.bs.tab", () => this._debouncedResizeAll());
// Resize initial
this._debouncedResizeAll(10);
}
_debouncedResizeAll(wait = 60) {
console.log("test")
if (this._resizeTimer) clearTimeout(this._resizeTimer);
this._resizeTimer = setTimeout(() => {
this._canvases.forEach(({ canvasEl, signaturePad }) =>
this._resizeCanvas(signaturePad, canvasEl)
);
this._resizeTimer = null;
}, wait);
}
_resizeCanvas(signaturePad, canvasEl) {
const rect = canvasEl.getBoundingClientRect();
if (rect.width === 0 || rect.height === 0) {
setTimeout(() => this._resizeCanvas(signaturePad, canvasEl), 100);
return;
}
const ratio = Math.max(window.devicePixelRatio || 1, 1);
const data = signaturePad.toData();
canvasEl.width = rect.width * ratio;
canvasEl.height = rect.height * ratio;
const ctx = canvasEl.getContext("2d");
if (ctx.resetTransform) ctx.resetTransform();
ctx.scale(ratio, ratio);
signaturePad.clear();
if (data.length) signaturePad.fromData(data);
}
destroy() {
this._canvases = [];
if (this._resizeTimer) clearTimeout(this._resizeTimer);
}
}
/* variables specific to current element */
$element-specific-variables: "";
.#{$namespace}boxSignature {
/* Save root element context for easy access if nesting is needed */
$self: &;
--comp-input-signature-border-color: var(--comp-input-signature-background-color);
/* properties of current element + media queries */
position: relative;
display: flex !important;
height: map-deep-get($design-tokens, "comp-input-signature-large-height");
border: map-deep-get($design-tokens, "comp-framed-choice-border-width") solid map-deep-get($design-tokens, "comp-input-signature-background-color");
border-color: var(--comp-input-signature-border-color);
/* 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 */
// boxSignature__body
&__body,
&__infos {
display: flex;
justify-content: center;
align-items: center;
}
&__body {
position: relative;
z-index: z("zero");
width: 100%;
}
// boxSignature__pad
&__pad {
position: absolute;
z-index: z("low");
top: 0;
left: 0;
width: 100%;
height: 100%;
}
// boxSignature__infos
&__infos {
flex-direction: column;
pointer-events: none;
}
// boxSignature__svg
&__svg {
max-width: 100%;
}
// boxSignature__resetBtn
&__resetBtn {
position: absolute;
z-index: z("low");
right: var(--comp-input-signature-large-inset-h-r);
bottom: var(--comp-input-signature-large-inset-v);
}
// boxSignature__modalTriggerText
&__modalTriggerText {
@include custom-prop-fallback("color", "comp-input-signature-text-color");
}
/* modifiers */
&.-isDisabled {
pointer-events: none;
@include custom-prop-fallback-override("comp-input-signature-border-color", "comp-input-signature-disabled-border-color");
@include custom-prop-fallback-override("comp-input-signature-background-color", "comp-input-signature-disabled-background-color");
#{$self}__text {
@include custom-prop-fallback-override("comp-input-signature-placeholder-text-color", "comp-input-signature-disabled-text-color");
}
}
&.-hasError {
@include custom-prop-fallback-override("comp-input-signature-border-color", "comp-input-signature-error-border-color");
@include custom-prop-fallback-override("comp-input-signature-background-color", "comp-input-signature-error-background-color");
#{$self}__text {
@include custom-prop-fallback-override("comp-input-signature-placeholder-text-color", "comp-input-signature-text-color");
}
}
/* random parent element */
/*
*
* Syntax : .randomParentElt & {}
*
*/
/* Pseudo Classes */
&:not(.-isDisabled) {
&:hover {
@include custom-prop-fallback("border-color", "comp-input-signature-hover-border-color");
cursor: crosshair;
}
}
&:focus {
}
&:active {
}
&:focus,
&:active {
}
}