@cagovweb/state-template 6.5.1 → 6.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- var StateTemplateNpmPackageVersion="6.5.1";
1
+ var StateTemplateNpmPackageVersion="6.5.2";
2
2
  /*!
3
3
  * Bootstrap v5.3.3 (https://getbootstrap.com/)
4
4
  * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
@@ -6318,17 +6318,18 @@ var StateTemplateNpmPackageVersion="6.5.1";
6318
6318
  window.addEventListener("load", () => {
6319
6319
  const doc = document.documentElement;
6320
6320
 
6321
- let prevScroll = window.scrollY || doc.scrollTop;
6322
- let curScroll;
6323
- let direction = 0;
6324
- let prevDirection = 0;
6325
-
6326
- const headerAlert = document.querySelector("header .alert");
6321
+ const headerAlert = document.querySelectorAll("header .alert");
6327
6322
  const header = document.querySelector(".utility-header");
6328
6323
  const mainheader = document.querySelector("header");
6329
6324
  if (!header || !mainheader) return;
6330
6325
 
6331
- window.addEventListener("scroll", () => {
6326
+ let prevScroll;
6327
+ let curScroll;
6328
+ let direction = 0;
6329
+ let prevDirection = 0;
6330
+ let ticking = false;
6331
+
6332
+ const updateHeader = () => {
6332
6333
  /*
6333
6334
  ** Find the direction of scroll
6334
6335
  ** 0 - initial, 1 - up, 2 - down
@@ -6346,26 +6347,33 @@ window.addEventListener("load", () => {
6346
6347
  if (direction !== prevDirection) {
6347
6348
  // Toggle Header
6348
6349
  if (direction === 2 && curScroll > 40) {
6349
- const hiddenheight =
6350
- header.clientHeight + (headerAlert?.clientHeight || 0);
6350
+ // Add all the alert heights to the hidden height
6351
+ let alertHeight = 0;
6352
+ headerAlert.forEach(alert => {
6353
+ alertHeight += alert.clientHeight;
6354
+ });
6351
6355
 
6356
+ const hiddenheight = header.clientHeight + alertHeight;
6352
6357
  mainheader.style.top = `-${hiddenheight}px`;
6353
6358
  prevDirection = direction;
6354
6359
  } else if (direction === 1 && curScroll < 40) {
6355
- // mainheader.classList.remove('scrolled');
6356
- // header.classList.remove('is-hidden');
6357
- // header.removeAttribute("style");
6358
6360
  mainheader.style.removeProperty("top");
6359
6361
  prevDirection = direction;
6360
6362
  }
6361
6363
  }
6362
6364
 
6363
6365
  prevScroll = curScroll;
6366
+ ticking = false;
6367
+ };
6368
+
6369
+ window.addEventListener("scroll", () => {
6370
+ if (!ticking) {
6371
+ requestAnimationFrame(updateHeader);
6372
+ ticking = true;
6373
+ }
6364
6374
  });
6365
6375
  });
6366
6376
 
6367
- // retain scroll position
6368
-
6369
6377
  //@ts-check
6370
6378
 
6371
6379
  window.addEventListener("load", () => {
@@ -7438,11 +7446,11 @@ window.addEventListener("load", () => {
7438
7446
  el.classList.add("has-sub");
7439
7447
 
7440
7448
  const carrot = document.createElement("span");
7441
- carrot.classList.add("ca-gov-icon-caret-down", "carrot");
7449
+ carrot.classList.add("carrot");
7442
7450
  carrot.ariaHidden = "true";
7443
7451
 
7444
7452
  const toggleSubNav = document.createElement("div");
7445
- toggleSubNav.classList.add("ca-gov-icon-caret-right", "rotate");
7453
+ toggleSubNav.classList.add("rotate");
7446
7454
  toggleSubNav.ariaHidden = "true";
7447
7455
  toggleSubNav.style.display = mobileView() ? "block" : "none";
7448
7456
 
@@ -7568,34 +7576,31 @@ window.addEventListener("load", () => {
7568
7576
  ".search-container:not(.featured-search)"
7569
7577
  ); // only on subpages, unique, same as #head-search
7570
7578
 
7571
- // header, contains nav, search form, etc, unique
7572
- const headerHeight = /** @type {HTMLElement} */ (
7573
- document.querySelector(".global-header")
7574
- )?.offsetHeight; // header height
7575
-
7576
- /** @type {HTMLElement | null} */
7577
- const utility = document.querySelector(".utility-header"); // utility header, unique
7578
- const utilityHeight = utility?.offsetHeight || 0;
7579
- // utility header height
7580
-
7581
- /** @type {NodeListOf<HTMLElement>} */
7582
- const alertBanner = document.querySelectorAll(".alert-banner"); // page can have multiple
7579
+ const getSearchTop = () => {
7580
+ /** @type {HTMLElement} */
7581
+ const header = document.querySelector(".global-header");
7582
+ /** @type {HTMLElement} */
7583
+ const utility = document.querySelector(".utility-header");
7584
+ /** @type {NodeListOf<HTMLElement>} */
7585
+ const alertBanners = document.querySelectorAll(".alert-banner");
7583
7586
 
7584
- let alertbannerHeight = 0;
7585
- // taking into account multiple alert banners
7586
- alertBanner.forEach(oneBanner => {
7587
- alertbannerHeight += oneBanner.offsetHeight;
7588
- });
7587
+ const headerHeight = header?.offsetHeight || 0;
7588
+ const utilityHeight = utility?.offsetHeight || 0;
7589
+ const alertBannerHeight = Array.from(alertBanners).reduce(
7590
+ (sum, banner) => sum + (banner.offsetHeight || 0),
7591
+ 0
7592
+ );
7589
7593
 
7590
- //const fullnav = document.querySelector(".top-level-nav"); // navigation ul tag, unique
7594
+ // contains navigation and search form, unique
7595
+ // Full width navigation
7596
+ const navigationHeight = document
7597
+ .querySelector(".navigation-search")
7598
+ ?.classList.contains("full-width-nav")
7599
+ ? 82
7600
+ : 0;
7591
7601
 
7592
- // contains navigation and search form, unique
7593
- // Full width navigation
7594
- const navigationHeight = document
7595
- .querySelector(".navigation-search")
7596
- ?.classList.contains("full-width-nav")
7597
- ? 82
7598
- : 0;
7602
+ return headerHeight - utilityHeight - alertBannerHeight - navigationHeight;
7603
+ };
7599
7604
 
