1
0
mirror of https://github.com/tabler/tabler.git synced 2026-08-07 03:42:27 +04:00
Files
tabler/shared/ui/Signature.astro
codecalm f27c70ad38 Fix Prettier formatting regression and Astro type-check errors
`Render Modal as real markup` (#2742) reformatted ~140 files back to
tabs/semicolons, breaking the Prettier config added by the Astro
quality gates (#2749). Re-run prettier --write to restore it, and fix
the type errors it had been masking: HTMLElement casts and `this`
typing in ChangePasswordModalContent/ConfirmDeleteModalContent
scripts, plain-JS syntax in the inline-injected progress.astro script,
narrowed prop unions in Button/Check/Spinner, nullable icon svg casts
in Icons/Rating, and a duplicate firstLetters/invalid `placeholder`
attribute in Select.astro. Also fix shared/vitest.config.mts's stale
`astro/lib/**/*.test.ts` include glob left over from the shared source
restructure, which made `pnpm test` report zero test files.
2026-08-03 01:26:19 +02:00

86 lines
2.5 KiB
Plaintext

---
import Icon from './Icon.astro'
import CaptureScript from '../components/CaptureScript.astro'
interface Props {
id?: string
class?: string
clear?: boolean
width?: number
height?: number
event?: string
/** extra-js param — raw JS appended inside the init callback */
extraJs?: string
}
const { id = 'default', class: className, clear, width = 400, height = 400, event = 'DOMContentLoaded', extraJs } = Astro.props
const signatureClass = ['signature position-relative', className]
const clearSnippet = clear
? ` document.querySelector(${JSON.stringify(`#signature-${id}-clear`)}).addEventListener("click", function () {
signaturePad.clear();
});
`
: ''
// extraJs is a documented escape hatch for raw JS (see Props) — not user data, so it
// stays interpolated verbatim rather than JSON-serialized.
const extraSnippet = extraJs
? `${extraJs}
`
: ''
// set:html (below) is genuinely required here: extraJs is a documented raw-JS escape
// hatch that must land *inside* the init callback body (it references canvas /
// signaturePad), so the whole script has to be assembled as text — <script define:vars>
// can only inject variables, not splice caller-supplied code into the function body.
const script = `<!-- BEGIN SIGNATURE PAD -->
<script>
document.addEventListener(${JSON.stringify(event)}, function () {
const canvas = document.getElementById(${JSON.stringify(`signature-${id}`)});
if (canvas) {
const signaturePad = new SignaturePad(canvas, {
backgroundColor: "transparent",
penColor: getComputedStyle(canvas).color
});
${clearSnippet}
function resizeCanvas() {
const ratio = Math.max(window.devicePixelRatio || 1, 1);
console.log(canvas.offsetWidth, canvas.offsetHeight);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext("2d").scale(ratio, ratio);
signaturePad.fromData(signaturePad.toData());
}
window.addEventListener("resize", resizeCanvas);
resizeCanvas();
${extraSnippet}
}
});
</script>
<!-- END SIGNATURE PAD -->`
---
<div class:list={signatureClass}>
{
clear && (
<div class="position-absolute top-0 end-0 p-2">
<div class="btn btn-icon" id={`signature-${id}-clear`} title="Clear signature" data-bs-toggle="tooltip">
<Icon name="trash" />{' '}
</div>
</div>
)
}
<canvas id={`signature-${id}`} width={width} height={height} class="signature-canvas"></canvas>
</div>
<CaptureScript>
<Fragment set:html={script} />
</CaptureScript>