Files
cv-site/static/hyperscript/utils._hs
T

219 lines
7.4 KiB
Plaintext
Raw Normal View History

2025-11-14 21:38:09 +00:00
-- ==============================================================================
-- CV Site - Hyperscript Functions
-- ==============================================================================
-- Global hyperscript functions for CV interactive features
-- Keeps HTML templates clean and behavior organized
-- ==============================================================================
-- PRINT FUNCTIONS
-- ==============================================================================
def printFriendly()
-- Store current state
set container to the first .cv-container
set paper to the first .cv-paper
set wasClean to container.classList.contains('theme-clean')
set wasLong to paper.classList.contains('cv-long')
set currentZoom to localStorage.getItem('cv-zoom') or '100'
-- Apply print-friendly settings
2025-11-15 15:59:54 +00:00
if wasClean is false
add .theme-clean to container
end
2025-11-14 21:38:09 +00:00
remove .cv-long from paper
add .cv-short to paper
-- Reset zoom for consistent printing
set #zoom-wrapper's *zoom to 1
-- Let CSS apply, then print
wait 50ms
call window.print()
-- Wait for print dialog to close, then restore
wait 100ms
-- Restore original theme
2025-11-15 15:59:54 +00:00
if wasClean is false
remove .theme-clean from container
end
2025-11-14 21:38:09 +00:00
-- Restore original length
if wasLong is true
remove .cv-short from paper
add .cv-long to paper
end
-- Restore original zoom by triggering slider input event
if currentZoom is not '100'
set #zoom-slider's value to currentZoom
send input to #zoom-slider
end
end
-- ==============================================================================
-- SCROLL BEHAVIOR
-- ==============================================================================
def initScrollBehavior()
set :lastScroll to 0
set :scrollThreshold to 100
set :keepHeaderVisible to false
end
def handleScroll()
set currentScroll to window.pageYOffset
set menu to the first .navigation-menu
set isMenuOpen to menu.classList.contains('menu-open')
-- Calculate if at bottom (within 50px)
set scrollHeight to the document's documentElement's scrollHeight
set clientHeight to the document's documentElement's clientHeight
2025-11-14 21:38:09 +00:00
set isAtBottom to (scrollHeight - currentScroll - clientHeight) < 50
-- Reset keepHeaderVisible when scrolling up
if currentScroll < :lastScroll
set :keepHeaderVisible to false
end
2025-11-15 15:59:54 +00:00
-- Header visibility: Scrolling down past threshold
if currentScroll > :scrollThreshold and currentScroll > :lastScroll and :keepHeaderVisible is false
add .header-hidden to .action-bar
if isMenuOpen is true
add .header-hidden to menu
end
end
-- Header visibility: Scrolling up past threshold
if currentScroll > :scrollThreshold and (currentScroll <= :lastScroll or :keepHeaderVisible is true)
remove .header-hidden from .action-bar
if isMenuOpen is true
remove .header-hidden from menu
2025-11-14 21:38:09 +00:00
end
2025-11-15 15:59:54 +00:00
end
-- Header visibility: At top
if currentScroll <= :scrollThreshold
2025-11-14 21:38:09 +00:00
remove .header-hidden from .action-bar
2025-11-15 15:59:54 +00:00
if isMenuOpen is true
remove .header-hidden from menu
end
2025-11-14 21:38:09 +00:00
end
-- Back to top button visibility (with null check)
set backToTop to #back-to-top
if backToTop is not null
if currentScroll > 300
set backToTop's *display to 'flex'
end
if currentScroll <= 300
set backToTop's *display to 'none'
end
2025-11-14 21:38:09 +00:00
end
-- At-bottom class for fixed buttons (with null checks)
2025-11-14 21:38:09 +00:00
if isAtBottom
if backToTop is not null then add .at-bottom to backToTop end
if #info-button is not null then add .at-bottom to #info-button end
if #shortcuts-button is not null then add .at-bottom to #shortcuts-button end
if #download-button is not null then add .at-bottom to #download-button end
if #print-friendly-button is not null then add .at-bottom to #print-friendly-button end
if #cmd-k-button is not null then add .at-bottom to #cmd-k-button end
add .at-bottom to .color-theme-switcher
if #zoom-toggle-button is not null then add .at-bottom to #zoom-toggle-button end
2025-11-15 15:59:54 +00:00
end
if not isAtBottom
if backToTop is not null then remove .at-bottom from backToTop end
if #info-button is not null then remove .at-bottom from #info-button end
if #shortcuts-button is not null then remove .at-bottom from #shortcuts-button end
if #download-button is not null then remove .at-bottom from #download-button end
if #print-friendly-button is not null then remove .at-bottom from #print-friendly-button end
if #cmd-k-button is not null then remove .at-bottom from #cmd-k-button end
remove .at-bottom from .color-theme-switcher
if #zoom-toggle-button is not null then remove .at-bottom from #zoom-toggle-button end
2025-11-14 21:38:09 +00:00
end
-- Update last scroll position
set :lastScroll to currentScroll
end
2025-11-15 15:59:54 +00:00
-- ==============================================================================
-- EXPAND/COLLAPSE ALL SECTIONS
-- ==============================================================================
-- Expand all <details> elements in the CV
def expandAllSections(evt)
if evt then call evt.preventDefault() end
set details to <details/>
for d in details
set d's @open to ''
end
end
-- Collapse all <details> elements in the CV
def collapseAllSections(evt)
if evt then call evt.preventDefault() end
set details to <details/>
for d in details
call d.removeAttribute('open')
end
end
-- ==============================================================================
-- FOOTER HOVER INTERACTION
-- ==============================================================================
-- Adds/removes footer-hovered class to fixed buttons when hovering footer
def setFooterHover(show)
set buttons to <.download-btn, .print-friendly-btn, .shortcuts-btn, .info-button, .back-to-top, .color-theme-switcher/>
for btn in buttons
if show
add .footer-hovered to btn
else
remove .footer-hovered from btn
end
end
end
-- ==============================================================================
-- MODAL HELPERS
-- ==============================================================================
-- Close modal when clicking backdrop (outside content)
def closeOnBackdrop(modal, evt)
if evt.target is modal
call modal.close()
end
end
-- ==============================================================================
-- SCROLL HELPERS
-- ==============================================================================
-- Smooth scroll to top of page
def scrollToTop(evt)
call evt.preventDefault()
call window.scrollTo({top: 0, behavior: 'smooth'})
end
-- ==============================================================================
-- NAVIGATION SCROLL
-- ==============================================================================
-- Smooth scroll to a section by ID
def scrollToSection(evt, sectionId)
if evt then call evt.preventDefault() end
set el to #{sectionId}
if el is not null
call el.scrollIntoView({ behavior: 'smooth' })
-- Close the menu after navigation
set menu to the first .navigation-menu
if menu is not null
remove .menu-hover from menu
remove .menu-open from menu
end
end
end
2025-11-15 15:59:54 +00:00
-- ==============================================================================
-- KEYBOARD SHORTCUTS
-- ==============================================================================
-- Note: Keyboard event handlers are now defined inline in the body tag
-- because hyperscript 0.9.12 doesn't support nested event handlers (on ... inside def)