7600
7605
  if (searchText && searchContainer) {
7601
7606
  // Unfreeze search width when blured.
@@ -7623,15 +7628,14 @@ window.addEventListener("load", () => {
7623
7628
  }
7624
7629
 
7625
7630
  // search box top position
7626
- // TODO: Really close to searchTop() except for top size
7627
- if (!mobileControlVisible()) {
7631
+ const setSearchTop = () => {
7632
+ if (!searchbox) return;
7633
+
7628
7634
  // calulation search box top position
7629
- const searchtop =
7630
- headerHeight - utilityHeight - alertbannerHeight - navigationHeight;
7631
- if (!mobileControlVisible() && searchbox) {
7632
- searchbox.style.top = `${Math.max(searchtop, 82)}px`;
7635
+ if (!mobileControlVisible()) {
7636
+ searchbox.style.top = `${Math.max(getSearchTop(), 55)}px`;
7633
7637
  }
7634
- }
7638
+ };
7635
7639
 
7636
7640
  // have the close button remove search results and the applied classes
7637
7641
  //resultsContainer.find('.close').on('click', removeSearchResults);
@@ -7727,46 +7731,18 @@ window.addEventListener("load", () => {
7727
7731
  }
7728
7732
  }
7729
7733
 
7730
- const setSearchTop = () => {
7731
- // calulation search box top position
7732
- const searchtop =
7733
- headerHeight - utilityHeight - alertbannerHeight - navigationHeight;
7734
- if (!mobileControlVisible() && searchbox) {
7735
- searchbox.style.top = `${Math.max(searchtop, 55)}px`;
7736
- }
7737
- };
7738
-
7739
7734
  // on alert close event
7740
7735
  document.querySelectorAll(".alert-banner .close").forEach(oneClose => {
7741
7736
  oneClose.addEventListener("click", setSearchTop);
7742
7737
  });
7743
7738
 
7744
- // Calculation search box top property on the scroll for the fixed nav
7745
- window.addEventListener("scroll", () => {
7746
- if (!mobileControlVisible()) {
7747
- // setting timeout before calculating the search box top property otherwise it can take into account transitional values.
7748
- setTimeout(setSearchTop, 400);
7749
-
7750
- // remove featured search on scroll in desktop
7751
- const FeaturedSearch = document.querySelector("nav ~ #head-search");
7752
- if (FeaturedSearch) {
7753
- if (
7754
- document.body.scrollTop >= 100 ||
7755
- document.documentElement.scrollTop >= 100
7756
- ) {
7757
- FeaturedSearch.classList.add("hidden-up");
7758
- } else {
7759
- FeaturedSearch.classList.remove("hidden-up");
7760
- }
7761
- }
7762
- }
7763
- });
7764
-
7765
- // search box top position if browser window is resized
7766
- window.addEventListener("resize", () => {
7767
- setSearchTop();
7768
- setSearchContainerAriaHidden();
7769
- });
7739
+ if (searchContainer || searchbox) {
7740
+ // search box top position if browser window is resized
7741
+ window.addEventListener("resize", () => {
7742
+ setSearchTop();
7743
+ setSearchContainerAriaHidden();
7744
+ });
7745
+ }
7770
7746
 
7771
7747
  setSearchContainerAriaHidden();
7772
7748
  });
@@ -7958,70 +7934,61 @@ window.addEventListener("load", () => {
7958
7934
  /**
7959
7935
  * @typedef {Object} ScrollCounter_Properties
7960
7936
  * @property {boolean} counterAlreadyFired
7961
- * @property {number} counterSpeed
7962
- * @property {number} counterTarget
7963
- * @property {number} counterCount
7964
- * @property {number} counterStep
7965
7937
  * @property {()=>void} updateCounter
7966
7938
  * @typedef {HTMLElement & ScrollCounter_Properties} ScrollCounter
7967
7939
  */
7968
7940
 
7969
7941
  document.addEventListener("DOMContentLoaded", () => {
7970
- // You can change this class to specify which elements are going to behave as counters.
7971
7942
  /** @type {NodeListOf<ScrollCounter>} */
7972
7943
  const elements = document.querySelectorAll(".scroll-counter");
7973
7944
 
7974
7945
  elements.forEach(item => {
7975
- // Add new attributes to the elements with the '.scroll-counter' HTML class
7976
7946
  item.counterAlreadyFired = false;
7977
- item.counterSpeed = Number(item.getAttribute("data-counter-time")) / 45;
7978
- item.counterTarget = +item.innerText;
7979
- item.counterCount = 0;
7980
- item.counterStep = item.counterTarget / item.counterSpeed;
7947
+
7948
+ const duration = Number(item.getAttribute("data-counter-time")); // ms
7949
+ const target = +item.textContent; // final number
7981
7950
 
7982
7951
  item.updateCounter = () => {
7983
- item.counterCount += item.counterStep;
7984
- item.innerText = Math.ceil(item.counterCount).toLocaleString();
7952
+ const start = performance.now();
7985
7953
 
7986
- if (item.counterCount < item.counterTarget) {
7987
- window.setTimeout(item.updateCounter, item.counterSpeed);
7988
- } else {
7989
- item.innerText = item.counterTarget.toLocaleString();
7990
- }
7954
+ const animate = now => {
7955
+ const elapsed = now - start;
7956
+ const progress = Math.min(elapsed / duration, 1);
7957
+ const current = Math.ceil(progress * target);
7958
+
7959
+ item.textContent = current.toLocaleString();
7960
+
7961
+ if (progress < 1) {
7962
+ requestAnimationFrame(animate);
7963
+ }
7964
+ };
7965
+
7966
+ requestAnimationFrame(animate);
7991
7967
  };
7992
7968
  });
7993
7969
 
7994
- // Function to determine if an element is visible in the web page
7995
- const isElementVisible = (/** @type {Element} */ el) => {
7996
- const scroll = window.scrollY || window.pageYOffset;
7997
- const boundsTop = el.getBoundingClientRect().top + scroll;
7998
- const viewport = {
7999
- top: scroll,
8000
- bottom: scroll + window.innerHeight
8001
- };
8002
- const bounds = {
8003
- top: boundsTop,
8004
- bottom: boundsTop + el.clientHeight
8005
- };
8006
- return (
8007
- (bounds.bottom >= viewport.top && bounds.bottom <= viewport.bottom) ||
8008
- (bounds.top <= viewport.bottom && bounds.top >= viewport.top)
8009
- );
7970
+ // Check if element is visible in viewport
7971
+ const isElementVisible = el => {
7972
+ const rect = el.getBoundingClientRect();
7973
+ return rect.top < window.innerHeight && rect.bottom > 0;
8010
7974
  };
8011
7975
 
8012
- // Funciton that will get fired uppon scrolling
7976
+ // Scroll handler
8013
7977
  const handleScroll = () => {
8014
7978
  elements.forEach(item => {
8015
7979
  if (item.counterAlreadyFired) return;
8016
7980
  if (!isElementVisible(item)) return;
7981
+
8017
7982
  item.updateCounter();
8018
7983
  item.counterAlreadyFired = true;
8019
7984
  });
8020
7985
  };
8021
7986
 
8022
- // Fire the function on load and scroll
7987
+ // Fire once on load and on scroll
8023
7988
  window.addEventListener("load", handleScroll);
8024
- window.addEventListener("scroll", handleScroll);
7989
+ window.addEventListener("scroll", () => {
7990
+ requestAnimationFrame(handleScroll);
7991
+ });
8025
7992
  });
8026
7993
 
8027
7994
  //@ts-check
@@ -8376,7 +8343,7 @@ window.addEventListener("load", () => {
8376
8343
 
8377
8344
  // create on this page label
8378
8345
  const onthispage =
8379
- '<div id="on-this-page-navigation-label" class="label">On this page</div>';
8346
+ '<div id="on-this-page-navigation-label" class="label" lang="en-US">On this page</div>';
8380
8347
  pagenav.innerHTML = onthispage;
8381
8348
 
8382
8349
  // add ul item to the nav and set aria labelledby