Files
WYGIWYH/app/templates/includes/tools/calculator.html
Herculino Trotta b4e9446cf6 chore: update tailwind to v4
As is customary in the JS world EVERYTHING must break with each major version
2025-06-21 16:12:44 -03:00

104 lines
5.2 KiB
HTML

{% load formats %}
<div class="tw:hidden tw:w-[60vw] tw:lg:w-[30vw] tw:xl:w-[20vw] position-fixed shadow rounded-3 bg-body tw:border-gray-700 tw:border tw:border-solid tw:text-center tw:align-middle tw:z-[2000] tw:touch-none user-select-none"
id="calculator"
hx-preserve
_="
on load
-- Get localized separators from Django
set window.decimalSeparator to '{% get_decimal_separator %}'
set window.thousandSeparator to '{% get_thousand_separator %}'
set window.argSeparator to ';'
end
on focusin halt the event end -- this prevents bootstrap's static offcanvas from hijacking the focus from the input when open end
on show or keyup[code is 'KeyC' and altKey is true] from body
if my.classList.contains('tw:hidden')
remove .{'tw:hidden'} from me
measure my width, height
set xoff to (window.innerWidth/2) - (width/2)
set yoff to (window.innerHeight/2) - (height)
add { left: ${xoff}px; top: ${yoff}px; }
add .scale-in-center to me then wait for animationend then remove .scale-in-center from me
then call #calculator-input.focus()
else
add .scale-out-center to me then wait for animationend then remove .scale-out-center from me
add .{'tw:hidden'} to me
end
end
on pointerdown(screenX, screenY)
if event.target.closest('#calculator-handle')
halt the event
measure my x, y, width, height
set xoff to screenX - x
set yoff to screenY - y
repeat until event pointerup from document
wait for pointermove(screenX, screenY) or
pointerup(screenX, screenY) from document
-- Calculate new position
set newX to screenX - xoff
set newY to screenY - yoff
-- Constrain to viewport
set newX to Math.max(5, Math.min(newX, window.innerWidth - (width + 10)))
set newY to Math.max(20, Math.min(newY, window.innerHeight - (height + 5)))
add { left: ${newX}px; top: ${newY}px; transform: none }
end
end
end">
<div id="calculator-handle"
class="position-absolute bg-secondary rounded-top-2 tw:cursor-move d-flex align-items-center justify-content-center tw:top-[-20px] tw:left-[3px] tw:w-[2em] tw:h-[20px]">
<i class="fa-solid fa-grip"></i>
</div>
<input type="search"
class="form-control"
id="calculator-input"
_="on click me.focus()
on input or search
js(my)
return my.value.replace(new RegExp('\\' + window.decimalSeparator + '|\\' + window.argSeparator + '|\\' + window.thousandSeparator, 'g'),
match => {
if (match === window.decimalSeparator) return '.';
if (match === window.argSeparator) return ',';
return ''; // This will remove the thousandSeparator
})
end
then set expr to it
then call math.evaluate(expr).toNumber()
if result exists and result is a Number
js(result)
return result.toLocaleString(undefined, {minimumFractionDigits: 0, maximumFractionDigits: 40})
end
then set localizedResult to it
set #calculator-result.innerText to localizedResult
then remove .{'tw:hidden'} from #calculator-result-container
then add .swing-in-top-fwd to #calculator-result-container
then settle
then remove .swing-in-top-fwd from #calculator-result-container
else
add .swing-out-top-bck to #calculator-result-container
then settle
then add .{'tw:hidden'} to #calculator-result-container
then remove .swing-out-top-bck from #calculator-result-container
end
catch e
add .swing-out-top-bck to #calculator-result-container
then settle
then add .{'tw:hidden'} to #calculator-result-container
then remove .swing-out-top-bck from #calculator-result-container
end"
placeholder="2 + 2">
<div class="tw:hidden" id="calculator-result-container">
<div class="d-flex flex-row p-2 justify-content-between">
<div class="tw:text-gray-400">=</div>
<div id="calculator-result" class="user-select-all"></div>
</div>
</div>
<div class="position-absolute tw:cursor-pointer top-0 start-100 translate-middle tw:p-0 text-bg-primary border border-light rounded-circle tw:flex tw:items-center tw:justify-center tw:w-5 tw:h-5"
_="on click trigger show on #calculator">
<i class="fa-solid fa-xmark tw:flex tw:items-center tw:justify-center tw:w-full tw:h-full"></i>
</div>
</div>