@biggive/components 202311241148.0.0 → 202312041141.0.0

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.
@@ -1041,6 +1041,7 @@ const biggiveMainMenuCss = "a{color:inherit;text-decoration:underline}a:hover{te
1041
1041
  const BiggiveMainMenu = class {
1042
1042
  constructor(hostRef) {
1043
1043
  index.registerInstance(this, hostRef);
1044
+ this.lastOffsetHeight = 0;
1044
1045
  this.openMobileMenu = () => {
1045
1046
  const mobileMenu = this.host.shadowRoot.querySelector('.nav-links');
1046
1047
  mobileMenu.style.left = '0';
@@ -1062,6 +1063,12 @@ const BiggiveMainMenu = class {
1062
1063
  event.preventDefault();
1063
1064
  }
1064
1065
  setHeaderSize() {
1066
+ if (this.host.offsetHeight === this.lastOffsetHeight) {
1067
+ // Some browsers fire 'resize' overzealously on scroll; we don't want to cause extra paints if nothing
1068
+ // relevant changed.
1069
+ return;
1070
+ }
1071
+ this.lastOffsetHeight = this.host.offsetHeight;
1065
1072
  // Some resize edge cases lead Firefox, and maybe others, to go haywire and get a host offset
1066
1073
  // height of millions of pixels, presumably due to a layout logic loop. So for as long as we use
1067
1074
  // this body padding workaround, we need a safe maximum value, currently 130px, beyond which
@@ -1626,11 +1633,12 @@ const BiggiveTimelineEntry = class {
1626
1633
  };
1627
1634
  BiggiveTimelineEntry.style = biggiveTimelineEntryCss;
1628
1635
 
1629
- const biggiveTotalizerCss = "a{color:inherit;text-decoration:underline}a:hover{text-decoration:none}.background-colour-hover-primary:hover,.background-colour-primary{background-color:#2C089B}.background-colour-hover-secondary:hover,.background-colour-secondary{background-color:#2AF135}.background-colour-hover-tertiary:hover,.background-colour-tertiary{background-color:#FF7272}.background-colour-hover-brand-1:hover,.background-colour-brand-1{background-color:#B30510}.background-colour-hover-brand-2:hover,.background-colour-brand-2{background-color:#6E0887}.background-colour-hover-brand-3:hover,.background-colour-brand-3{background-color:#50B400}.background-colour-hover-brand-4:hover,.background-colour-brand-4{background-color:#FFE500}.background-colour-hover-brand-5:hover,.background-colour-brand-5{background-color:#F07D00}.background-colour-hover-brand-cc-red:hover,.background-colour-brand-cc-red{background-color:#B30510}.background-colour-hover-brand-wgmf-purple:hover,.background-colour-brand-wgmf-purple{background-color:#6E0887}.background-colour-hover-brand-gmf-green:hover,.background-colour-brand-gmf-green{background-color:#50B400}.background-colour-hover-brand-emf-yellow:hover,.background-colour-brand-emf-yellow{background-color:#FFE500}.background-colour-hover-brand-c4c-orange:hover,.background-colour-brand-c4c-orange{background-color:#F07D00}.background-colour-hover-brand-afa-pink:hover,.background-colour-brand-afa-pink{background-color:#BF387D}.background-colour-hover-brand-mhf-turquoise:hover,.background-colour-brand-mhf-turquoise{background-color:#62CFC9}.background-colour-hover-brand-grey:hover,.background-colour-brand-grey{background-color:#CBC8C8}.background-colour-hover-white:hover,.background-colour-white{background-color:#FFFFFF}.background-colour-hover-black:hover,.background-colour-black{background-color:#000000}.background-colour-hover-grey-extra-light:hover,.background-colour-grey-extra-light{background-color:#D7D7D7}.background-colour-hover-grey-light:hover,.background-colour-grey-light{background-color:#E8E8E8}.background-colour-hover-grey-medium:hover,.background-colour-grey-medium{background-color:#8A8A8A}.background-colour-hover-grey-dark:hover,.background-colour-grey-dark{background-color:#4A4A4A}.background-colour-hover-brand-6:hover,.background-colour-brand-6{background-color:#62CFC9}.space-above-0{margin-top:0}.space-above-1{margin-top:5px}.space-above-2{margin-top:10px}.space-above-3{margin-top:15px}.space-above-4{margin-top:30px}.space-above-5{margin-top:45px}.space-above-6{margin-top:60px}.space-below-0{margin-bottom:0}.space-below-1{margin-bottom:5px}.space-below-2{margin-bottom:10px}.space-below-3{margin-bottom:15px}.space-below-4{margin-bottom:30px}.space-below-5{margin-bottom:45px}.space-below-6{margin-bottom:60px}.text-colour-hover-primary:hover,.text-colour-primary{color:#2C089B}.text-colour-hover-secondary:hover,.text-colour-secondary{color:#2AF135}.text-colour-hover-tertiary:hover,.text-colour-tertiary{color:#FF7272}.text-colour-hover-brand-1:hover,.text-colour-brand-1{color:#B30510}.text-colour-hover-brand-2:hover,.text-colour-brand-2{color:#6E0887}.text-colour-hover-brand-3:hover,.text-colour-brand-3{color:#50B400}.text-colour-hover-brand-4:hover,.text-colour-brand-4{color:#FFE500}.text-colour-hover-brand-5:hover,.text-colour-brand-5{color:#F07D00}.text-colour-hover-brand-cc-red:hover,.text-colour-brand-cc-red{color:#B30510}.text-colour-hover-brand-wgmf-purple:hover,.text-colour-brand-wgmf-purple{color:#6E0887}.text-colour-hover-brand-gmf-green:hover,.text-colour-brand-gmf-green{color:#50B400}.text-colour-hover-brand-emf-yellow:hover,.text-colour-brand-emf-yellow{color:#FFE500}.text-colour-hover-brand-c4c-orange:hover,.text-colour-brand-c4c-orange{color:#F07D00}.text-colour-hover-brand-afa-pink:hover,.text-colour-brand-afa-pink{color:#BF387D}.text-colour-hover-brand-mhf-turquoise:hover,.text-colour-brand-mhf-turquoise{color:#62CFC9}.text-colour-hover-brand-grey:hover,.text-colour-brand-grey{color:#CBC8C8}.text-colour-hover-white:hover,.text-colour-white{color:#FFFFFF}.text-colour-hover-black:hover,.text-colour-black{color:#000000}.text-colour-hover-grey-extra-light:hover,.text-colour-grey-extra-light{color:#D7D7D7}.text-colour-hover-grey-light:hover,.text-colour-grey-light{color:#E8E8E8}.text-colour-hover-grey-medium:hover,.text-colour-grey-medium{color:#8A8A8A}.text-colour-hover-grey-dark:hover,.text-colour-grey-dark{color:#4A4A4A}.text-colour-hover-brand-6:hover,.text-colour-brand-6{color:#CBC8C8}:host{display:contents;font-family:\"Euclid Triangle\", sans-serif;font-size:17px;line-height:24px}@keyframes ticker{0%{transform:translate3d(0, 0, 0)}100%{transform:translate3d(-200%, 0, 0)}}.container{position:absolute;left:0;right:0;z-index:1}.container .main-message-wrap{position:absolute;z-index:1;padding:10px 30px;left:0;top:0;font-size:24px;line-height:30px;font-weight:600;max-width:33.3%}.container .ticker-wrap{padding:10px 0 10px 0;min-height:17px;font-size:17px;line-height:24px;overflow:hidden;position:relative}.container .ticker-wrap .sleeve{will-change:transform;width:100%;position:absolute;left:100%;display:flex;animation-iteration-count:infinite;animation-timing-function:linear;animation-name:ticker;animation-duration:10s}@media (prefers-reduced-motion){.container .ticker-wrap .sleeve{animation-name:none}}.container .ticker-wrap .sleeve .ticker-item{white-space:nowrap;padding:0 15px}.container .ticker-wrap .sleeve.sleeve-delayed-copy{animation-delay:5s}@media screen and (max-width: 768px){.container .main-message-wrap{font-size:17px;line-height:24px;padding:10px}}";
1636
+ const biggiveTotalizerCss = "a{color:inherit;text-decoration:underline}a:hover{text-decoration:none}.background-colour-hover-primary:hover,.background-colour-primary{background-color:#2C089B}.background-colour-hover-secondary:hover,.background-colour-secondary{background-color:#2AF135}.background-colour-hover-tertiary:hover,.background-colour-tertiary{background-color:#FF7272}.background-colour-hover-brand-1:hover,.background-colour-brand-1{background-color:#B30510}.background-colour-hover-brand-2:hover,.background-colour-brand-2{background-color:#6E0887}.background-colour-hover-brand-3:hover,.background-colour-brand-3{background-color:#50B400}.background-colour-hover-brand-4:hover,.background-colour-brand-4{background-color:#FFE500}.background-colour-hover-brand-5:hover,.background-colour-brand-5{background-color:#F07D00}.background-colour-hover-brand-cc-red:hover,.background-colour-brand-cc-red{background-color:#B30510}.background-colour-hover-brand-wgmf-purple:hover,.background-colour-brand-wgmf-purple{background-color:#6E0887}.background-colour-hover-brand-gmf-green:hover,.background-colour-brand-gmf-green{background-color:#50B400}.background-colour-hover-brand-emf-yellow:hover,.background-colour-brand-emf-yellow{background-color:#FFE500}.background-colour-hover-brand-c4c-orange:hover,.background-colour-brand-c4c-orange{background-color:#F07D00}.background-colour-hover-brand-afa-pink:hover,.background-colour-brand-afa-pink{background-color:#BF387D}.background-colour-hover-brand-mhf-turquoise:hover,.background-colour-brand-mhf-turquoise{background-color:#62CFC9}.background-colour-hover-brand-grey:hover,.background-colour-brand-grey{background-color:#CBC8C8}.background-colour-hover-white:hover,.background-colour-white{background-color:#FFFFFF}.background-colour-hover-black:hover,.background-colour-black{background-color:#000000}.background-colour-hover-grey-extra-light:hover,.background-colour-grey-extra-light{background-color:#D7D7D7}.background-colour-hover-grey-light:hover,.background-colour-grey-light{background-color:#E8E8E8}.background-colour-hover-grey-medium:hover,.background-colour-grey-medium{background-color:#8A8A8A}.background-colour-hover-grey-dark:hover,.background-colour-grey-dark{background-color:#4A4A4A}.background-colour-hover-brand-6:hover,.background-colour-brand-6{background-color:#62CFC9}.space-above-0{margin-top:0}.space-above-1{margin-top:5px}.space-above-2{margin-top:10px}.space-above-3{margin-top:15px}.space-above-4{margin-top:30px}.space-above-5{margin-top:45px}.space-above-6{margin-top:60px}.space-below-0{margin-bottom:0}.space-below-1{margin-bottom:5px}.space-below-2{margin-bottom:10px}.space-below-3{margin-bottom:15px}.space-below-4{margin-bottom:30px}.space-below-5{margin-bottom:45px}.space-below-6{margin-bottom:60px}.text-colour-hover-primary:hover,.text-colour-primary{color:#2C089B}.text-colour-hover-secondary:hover,.text-colour-secondary{color:#2AF135}.text-colour-hover-tertiary:hover,.text-colour-tertiary{color:#FF7272}.text-colour-hover-brand-1:hover,.text-colour-brand-1{color:#B30510}.text-colour-hover-brand-2:hover,.text-colour-brand-2{color:#6E0887}.text-colour-hover-brand-3:hover,.text-colour-brand-3{color:#50B400}.text-colour-hover-brand-4:hover,.text-colour-brand-4{color:#FFE500}.text-colour-hover-brand-5:hover,.text-colour-brand-5{color:#F07D00}.text-colour-hover-brand-cc-red:hover,.text-colour-brand-cc-red{color:#B30510}.text-colour-hover-brand-wgmf-purple:hover,.text-colour-brand-wgmf-purple{color:#6E0887}.text-colour-hover-brand-gmf-green:hover,.text-colour-brand-gmf-green{color:#50B400}.text-colour-hover-brand-emf-yellow:hover,.text-colour-brand-emf-yellow{color:#FFE500}.text-colour-hover-brand-c4c-orange:hover,.text-colour-brand-c4c-orange{color:#F07D00}.text-colour-hover-brand-afa-pink:hover,.text-colour-brand-afa-pink{color:#BF387D}.text-colour-hover-brand-mhf-turquoise:hover,.text-colour-brand-mhf-turquoise{color:#62CFC9}.text-colour-hover-brand-grey:hover,.text-colour-brand-grey{color:#CBC8C8}.text-colour-hover-white:hover,.text-colour-white{color:#FFFFFF}.text-colour-hover-black:hover,.text-colour-black{color:#000000}.text-colour-hover-grey-extra-light:hover,.text-colour-grey-extra-light{color:#D7D7D7}.text-colour-hover-grey-light:hover,.text-colour-grey-light{color:#E8E8E8}.text-colour-hover-grey-medium:hover,.text-colour-grey-medium{color:#8A8A8A}.text-colour-hover-grey-dark:hover,.text-colour-grey-dark{color:#4A4A4A}.text-colour-hover-brand-6:hover,.text-colour-brand-6{color:#CBC8C8}:host{display:contents;font-family:\"Euclid Triangle\", sans-serif;font-size:17px;line-height:24px;--ticker-end-left:-100%}@keyframes ticker{0%{transform:translate3d(0, 0, 0)}100%{transform:translate3d(var(--ticker-end-left), 0, 0)}}.container{position:absolute;left:0;right:0;z-index:1}.container .main-message-wrap{position:absolute;z-index:1;padding:10px 30px;left:0;top:0;font-size:24px;line-height:30px;font-weight:600;max-width:33.3%}.container .ticker-wrap{font-size:17px;line-height:24px;padding:6px 30px 10px 0;min-height:17px;overflow:hidden;position:relative}.container .ticker-wrap .sleeve{will-change:transform;position:absolute;display:flex;min-width:100%;left:100%;animation-iteration-count:infinite;animation-timing-function:linear;animation-name:ticker;animation-duration:10s}@media (prefers-reduced-motion){.container .ticker-wrap .sleeve{animation-name:none !important}}.container .ticker-wrap .sleeve ::slotted([slot=ticker-items]){display:inline-flex;white-space:nowrap;max-height:24px}.container .ticker-wrap .sleeve-delayed-copy{display:none;white-space:nowrap;max-height:24px}@media screen and (max-width: 768px){.container .main-message-wrap{font-size:17px;line-height:24px;padding:10px}}";
1630
1637
 
1631
1638
  const BiggiveTotalizer = class {
1632
1639
  constructor(hostRef) {
1633
1640
  index.registerInstance(this, hostRef);
1641
+ this.lastWrapperWidth = 0;
1634
1642
  this.spaceBelow = 0;
1635
1643
  this.primaryColour = 'primary';
1636
1644
  this.primaryTextColour = 'white';
@@ -1638,64 +1646,82 @@ const BiggiveTotalizer = class {
1638
1646
  this.secondaryTextColour = 'black';
1639
1647
  this.mainMessage = undefined;
1640
1648
  }
1641
- setSpeed(itemsWidth) {
1642
- var _a, _b;
1643
- const sleeve1 = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap #sleeve_1');
1644
- const sleeve2 = (_b = this.host.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.ticker-wrap #sleeve_2');
1645
- if (!sleeve1 || !sleeve2) {
1646
- console.log('sleeve1 or sleeve2 is missing, skipping setSpeed()');
1649
+ setSpeed(itemsWidth, containerWidth) {
1650
+ var _a;
1651
+ console.log('setSpeed() called with itemsWidth=' + itemsWidth + ', containerWidth=' + containerWidth);
1652
+ if (containerWidth === this.lastWrapperWidth) {
1653
+ // Some browsers fire 'resize' overzealously on scroll; we don't want to cause extra paints if nothing
1654
+ // relevant changed.
1647
1655
  return;
1648
1656
  }
1649
- // Restart the animation(s) on window resize to reduce the chance of jankiness.
1650
- // https://stackoverflow.com/a/45036752/2803757
1651
- sleeve1.style.animationName = 'none';
1652
- sleeve2.style.animationName = 'none';
1653
- const duration = sleeve1.clientWidth / 50;
1654
- sleeve1.style.animationDuration = Math.round(duration) + 's';
1655
- sleeve1.style.animationName = 'ticker';
1656
- // For now, only show the 2nd copy if there's space for it to not overlap. This means
1657
- // a bumpier loop on mobile, but we'd need a tweaked approach to wrap around cleanly
1658
- // where the item lists doesn't fit on the screen twice. The 1.5 ratio is a trial and
1659
- // error number which seems OK for now. It leaves a bit of a gap before items cycle
1660
- // back in at tablet sizes but is an improvement on what we had before at all breakpoints
1661
- // tested.
1662
- if (itemsWidth * 1.5 < sleeve1.clientWidth) {
1663
- sleeve2.style.animationDuration = Math.round(duration) + 's';
1664
- sleeve2.style.animationDelay = Math.round(duration / 2) + 's';
1665
- sleeve2.style.animationName = 'ticker';
1657
+ let sleeves = [];
1658
+ for (const ii in [1, 2, 3, 4]) {
1659
+ const sleeve = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap #sleeve_' + ii);
1660
+ if (sleeve) {
1661
+ sleeves.push(sleeve);
1662
+ // Restart the animation(s) on window resize to reduce the chance of jankiness.
1663
+ // https://stackoverflow.com/a/45036752/2803757
1664
+ sleeve.style.animationName = 'none';
1665
+ }
1666
+ }
1667
+ this.lastWrapperWidth = containerWidth;
1668
+ if (sleeves.length === 0) {
1669
+ console.log('sleeves missing, skipping setSpeed()');
1670
+ return;
1671
+ }
1672
+ // We've seen the initial calculation exclude the ~30px per set of values end padding before,
1673
+ // and it's safe to err on the side of more copies to reduce the chance of abrupt early loop
1674
+ // ends, so we add a buffer of 40px to the calculation when deciding how many copies to use.
1675
+ const sleeveCount = Math.max(1, Math.min(4, Math.ceil((2 * (40 + itemsWidth)) / containerWidth)));
1676
+ this.host.style.setProperty('--ticker-end-left', `-${sleeveCount * 100}%`);
1677
+ const duration = Math.round((itemsWidth / 100) * sleeveCount);
1678
+ for (let ii = 1; ii <= sleeveCount; ii++) {
1679
+ const sleeve = sleeves[ii - 1];
1680
+ if (sleeve) {
1681
+ sleeve.style.animationDuration = duration + 's';
1682
+ // https://stackoverflow.com/a/45847760
1683
+ sleeve.style.animationDelay = (duration * (ii - 1)) / sleeveCount + 's';
1684
+ sleeve.style.display = 'inline-flex';
1685
+ sleeve.style.animationName = 'ticker';
1686
+ }
1666
1687
  }
1667
1688
  }
1668
- componentDidRender() {
1669
- var _a, _b;
1689
+ componentDidLoad() {
1690
+ var _a, _b, _c, _d, _e;
1691
+ const wrapper = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap');
1670
1692
  const tickerItemsInternalWrapper = this.host.querySelector(`[slot="ticker-items"]`);
1671
- const sleeve1 = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap #sleeve_1');
1672
- const sleeve2 = (_b = this.host.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.ticker-wrap #sleeve_2');
1673
- if (!tickerItemsInternalWrapper || !sleeve1 || !sleeve2) {
1674
- console.log('tickerItemsInternalWrapper, sleeve1 or sleeve2 is missing, skipping totalizer animation setup');
1693
+ const sleeve1 = (_b = this.host.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.ticker-wrap #sleeve_1');
1694
+ const sleeve2 = (_c = this.host.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('.ticker-wrap #sleeve_2');
1695
+ const sleeve3 = (_d = this.host.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelector('.ticker-wrap #sleeve_3');
1696
+ const sleeve4 = (_e = this.host.shadowRoot) === null || _e === void 0 ? void 0 : _e.querySelector('.ticker-wrap #sleeve_4');
1697
+ if (!tickerItemsInternalWrapper || !sleeve1) {
1698
+ console.log('tickerItemsInternalWrapper or sleeve1 is missing, skipping totalizer animation setup');
1675
1699
  return;
1676
1700
  }
1677
1701
  // Clone all children of the ticker items internal wrapper and append them, so the ticker can show items without
1678
- // a blank break. Sleeve 2 will animate on a delay per https://stackoverflow.com/a/45847760.
1702
+ // a blank break. Sleeve 2 and up will animate on delays per https://stackoverflow.com/a/45847760.
1679
1703
  tickerItemsInternalWrapper.childNodes.forEach((child) => {
1680
- sleeve2.appendChild(child.cloneNode(true)); // Deep clone all items.
1704
+ sleeve2 && sleeve2.appendChild(child.cloneNode(true)); // Deep clone all items.
1705
+ sleeve3 && sleeve3.appendChild(child.cloneNode(true));
1706
+ sleeve4 && sleeve4.appendChild(child.cloneNode(true));
1681
1707
  });
1682
- if (tickerItemsInternalWrapper !== null && tickerItemsInternalWrapper !== undefined) {
1683
- tickerItemsInternalWrapper.style.display = 'inline-flex';
1684
- tickerItemsInternalWrapper.style.flex = 'none';
1685
- }
1686
- this.setSpeed(tickerItemsInternalWrapper.clientWidth);
1708
+ setTimeout(() => {
1709
+ // In Angular contexts, it seems like we need to leave little time before the calculations work.
1710
+ // Not totally clear why yet.
1711
+ this.setSpeed(tickerItemsInternalWrapper.clientWidth, wrapper.clientWidth);
1712
+ }, 300);
1687
1713
  window.addEventListener('resize', () => {
1688
- this.setSpeed(tickerItemsInternalWrapper.clientWidth);
1714
+ this.setSpeed(tickerItemsInternalWrapper.clientWidth, wrapper.clientWidth);
1689
1715
  });
1690
1716
  }
1691
1717
  render() {
1692
- return (index.h("div", { class: 'container space-below-' + this.spaceBelow }, index.h("div", null, index.h("div", { class: "banner" }, index.h("div", { class: 'main-message-wrap background-colour-' + this.secondaryColour + ' text-colour-' + this.secondaryTextColour }, this.mainMessage), index.h("div", { class: 'ticker-wrap background-colour-' + this.primaryColour + ' text-colour-' + this.primaryTextColour }, index.h("div", { id: "sleeve_1", class: "sleeve" }, index.h("slot", { name: "ticker-items" })), index.h("div", { id: "sleeve_2", class: "sleeve sleeve-delayed-copy" }))))));
1718
+ return (index.h("div", { class: 'container space-below-' + this.spaceBelow }, index.h("div", null, index.h("div", { class: "banner" }, index.h("div", { class: 'main-message-wrap background-colour-' + this.secondaryColour + ' text-colour-' + this.secondaryTextColour }, this.mainMessage), index.h("div", { class: 'ticker-wrap background-colour-' + this.primaryColour + ' text-colour-' + this.primaryTextColour }, index.h("div", { id: "sleeve_1", class: "sleeve" }, index.h("slot", { name: "ticker-items" })), index.h("div", { id: "sleeve_2", class: "sleeve sleeve-delayed-copy" }), index.h("div", { id: "sleeve_3", class: "sleeve sleeve-delayed-copy" }), index.h("div", { id: "sleeve_4", class: "sleeve sleeve-delayed-copy" }))))));
1693
1719
  }
1694
1720
  get host() { return index.getElement(this); }
1695
1721
  };
1696
1722
  BiggiveTotalizer.style = biggiveTotalizerCss;
1697
1723
 
1698
- const biggiveTotalizerTickerItemCss = "a{color:inherit;text-decoration:underline}a:hover{text-decoration:none}:host{display:contents}.ticker-item{margin-right:20px}";
1724
+ const biggiveTotalizerTickerItemCss = "a{color:inherit;text-decoration:underline}a:hover{text-decoration:none}:host{display:contents}.ticker-item{margin-right:30px}";
1699
1725
 
1700
1726
  const BiggiveTotalizerTickerItem = class {
1701
1727
  constructor(hostRef) {
@@ -2,6 +2,7 @@ import { h, Host } from '@stencil/core';
2
2
  import { makeURL } from '../../util/helper-methods';
3
3
  export class BiggiveMainMenu {
4
4
  constructor() {
5
+ this.lastOffsetHeight = 0;
5
6
  this.openMobileMenu = () => {
6
7
  const mobileMenu = this.host.shadowRoot.querySelector('.nav-links');
7
8
  mobileMenu.style.left = '0';
@@ -23,6 +24,12 @@ export class BiggiveMainMenu {
23
24
  event.preventDefault();
24
25
  }
25
26
  setHeaderSize() {
27
+ if (this.host.offsetHeight === this.lastOffsetHeight) {
28
+ // Some browsers fire 'resize' overzealously on scroll; we don't want to cause extra paints if nothing
29
+ // relevant changed.
30
+ return;
31
+ }
32
+ this.lastOffsetHeight = this.host.offsetHeight;
26
33
  // Some resize edge cases lead Firefox, and maybe others, to go haywire and get a host offset
27
34
  // height of millions of pixels, presumably due to a layout logic loop. So for as long as we use
28
35
  // this body padding workaround, we need a safe maximum value, currently 130px, beyond which
@@ -303,6 +303,7 @@ a:hover {
303
303
  font-family: "Euclid Triangle", sans-serif;
304
304
  font-size: 17px;
305
305
  line-height: 24px;
306
+ --ticker-end-left: -100%;
306
307
  }
307
308
 
308
309
  @keyframes ticker {
@@ -310,7 +311,7 @@ a:hover {
310
311
  transform: translate3d(0, 0, 0);
311
312
  }
312
313
  100% {
313
- transform: translate3d(-200%, 0, 0);
314
+ transform: translate3d(var(--ticker-end-left), 0, 0);
314
315
  }
315
316
  }
316
317
  .container {
@@ -331,19 +332,19 @@ a:hover {
331
332
  max-width: 33.3%;
332
333
  }
333
334
  .container .ticker-wrap {
334
- padding: 10px 0 10px 0;
335
- min-height: 17px;
336
335
  font-size: 17px;
337
336
  line-height: 24px;
337
+ padding: 6px 30px 10px 0;
338
+ min-height: 17px;
338
339
  overflow: hidden;
339
340
  position: relative;
340
341
  }
341
342
  .container .ticker-wrap .sleeve {
342
343
  will-change: transform;
343
- width: 100%;
344
344
  position: absolute;
345
- left: 100%;
346
345
  display: flex;
346
+ min-width: 100%;
347
+ left: 100%;
347
348
  animation-iteration-count: infinite;
348
349
  animation-timing-function: linear;
349
350
  animation-name: ticker;
@@ -351,15 +352,18 @@ a:hover {
351
352
  }
352
353
  @media (prefers-reduced-motion) {
353
354
  .container .ticker-wrap .sleeve {
354
- animation-name: none;
355
+ animation-name: none !important;
355
356
  }
356
357
  }
357
- .container .ticker-wrap .sleeve .ticker-item {
358
+ .container .ticker-wrap .sleeve ::slotted([slot=ticker-items]) {
359
+ display: inline-flex;
358
360
  white-space: nowrap;
359
- padding: 0 15px;
361
+ max-height: 24px;
360
362
  }
361
- .container .ticker-wrap .sleeve.sleeve-delayed-copy {
362
- animation-delay: 5s;
363
+ .container .ticker-wrap .sleeve-delayed-copy {
364
+ display: none;
365
+ white-space: nowrap;
366
+ max-height: 24px;
363
367
  }
364
368
 
365
369
  @media screen and (max-width: 768px) {
@@ -1,6 +1,7 @@
1
1
  import { h } from '@stencil/core';
2
2
  export class BiggiveTotalizer {
3
3
  constructor() {
4
+ this.lastWrapperWidth = 0;
4
5
  this.spaceBelow = 0;
5
6
  this.primaryColour = 'primary';
6
7
  this.primaryTextColour = 'white';
@@ -8,59 +9,76 @@ export class BiggiveTotalizer {
8
9
  this.secondaryTextColour = 'black';
9
10
  this.mainMessage = undefined;
10
11
  }
11
- setSpeed(itemsWidth) {
12
- var _a, _b;
13
- const sleeve1 = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap #sleeve_1');
14
- const sleeve2 = (_b = this.host.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.ticker-wrap #sleeve_2');
15
- if (!sleeve1 || !sleeve2) {
16
- console.log('sleeve1 or sleeve2 is missing, skipping setSpeed()');
12
+ setSpeed(itemsWidth, containerWidth) {
13
+ var _a;
14
+ console.log('setSpeed() called with itemsWidth=' + itemsWidth + ', containerWidth=' + containerWidth);
15
+ if (containerWidth === this.lastWrapperWidth) {
16
+ // Some browsers fire 'resize' overzealously on scroll; we don't want to cause extra paints if nothing
17
+ // relevant changed.
17
18
  return;
18
19
  }
19
- // Restart the animation(s) on window resize to reduce the chance of jankiness.
20
- // https://stackoverflow.com/a/45036752/2803757
21
- sleeve1.style.animationName = 'none';
22
- sleeve2.style.animationName = 'none';
23
- sleeve1.offsetHeight;
24
- const duration = sleeve1.clientWidth / 50;
25
- sleeve1.style.animationDuration = Math.round(duration) + 's';
26
- sleeve1.style.animationName = 'ticker';
27
- // For now, only show the 2nd copy if there's space for it to not overlap. This means
28
- // a bumpier loop on mobile, but we'd need a tweaked approach to wrap around cleanly
29
- // where the item lists doesn't fit on the screen twice. The 1.5 ratio is a trial and
30
- // error number which seems OK for now. It leaves a bit of a gap before items cycle
31
- // back in at tablet sizes but is an improvement on what we had before at all breakpoints
32
- // tested.
33
- if (itemsWidth * 1.5 < sleeve1.clientWidth) {
34
- sleeve2.style.animationDuration = Math.round(duration) + 's';
35
- sleeve2.style.animationDelay = Math.round(duration / 2) + 's';
36
- sleeve2.style.animationName = 'ticker';
20
+ let sleeves = [];
21
+ for (const ii in [1, 2, 3, 4]) {
22
+ const sleeve = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap #sleeve_' + ii);
23
+ if (sleeve) {
24
+ sleeves.push(sleeve);
25
+ // Restart the animation(s) on window resize to reduce the chance of jankiness.
26
+ // https://stackoverflow.com/a/45036752/2803757
27
+ sleeve.style.animationName = 'none';
28
+ }
29
+ }
30
+ this.lastWrapperWidth = containerWidth;
31
+ if (sleeves.length === 0) {
32
+ console.log('sleeves missing, skipping setSpeed()');
33
+ return;
34
+ }
35
+ // We've seen the initial calculation exclude the ~30px per set of values end padding before,
36
+ // and it's safe to err on the side of more copies to reduce the chance of abrupt early loop
37
+ // ends, so we add a buffer of 40px to the calculation when deciding how many copies to use.
38
+ const sleeveCount = Math.max(1, Math.min(4, Math.ceil((2 * (40 + itemsWidth)) / containerWidth)));
39
+ this.host.style.setProperty('--ticker-end-left', `-${sleeveCount * 100}%`);
40
+ const duration = Math.round((itemsWidth / 100) * sleeveCount);
41
+ for (let ii = 1; ii <= sleeveCount; ii++) {
42
+ const sleeve = sleeves[ii - 1];
43
+ if (sleeve) {
44
+ sleeve.style.animationDuration = duration + 's';
45
+ // https://stackoverflow.com/a/45847760
46
+ sleeve.style.animationDelay = (duration * (ii - 1)) / sleeveCount + 's';
47
+ sleeve.style.display = 'inline-flex';
48
+ sleeve.style.animationName = 'ticker';
49
+ }
37
50
  }
38
51
  }
39
- componentDidRender() {
40
- var _a, _b;
52
+ componentDidLoad() {
53
+ var _a, _b, _c, _d, _e;
54
+ const wrapper = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap');
41
55
  const tickerItemsInternalWrapper = this.host.querySelector(`[slot="ticker-items"]`);
42
- const sleeve1 = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap #sleeve_1');
43
- const sleeve2 = (_b = this.host.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.ticker-wrap #sleeve_2');
44
- if (!tickerItemsInternalWrapper || !sleeve1 || !sleeve2) {
45
- console.log('tickerItemsInternalWrapper, sleeve1 or sleeve2 is missing, skipping totalizer animation setup');
56
+ const sleeve1 = (_b = this.host.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.ticker-wrap #sleeve_1');
57
+ const sleeve2 = (_c = this.host.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('.ticker-wrap #sleeve_2');
58
+ const sleeve3 = (_d = this.host.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelector('.ticker-wrap #sleeve_3');
59
+ const sleeve4 = (_e = this.host.shadowRoot) === null || _e === void 0 ? void 0 : _e.querySelector('.ticker-wrap #sleeve_4');
60
+ if (!tickerItemsInternalWrapper || !sleeve1) {
61
+ console.log('tickerItemsInternalWrapper or sleeve1 is missing, skipping totalizer animation setup');
46
62
  return;
47
63
  }
48
64
  // Clone all children of the ticker items internal wrapper and append them, so the ticker can show items without
49
- // a blank break. Sleeve 2 will animate on a delay per https://stackoverflow.com/a/45847760.
65
+ // a blank break. Sleeve 2 and up will animate on delays per https://stackoverflow.com/a/45847760.
50
66
  tickerItemsInternalWrapper.childNodes.forEach((child) => {
51
- sleeve2.appendChild(child.cloneNode(true)); // Deep clone all items.
67
+ sleeve2 && sleeve2.appendChild(child.cloneNode(true)); // Deep clone all items.
68
+ sleeve3 && sleeve3.appendChild(child.cloneNode(true));
69
+ sleeve4 && sleeve4.appendChild(child.cloneNode(true));
52
70
  });
53
- if (tickerItemsInternalWrapper !== null && tickerItemsInternalWrapper !== undefined) {
54
- tickerItemsInternalWrapper.style.display = 'inline-flex';
55
- tickerItemsInternalWrapper.style.flex = 'none';
56
- }
57
- this.setSpeed(tickerItemsInternalWrapper.clientWidth);
71
+ setTimeout(() => {
72
+ // In Angular contexts, it seems like we need to leave little time before the calculations work.
73
+ // Not totally clear why yet.
74
+ this.setSpeed(tickerItemsInternalWrapper.clientWidth, wrapper.clientWidth);
75
+ }, 300);
58
76
  window.addEventListener('resize', () => {
59
- this.setSpeed(tickerItemsInternalWrapper.clientWidth);
77
+ this.setSpeed(tickerItemsInternalWrapper.clientWidth, wrapper.clientWidth);
60
78
  });
61
79
  }
62
80
  render() {
63
- return (h("div", { class: 'container space-below-' + this.spaceBelow }, h("div", null, h("div", { class: "banner" }, h("div", { class: 'main-message-wrap background-colour-' + this.secondaryColour + ' text-colour-' + this.secondaryTextColour }, this.mainMessage), h("div", { class: 'ticker-wrap background-colour-' + this.primaryColour + ' text-colour-' + this.primaryTextColour }, h("div", { id: "sleeve_1", class: "sleeve" }, h("slot", { name: "ticker-items" })), h("div", { id: "sleeve_2", class: "sleeve sleeve-delayed-copy" }))))));
81
+ return (h("div", { class: 'container space-below-' + this.spaceBelow }, h("div", null, h("div", { class: "banner" }, h("div", { class: 'main-message-wrap background-colour-' + this.secondaryColour + ' text-colour-' + this.secondaryTextColour }, this.mainMessage), h("div", { class: 'ticker-wrap background-colour-' + this.primaryColour + ' text-colour-' + this.primaryTextColour }, h("div", { id: "sleeve_1", class: "sleeve" }, h("slot", { name: "ticker-items" })), h("div", { id: "sleeve_2", class: "sleeve sleeve-delayed-copy" }), h("div", { id: "sleeve_3", class: "sleeve sleeve-delayed-copy" }), h("div", { id: "sleeve_4", class: "sleeve sleeve-delayed-copy" }))))));
64
82
  }
65
83
  static get is() { return "biggive-totalizer"; }
66
84
  static get encapsulation() { return "shadow"; }
@@ -17,5 +17,5 @@ a:hover {
17
17
  }
18
18
 
19
19
  .ticker-item {
20
- margin-right: 20px;
20
+ margin-right: 30px;
21
21
  }
@@ -10,6 +10,7 @@ const BiggiveMainMenu$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLEle
10
10
  super();
11
11
  this.__registerHost();
12
12
  this.__attachShadow();
13
+ this.lastOffsetHeight = 0;
13
14
  this.openMobileMenu = () => {
14
15
  const mobileMenu = this.host.shadowRoot.querySelector('.nav-links');
15
16
  mobileMenu.style.left = '0';
@@ -31,6 +32,12 @@ const BiggiveMainMenu$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLEle
31
32
  event.preventDefault();
32
33
  }
33
34
  setHeaderSize() {
35
+ if (this.host.offsetHeight === this.lastOffsetHeight) {
36
+ // Some browsers fire 'resize' overzealously on scroll; we don't want to cause extra paints if nothing
37
+ // relevant changed.
38
+ return;
39
+ }
40
+ this.lastOffsetHeight = this.host.offsetHeight;
34
41
  // Some resize edge cases lead Firefox, and maybe others, to go haywire and get a host offset
35
42
  // height of millions of pixels, presumably due to a layout logic loop. So for as long as we use
36
43
  // this body padding workaround, we need a safe maximum value, currently 130px, beyond which
@@ -1,6 +1,6 @@
1
1
  import { proxyCustomElement, HTMLElement, h } from '@stencil/core/internal/client';
2
2
 
3
- const biggiveTotalizerTickerItemCss = "a{color:inherit;text-decoration:underline}a:hover{text-decoration:none}:host{display:contents}.ticker-item{margin-right:20px}";
3
+ const biggiveTotalizerTickerItemCss = "a{color:inherit;text-decoration:underline}a:hover{text-decoration:none}:host{display:contents}.ticker-item{margin-right:30px}";
4
4
 
5
5
  const BiggiveTotalizerTickerItem$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
6
6
  constructor() {
@@ -1,12 +1,13 @@
1
1
  import { proxyCustomElement, HTMLElement, h } from '@stencil/core/internal/client';
2
2
 
3
- const biggiveTotalizerCss = "a{color:inherit;text-decoration:underline}a:hover{text-decoration:none}.background-colour-hover-primary:hover,.background-colour-primary{background-color:#2C089B}.background-colour-hover-secondary:hover,.background-colour-secondary{background-color:#2AF135}.background-colour-hover-tertiary:hover,.background-colour-tertiary{background-color:#FF7272}.background-colour-hover-brand-1:hover,.background-colour-brand-1{background-color:#B30510}.background-colour-hover-brand-2:hover,.background-colour-brand-2{background-color:#6E0887}.background-colour-hover-brand-3:hover,.background-colour-brand-3{background-color:#50B400}.background-colour-hover-brand-4:hover,.background-colour-brand-4{background-color:#FFE500}.background-colour-hover-brand-5:hover,.background-colour-brand-5{background-color:#F07D00}.background-colour-hover-brand-cc-red:hover,.background-colour-brand-cc-red{background-color:#B30510}.background-colour-hover-brand-wgmf-purple:hover,.background-colour-brand-wgmf-purple{background-color:#6E0887}.background-colour-hover-brand-gmf-green:hover,.background-colour-brand-gmf-green{background-color:#50B400}.background-colour-hover-brand-emf-yellow:hover,.background-colour-brand-emf-yellow{background-color:#FFE500}.background-colour-hover-brand-c4c-orange:hover,.background-colour-brand-c4c-orange{background-color:#F07D00}.background-colour-hover-brand-afa-pink:hover,.background-colour-brand-afa-pink{background-color:#BF387D}.background-colour-hover-brand-mhf-turquoise:hover,.background-colour-brand-mhf-turquoise{background-color:#62CFC9}.background-colour-hover-brand-grey:hover,.background-colour-brand-grey{background-color:#CBC8C8}.background-colour-hover-white:hover,.background-colour-white{background-color:#FFFFFF}.background-colour-hover-black:hover,.background-colour-black{background-color:#000000}.background-colour-hover-grey-extra-light:hover,.background-colour-grey-extra-light{background-color:#D7D7D7}.background-colour-hover-grey-light:hover,.background-colour-grey-light{background-color:#E8E8E8}.background-colour-hover-grey-medium:hover,.background-colour-grey-medium{background-color:#8A8A8A}.background-colour-hover-grey-dark:hover,.background-colour-grey-dark{background-color:#4A4A4A}.background-colour-hover-brand-6:hover,.background-colour-brand-6{background-color:#62CFC9}.space-above-0{margin-top:0}.space-above-1{margin-top:5px}.space-above-2{margin-top:10px}.space-above-3{margin-top:15px}.space-above-4{margin-top:30px}.space-above-5{margin-top:45px}.space-above-6{margin-top:60px}.space-below-0{margin-bottom:0}.space-below-1{margin-bottom:5px}.space-below-2{margin-bottom:10px}.space-below-3{margin-bottom:15px}.space-below-4{margin-bottom:30px}.space-below-5{margin-bottom:45px}.space-below-6{margin-bottom:60px}.text-colour-hover-primary:hover,.text-colour-primary{color:#2C089B}.text-colour-hover-secondary:hover,.text-colour-secondary{color:#2AF135}.text-colour-hover-tertiary:hover,.text-colour-tertiary{color:#FF7272}.text-colour-hover-brand-1:hover,.text-colour-brand-1{color:#B30510}.text-colour-hover-brand-2:hover,.text-colour-brand-2{color:#6E0887}.text-colour-hover-brand-3:hover,.text-colour-brand-3{color:#50B400}.text-colour-hover-brand-4:hover,.text-colour-brand-4{color:#FFE500}.text-colour-hover-brand-5:hover,.text-colour-brand-5{color:#F07D00}.text-colour-hover-brand-cc-red:hover,.text-colour-brand-cc-red{color:#B30510}.text-colour-hover-brand-wgmf-purple:hover,.text-colour-brand-wgmf-purple{color:#6E0887}.text-colour-hover-brand-gmf-green:hover,.text-colour-brand-gmf-green{color:#50B400}.text-colour-hover-brand-emf-yellow:hover,.text-colour-brand-emf-yellow{color:#FFE500}.text-colour-hover-brand-c4c-orange:hover,.text-colour-brand-c4c-orange{color:#F07D00}.text-colour-hover-brand-afa-pink:hover,.text-colour-brand-afa-pink{color:#BF387D}.text-colour-hover-brand-mhf-turquoise:hover,.text-colour-brand-mhf-turquoise{color:#62CFC9}.text-colour-hover-brand-grey:hover,.text-colour-brand-grey{color:#CBC8C8}.text-colour-hover-white:hover,.text-colour-white{color:#FFFFFF}.text-colour-hover-black:hover,.text-colour-black{color:#000000}.text-colour-hover-grey-extra-light:hover,.text-colour-grey-extra-light{color:#D7D7D7}.text-colour-hover-grey-light:hover,.text-colour-grey-light{color:#E8E8E8}.text-colour-hover-grey-medium:hover,.text-colour-grey-medium{color:#8A8A8A}.text-colour-hover-grey-dark:hover,.text-colour-grey-dark{color:#4A4A4A}.text-colour-hover-brand-6:hover,.text-colour-brand-6{color:#CBC8C8}:host{display:contents;font-family:\"Euclid Triangle\", sans-serif;font-size:17px;line-height:24px}@keyframes ticker{0%{transform:translate3d(0, 0, 0)}100%{transform:translate3d(-200%, 0, 0)}}.container{position:absolute;left:0;right:0;z-index:1}.container .main-message-wrap{position:absolute;z-index:1;padding:10px 30px;left:0;top:0;font-size:24px;line-height:30px;font-weight:600;max-width:33.3%}.container .ticker-wrap{padding:10px 0 10px 0;min-height:17px;font-size:17px;line-height:24px;overflow:hidden;position:relative}.container .ticker-wrap .sleeve{will-change:transform;width:100%;position:absolute;left:100%;display:flex;animation-iteration-count:infinite;animation-timing-function:linear;animation-name:ticker;animation-duration:10s}@media (prefers-reduced-motion){.container .ticker-wrap .sleeve{animation-name:none}}.container .ticker-wrap .sleeve .ticker-item{white-space:nowrap;padding:0 15px}.container .ticker-wrap .sleeve.sleeve-delayed-copy{animation-delay:5s}@media screen and (max-width: 768px){.container .main-message-wrap{font-size:17px;line-height:24px;padding:10px}}";
3
+ const biggiveTotalizerCss = "a{color:inherit;text-decoration:underline}a:hover{text-decoration:none}.background-colour-hover-primary:hover,.background-colour-primary{background-color:#2C089B}.background-colour-hover-secondary:hover,.background-colour-secondary{background-color:#2AF135}.background-colour-hover-tertiary:hover,.background-colour-tertiary{background-color:#FF7272}.background-colour-hover-brand-1:hover,.background-colour-brand-1{background-color:#B30510}.background-colour-hover-brand-2:hover,.background-colour-brand-2{background-color:#6E0887}.background-colour-hover-brand-3:hover,.background-colour-brand-3{background-color:#50B400}.background-colour-hover-brand-4:hover,.background-colour-brand-4{background-color:#FFE500}.background-colour-hover-brand-5:hover,.background-colour-brand-5{background-color:#F07D00}.background-colour-hover-brand-cc-red:hover,.background-colour-brand-cc-red{background-color:#B30510}.background-colour-hover-brand-wgmf-purple:hover,.background-colour-brand-wgmf-purple{background-color:#6E0887}.background-colour-hover-brand-gmf-green:hover,.background-colour-brand-gmf-green{background-color:#50B400}.background-colour-hover-brand-emf-yellow:hover,.background-colour-brand-emf-yellow{background-color:#FFE500}.background-colour-hover-brand-c4c-orange:hover,.background-colour-brand-c4c-orange{background-color:#F07D00}.background-colour-hover-brand-afa-pink:hover,.background-colour-brand-afa-pink{background-color:#BF387D}.background-colour-hover-brand-mhf-turquoise:hover,.background-colour-brand-mhf-turquoise{background-color:#62CFC9}.background-colour-hover-brand-grey:hover,.background-colour-brand-grey{background-color:#CBC8C8}.background-colour-hover-white:hover,.background-colour-white{background-color:#FFFFFF}.background-colour-hover-black:hover,.background-colour-black{background-color:#000000}.background-colour-hover-grey-extra-light:hover,.background-colour-grey-extra-light{background-color:#D7D7D7}.background-colour-hover-grey-light:hover,.background-colour-grey-light{background-color:#E8E8E8}.background-colour-hover-grey-medium:hover,.background-colour-grey-medium{background-color:#8A8A8A}.background-colour-hover-grey-dark:hover,.background-colour-grey-dark{background-color:#4A4A4A}.background-colour-hover-brand-6:hover,.background-colour-brand-6{background-color:#62CFC9}.space-above-0{margin-top:0}.space-above-1{margin-top:5px}.space-above-2{margin-top:10px}.space-above-3{margin-top:15px}.space-above-4{margin-top:30px}.space-above-5{margin-top:45px}.space-above-6{margin-top:60px}.space-below-0{margin-bottom:0}.space-below-1{margin-bottom:5px}.space-below-2{margin-bottom:10px}.space-below-3{margin-bottom:15px}.space-below-4{margin-bottom:30px}.space-below-5{margin-bottom:45px}.space-below-6{margin-bottom:60px}.text-colour-hover-primary:hover,.text-colour-primary{color:#2C089B}.text-colour-hover-secondary:hover,.text-colour-secondary{color:#2AF135}.text-colour-hover-tertiary:hover,.text-colour-tertiary{color:#FF7272}.text-colour-hover-brand-1:hover,.text-colour-brand-1{color:#B30510}.text-colour-hover-brand-2:hover,.text-colour-brand-2{color:#6E0887}.text-colour-hover-brand-3:hover,.text-colour-brand-3{color:#50B400}.text-colour-hover-brand-4:hover,.text-colour-brand-4{color:#FFE500}.text-colour-hover-brand-5:hover,.text-colour-brand-5{color:#F07D00}.text-colour-hover-brand-cc-red:hover,.text-colour-brand-cc-red{color:#B30510}.text-colour-hover-brand-wgmf-purple:hover,.text-colour-brand-wgmf-purple{color:#6E0887}.text-colour-hover-brand-gmf-green:hover,.text-colour-brand-gmf-green{color:#50B400}.text-colour-hover-brand-emf-yellow:hover,.text-colour-brand-emf-yellow{color:#FFE500}.text-colour-hover-brand-c4c-orange:hover,.text-colour-brand-c4c-orange{color:#F07D00}.text-colour-hover-brand-afa-pink:hover,.text-colour-brand-afa-pink{color:#BF387D}.text-colour-hover-brand-mhf-turquoise:hover,.text-colour-brand-mhf-turquoise{color:#62CFC9}.text-colour-hover-brand-grey:hover,.text-colour-brand-grey{color:#CBC8C8}.text-colour-hover-white:hover,.text-colour-white{color:#FFFFFF}.text-colour-hover-black:hover,.text-colour-black{color:#000000}.text-colour-hover-grey-extra-light:hover,.text-colour-grey-extra-light{color:#D7D7D7}.text-colour-hover-grey-light:hover,.text-colour-grey-light{color:#E8E8E8}.text-colour-hover-grey-medium:hover,.text-colour-grey-medium{color:#8A8A8A}.text-colour-hover-grey-dark:hover,.text-colour-grey-dark{color:#4A4A4A}.text-colour-hover-brand-6:hover,.text-colour-brand-6{color:#CBC8C8}:host{display:contents;font-family:\"Euclid Triangle\", sans-serif;font-size:17px;line-height:24px;--ticker-end-left:-100%}@keyframes ticker{0%{transform:translate3d(0, 0, 0)}100%{transform:translate3d(var(--ticker-end-left), 0, 0)}}.container{position:absolute;left:0;right:0;z-index:1}.container .main-message-wrap{position:absolute;z-index:1;padding:10px 30px;left:0;top:0;font-size:24px;line-height:30px;font-weight:600;max-width:33.3%}.container .ticker-wrap{font-size:17px;line-height:24px;padding:6px 30px 10px 0;min-height:17px;overflow:hidden;position:relative}.container .ticker-wrap .sleeve{will-change:transform;position:absolute;display:flex;min-width:100%;left:100%;animation-iteration-count:infinite;animation-timing-function:linear;animation-name:ticker;animation-duration:10s}@media (prefers-reduced-motion){.container .ticker-wrap .sleeve{animation-name:none !important}}.container .ticker-wrap .sleeve ::slotted([slot=ticker-items]){display:inline-flex;white-space:nowrap;max-height:24px}.container .ticker-wrap .sleeve-delayed-copy{display:none;white-space:nowrap;max-height:24px}@media screen and (max-width: 768px){.container .main-message-wrap{font-size:17px;line-height:24px;padding:10px}}";
4
4
 
5
5
  const BiggiveTotalizer$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
6
6
  constructor() {
7
7
  super();
8
8
  this.__registerHost();
9
9
  this.__attachShadow();
10
+ this.lastWrapperWidth = 0;
10
11
  this.spaceBelow = 0;
11
12
  this.primaryColour = 'primary';
12
13
  this.primaryTextColour = 'white';
@@ -14,58 +15,76 @@ const BiggiveTotalizer$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLEl
14
15
  this.secondaryTextColour = 'black';
15
16
  this.mainMessage = undefined;
16
17
  }
17
- setSpeed(itemsWidth) {
18
- var _a, _b;
19
- const sleeve1 = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap #sleeve_1');
20
- const sleeve2 = (_b = this.host.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.ticker-wrap #sleeve_2');
21
- if (!sleeve1 || !sleeve2) {
22
- console.log('sleeve1 or sleeve2 is missing, skipping setSpeed()');
18
+ setSpeed(itemsWidth, containerWidth) {
19
+ var _a;
20
+ console.log('setSpeed() called with itemsWidth=' + itemsWidth + ', containerWidth=' + containerWidth);
21
+ if (containerWidth === this.lastWrapperWidth) {
22
+ // Some browsers fire 'resize' overzealously on scroll; we don't want to cause extra paints if nothing
23
+ // relevant changed.
23
24
  return;
24
25
  }
25
- // Restart the animation(s) on window resize to reduce the chance of jankiness.
26
- // https://stackoverflow.com/a/45036752/2803757
27
- sleeve1.style.animationName = 'none';
28
- sleeve2.style.animationName = 'none';
29
- const duration = sleeve1.clientWidth / 50;
30
- sleeve1.style.animationDuration = Math.round(duration) + 's';
31
- sleeve1.style.animationName = 'ticker';
32
- // For now, only show the 2nd copy if there's space for it to not overlap. This means
33
- // a bumpier loop on mobile, but we'd need a tweaked approach to wrap around cleanly
34
- // where the item lists doesn't fit on the screen twice. The 1.5 ratio is a trial and
35
- // error number which seems OK for now. It leaves a bit of a gap before items cycle
36
- // back in at tablet sizes but is an improvement on what we had before at all breakpoints
37
- // tested.
38
- if (itemsWidth * 1.5 < sleeve1.clientWidth) {
39
- sleeve2.style.animationDuration = Math.round(duration) + 's';
40
- sleeve2.style.animationDelay = Math.round(duration / 2) + 's';
41
- sleeve2.style.animationName = 'ticker';
26
+ let sleeves = [];
27
+ for (const ii in [1, 2, 3, 4]) {
28
+ const sleeve = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap #sleeve_' + ii);
29
+ if (sleeve) {
30
+ sleeves.push(sleeve);
31
+ // Restart the animation(s) on window resize to reduce the chance of jankiness.
32
+ // https://stackoverflow.com/a/45036752/2803757
33
+ sleeve.style.animationName = 'none';
34
+ }
35
+ }
36
+ this.lastWrapperWidth = containerWidth;
37
+ if (sleeves.length === 0) {
38
+ console.log('sleeves missing, skipping setSpeed()');
39
+ return;
40
+ }
41
+ // We've seen the initial calculation exclude the ~30px per set of values end padding before,
42
+ // and it's safe to err on the side of more copies to reduce the chance of abrupt early loop
43
+ // ends, so we add a buffer of 40px to the calculation when deciding how many copies to use.
44
+ const sleeveCount = Math.max(1, Math.min(4, Math.ceil((2 * (40 + itemsWidth)) / containerWidth)));
45
+ this.host.style.setProperty('--ticker-end-left', `-${sleeveCount * 100}%`);
46
+ const duration = Math.round((itemsWidth / 100) * sleeveCount);
47
+ for (let ii = 1; ii <= sleeveCount; ii++) {
48
+ const sleeve = sleeves[ii - 1];
49
+ if (sleeve) {
50
+ sleeve.style.animationDuration = duration + 's';
51
+ // https://stackoverflow.com/a/45847760
52
+ sleeve.style.animationDelay = (duration * (ii - 1)) / sleeveCount + 's';
53
+ sleeve.style.display = 'inline-flex';
54
+ sleeve.style.animationName = 'ticker';
55
+ }
42
56
  }
43
57
  }
44
- componentDidRender() {
45
- var _a, _b;
58
+ componentDidLoad() {
59
+ var _a, _b, _c, _d, _e;
60
+ const wrapper = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap');
46
61
  const tickerItemsInternalWrapper = this.host.querySelector(`[slot="ticker-items"]`);
47
- const sleeve1 = (_a = this.host.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.ticker-wrap #sleeve_1');
48
- const sleeve2 = (_b = this.host.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.ticker-wrap #sleeve_2');
49
- if (!tickerItemsInternalWrapper || !sleeve1 || !sleeve2) {
50
- console.log('tickerItemsInternalWrapper, sleeve1 or sleeve2 is missing, skipping totalizer animation setup');
62
+ const sleeve1 = (_b = this.host.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.ticker-wrap #sleeve_1');
63
+ const sleeve2 = (_c = this.host.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('.ticker-wrap #sleeve_2');
64
+ const sleeve3 = (_d = this.host.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelector('.ticker-wrap #sleeve_3');
65
+ const sleeve4 = (_e = this.host.shadowRoot) === null || _e === void 0 ? void 0 : _e.querySelector('.ticker-wrap #sleeve_4');
66
+ if (!tickerItemsInternalWrapper || !sleeve1) {
67
+ console.log('tickerItemsInternalWrapper or sleeve1 is missing, skipping totalizer animation setup');
51
68
  return;
52
69
  }
53
70
  // Clone all children of the ticker items internal wrapper and append them, so the ticker can show items without
54
- // a blank break. Sleeve 2 will animate on a delay per https://stackoverflow.com/a/45847760.
71
+ // a blank break. Sleeve 2 and up will animate on delays per https://stackoverflow.com/a/45847760.
55
72
  tickerItemsInternalWrapper.childNodes.forEach((child) => {
56
- sleeve2.appendChild(child.cloneNode(true)); // Deep clone all items.
73
+ sleeve2 && sleeve2.appendChild(child.cloneNode(true)); // Deep clone all items.
74
+ sleeve3 && sleeve3.appendChild(child.cloneNode(true));
75
+ sleeve4 && sleeve4.appendChild(child.cloneNode(true));
57
76
  });
58
- if (tickerItemsInternalWrapper !== null && tickerItemsInternalWrapper !== undefined) {
59
- tickerItemsInternalWrapper.style.display = 'inline-flex';
60
- tickerItemsInternalWrapper.style.flex = 'none';
61
- }
62
- this.setSpeed(tickerItemsInternalWrapper.clientWidth);
77
+ setTimeout(() => {
78
+ // In Angular contexts, it seems like we need to leave little time before the calculations work.
79
+ // Not totally clear why yet.
80
+ this.setSpeed(tickerItemsInternalWrapper.clientWidth, wrapper.clientWidth);
81
+ }, 300);
63
82
  window.addEventListener('resize', () => {
64
- this.setSpeed(tickerItemsInternalWrapper.clientWidth);
83
+ this.setSpeed(tickerItemsInternalWrapper.clientWidth, wrapper.clientWidth);
65
84
  });
66
85
  }
67
86
  render() {
68
- return (h("div", { class: 'container space-below-' + this.spaceBelow }, h("div", null, h("div", { class: "banner" }, h("div", { class: 'main-message-wrap background-colour-' + this.secondaryColour + ' text-colour-' + this.secondaryTextColour }, this.mainMessage), h("div", { class: 'ticker-wrap background-colour-' + this.primaryColour + ' text-colour-' + this.primaryTextColour }, h("div", { id: "sleeve_1", class: "sleeve" }, h("slot", { name: "ticker-items" })), h("div", { id: "sleeve_2", class: "sleeve sleeve-delayed-copy" }))))));
87
+ return (h("div", { class: 'container space-below-' + this.spaceBelow }, h("div", null, h("div", { class: "banner" }, h("div", { class: 'main-message-wrap background-colour-' + this.secondaryColour + ' text-colour-' + this.secondaryTextColour }, this.mainMessage), h("div", { class: 'ticker-wrap background-colour-' + this.primaryColour + ' text-colour-' + this.primaryTextColour }, h("div", { id: "sleeve_1", class: "sleeve" }, h("slot", { name: "ticker-items" })), h("div", { id: "sleeve_2", class: "sleeve sleeve-delayed-copy" }), h("div", { id: "sleeve_3", class: "sleeve sleeve-delayed-copy" }), h("div", { id: "sleeve_4", class: "sleeve sleeve-delayed-copy" }))))));
69
88
  }
70
89
  get host() { return this; }
71
90
  static get style() { return biggiveTotalizerCss; }