Commit 0dcbfc50 authored by Shane Hughes's avatar Shane Hughes
Browse files

Bug 1804726 - Refactor about:welcome transitions. r=emcminn

This patch accomplishes a couple different things in one go.
about:welcome has a feature to allow switching screens by history
navigation. But the screen transitions don't play in that case. There
was also an issue (see bug 1804098) where rounding inconsistencies could
cause 1px gaps to appear in the animated progress bar, because of the
use of transform. By converting the progress bar into a single element
and just modulating its width, we can stop using transform and also
enable transitions for history navigation. Technically, this also allows
us to advance by more than 1 screen without messing up the animations,
though this is not currently used. Incidentally, it simplifies the CSS.

Differential Revision: https://phabricator.services.mozilla.com/D164310
parent 49f01cb7
Loading
Loading
Loading
Loading
+90 −38
Original line number Diff line number Diff line
@@ -174,6 +174,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export */   "MultiStageAboutWelcome": () => (/* binding */ MultiStageAboutWelcome),
/* harmony export */   "SecondaryCTA": () => (/* binding */ SecondaryCTA),
/* harmony export */   "StepsIndicator": () => (/* binding */ StepsIndicator),
/* harmony export */   "ProgressBar": () => (/* binding */ ProgressBar),
/* harmony export */   "WelcomeScreen": () => (/* binding */ WelcomeScreen)
/* harmony export */ });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
@@ -199,6 +200,7 @@ const MultiStageAboutWelcome = props => {
    screens
  } = props;
  const [index, setScreenIndex] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(props.startScreen);
  const [previousOrder, setPreviousOrder] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(-1);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const screenInitials = screens.map(({
      id
@@ -216,26 +218,11 @@ const MultiStageAboutWelcome = props => {

    if (props.updateHistory && index > window.history.state) {
      window.history.pushState(index, "");
    }
  }, [index]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (props.updateHistory) {
      // Switch to the screen tracked in state (null for initial state)
      // or last screen index if a user navigates by pressing back
      // button from about:home
      const handler = ({
        state
      }) => setScreenIndex(Math.min(state, screens.length - 1)); // Handle page load, e.g., going back to about:welcome from about:home

    } // Remember the previous screen index so we can animate the transition

      handler(window.history); // Watch for browser back/forward button navigation events

      window.addEventListener("popstate", handler);
      return () => window.removeEventListener("popstate", handler);
    }

    return false;
  }, []);
    setPreviousOrder(index);
  }, [index]);
  const [flowParams, setFlowParams] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const {
    metricsFlowUri
@@ -273,8 +260,43 @@ const MultiStageAboutWelcome = props => {
        window.AWFinish();
      }
    }, props.transitions ? TRANSITION_OUT_TIME : 0);
  }; // Update top sites with default sites by region when region is available
  };

  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (props.updateHistory) {
      const handleIn = ({
        state
      }) => {
        setTransition(props.transitions ? "in" : "");
        setScreenIndex(Math.min(state, screens.length - 1));
      }; // Switch to the screen tracked in state (null for initial state)
      // or last screen index if a user navigates by pressing back
      // button from about:home


      const handler = history => {
        if (transition === "out") {
          return;
        }

        setTransition(props.transitions ? "out" : "");
        setTimeout(() => handleIn(history), props.transitions ? TRANSITION_OUT_TIME : 0);
      }; // Handle page load, e.g., going back to about:welcome from about:home


      handleIn(window.history);

      if (window.history.state) {
        setPreviousOrder(Math.min(window.history.state, screens.length - 1));
      } // Watch for browser back/forward button navigation events


      window.addEventListener("popstate", handler);
      return () => window.removeEventListener("popstate", handler);
    }

    return false;
  }, []); // Update top sites with default sites by region when region is available

  const [region, setRegion] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
@@ -354,6 +376,7 @@ const MultiStageAboutWelcome = props => {
      isLastCenteredScreen: isLastCenteredScreen,
      stepOrder: stepOrder,
      order: order,
      previousOrder: previousOrder,
      content: screen.content,
      navigate: handleTransition,
      topSites: topSites,
@@ -403,6 +426,21 @@ const StepsIndicator = props => {

  return steps;
};
const ProgressBar = ({
  step,
  previousStep,
  totalNumberOfScreens
}) => {
  const [progress, setProgress] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(previousStep / totalNumberOfScreens);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => setProgress(step / totalNumberOfScreens), [step, totalNumberOfScreens]);
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
    className: "indicator",
    role: "presentation",
    style: {
      width: `${progress * 100}%`
    }
  });
};
class WelcomeScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) {
  constructor(props) {
    super(props);
@@ -524,6 +562,7 @@ class WelcomeScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
      id: this.props.id,
      order: this.props.order,
      stepOrder: this.props.stepOrder,
      previousOrder: this.props.previousOrder,
      activeTheme: this.props.activeTheme,
      activeMultiSelect: this.props.activeMultiSelect,
      setActiveMultiSelect: this.props.setActiveMultiSelect,
@@ -707,6 +746,7 @@ const MultiStageProtonScreen = props => {
    isFirstCenteredScreen: props.isFirstCenteredScreen,
    isLastCenteredScreen: props.isLastCenteredScreen,
    stepOrder: props.stepOrder,
    previousOrder: props.previousOrder,
    autoAdvance: props.autoAdvance,
    isRtamo: props.isRtamo,
    addonName: props.addonName,
@@ -862,6 +902,35 @@ class ProtonScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
    });
  }

  renderStepsIndicator() {
    const currentStep = (this.props.order ?? 0) + 1;
    const previousStep = (this.props.previousOrder ?? -1) + 1;
    const {
      content,
      totalNumberOfScreens: total
    } = this.props;
    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
      className: `steps${content.progress_bar ? " progress-bar" : ""}`,
      "data-l10n-id": "onboarding-welcome-steps-indicator2",
      "data-l10n-args": JSON.stringify({
        current: currentStep,
        total: total ?? 0
      }),
      "data-l10n-attrs": "aria-valuetext",
      role: "meter",
      "aria-valuenow": currentStep,
      "aria-valuemin": 1,
      "aria-valuemax": total
    }, content.progress_bar ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_6__.ProgressBar, {
      step: currentStep,
      previousStep: previousStep,
      totalNumberOfScreens: total
    }) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_6__.StepsIndicator, {
      order: this.props.stepOrder,
      totalNumberOfScreens: total
    }));
  }

  renderSecondarySection(content) {
    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
      className: "section-secondary",
@@ -899,8 +968,7 @@ class ProtonScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
      isRtamo,
      isTheme,
      isFirstCenteredScreen,
      isLastCenteredScreen,
      totalNumberOfScreens: total
      isLastCenteredScreen
    } = this.props;
    const includeNoodles = content.has_noodles; // The default screen position is "center"

@@ -910,7 +978,6 @@ class ProtonScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
    // by checking if screen order is even or odd.

    const screenClassName = isCenterPosition ? this.getScreenClassName(isFirstCenteredScreen, isLastCenteredScreen, includeNoodles, content === null || content === void 0 ? void 0 : content.video_container) : "";
    const currentStep = (this.props.order ?? 0) + 1;
    return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("main", {
      className: `screen ${this.props.id || ""} ${screenClassName} ${textColorClass}`,
      role: "alertdialog",
@@ -963,22 +1030,7 @@ class ProtonScreen extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
      content: content,
      addonName: this.props.addonName,
      handleAction: this.props.handleAction
    })), hideStepsIndicator ? null : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
      className: `steps ${content.progress_bar ? "progress-bar" : ""}`,
      "data-l10n-id": "onboarding-welcome-steps-indicator2",
      "data-l10n-args": JSON.stringify({
        current: currentStep,
        total: total ?? 0
      }),
      "data-l10n-attrs": "aria-valuetext",
      role: "meter",
      "aria-valuenow": currentStep,
      "aria-valuemin": 1,
      "aria-valuemax": total
    }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_6__.StepsIndicator, {
      order: this.props.stepOrder,
      totalNumberOfScreens: total
    })))));
    })), hideStepsIndicator ? null : this.renderStepsIndicator())));
  }

}
+14 −44
Original line number Diff line number Diff line
@@ -311,8 +311,7 @@ html {
    --translate: 30px;
    --rotate: 20deg;
    --scale: 0.4;
    --wipe-scale: 0 1;
    --wipe-opacity: 1;
    --progress-bar-transition: 0.6s width;
  }
  .onboardingContainer:dir(rtl) {
    --scale: -0.4 0.4;
@@ -323,8 +322,7 @@ html {
    --translate: 0;
    --rotate: 0deg;
    --scale: 1;
    --wipe-scale: 1;
    --wipe-opacity: 0;
    --progress-bar-transition: none;
  }
  .onboardingContainer:dir(rtl) {
    --scale: -1 1;
@@ -645,30 +643,6 @@ html {
.onboardingContainer .screen[pos=split] .section-main .main-content .steps.progress-bar {
  width: 400px;
  margin-inline: -35px;
  background-color: color-mix(in srgb, var(--in-content-button-text-color) 25%, transparent);
  transition: none;
  opacity: 1;
  scale: 1;
}
.onboardingContainer .screen[pos=split] .section-main .main-content .steps.progress-bar .indicator {
  width: -moz-available;
  height: 100%;
  margin-inline: -1px;
  scale: 1;
  background: transparent;
  border: 0;
  border-radius: 0;
  opacity: 1;
}
.onboardingContainer .screen[pos=split] .section-main .main-content .steps.progress-bar .indicator.current, .onboardingContainer .screen[pos=split] .section-main .main-content .steps.progress-bar .indicator.complete {
  background-color: var(--checkbox-checked-bgcolor);
}
.onboardingContainer .screen[pos=split] .section-main .main-content .steps.progress-bar .indicator.current {
  transition: var(--transition);
  transform-origin: left;
}
.onboardingContainer .screen[pos=split] .section-main .main-content .steps.progress-bar .indicator.current:dir(rtl) {
  transform-origin: right;
}
@media (prefers-contrast) {
  .onboardingContainer .screen[pos=split] .section-main .main-content {
@@ -676,11 +650,9 @@ html {
  }
  .onboardingContainer .screen[pos=split] .section-main .main-content .steps.progress-bar {
    border-top: 1px solid var(--in-content-page-color);
  }
  .onboardingContainer .screen[pos=split] .section-main .main-content .steps.progress-bar .indicator {
    background-color: var(--in-content-page-background);
  }
  .onboardingContainer .screen[pos=split] .section-main .main-content .steps.progress-bar .indicator.current, .onboardingContainer .screen[pos=split] .section-main .main-content .steps.progress-bar .indicator.complete {
  .onboardingContainer .screen[pos=split] .section-main .main-content .steps.progress-bar .indicator {
    background-color: var(--in-content-accent-color);
  }
}
@@ -1305,18 +1277,20 @@ html {
  height: 6px;
  padding-block: 0;
  margin-block: 42px 0;
  background-color: color-mix(in srgb, var(--in-content-button-text-color) 25%, transparent);
  justify-content: start;
  opacity: 1;
  transition: none;
}
.onboardingContainer .steps.progress-bar .indicator {
  border-radius: 0;
  width: -moz-available;
  height: 100%;
  margin-inline: 0;
}
.onboardingContainer .steps .indicator.current, .onboardingContainer .steps.progress-bar .indicator.complete {
  background-color: var(--checkbox-checked-bgcolor);
  border: 0;
  border-radius: 0;
  opacity: 1;
  border-color: var(--checkbox-checked-bgcolor);
}
.onboardingContainer .steps .indicator.current:last-of-type:first-of-type, .onboardingContainer .steps.progress-bar .indicator.complete:last-of-type:first-of-type {
  opacity: 0;
  transition: var(--progress-bar-transition);
}
.onboardingContainer .primary,
.onboardingContainer .secondary {
@@ -1572,13 +1546,9 @@ html {
  opacity: 0;
  translate: 0 calc(-1 * var(--translate));
}
.onboardingContainer.transition-in .screen:not(.dialog-initial):not([pos=corner]) .steps {
.onboardingContainer.transition-in .screen:not(.dialog-initial):not([pos=corner]) .steps:not(.progress-bar) {
  opacity: 0.2;
}
.onboardingContainer.transition-in .screen[pos=split] .steps.progress-bar .indicator.current {
  scale: var(--wipe-scale);
  opacity: var(--wipe-opacity);
}
.onboardingContainer.transition-in .screen:not([pos=corner]) .welcome-text,
.onboardingContainer.transition-in .screen:not([pos=corner]) .tiles-theme-section,
.onboardingContainer.transition-in .screen:not([pos=corner]) .colorway-text,
@@ -1635,7 +1605,7 @@ html {
  translate: 0 var(--translate);
  transition-delay: 0.3s;
}
.onboardingContainer.transition-out .screen:not(.dialog-last):not([pos=corner]) .steps {
.onboardingContainer.transition-out .screen:not(.dialog-last):not([pos=corner]) .steps:not(.progress-bar) {
  opacity: 0.2;
  transition-delay: 0.5s;
}
+16 −65
Original line number Diff line number Diff line
@@ -112,8 +112,7 @@ html {
    --translate: 30px;
    --rotate: 20deg;
    --scale: 0.4;
    --wipe-scale: 0 1;
    --wipe-opacity: 1;
    --progress-bar-transition: 0.6s width;

    // Scale is used for noodles that can be flipped.
    &:dir(rtl) {
@@ -127,8 +126,7 @@ html {
    --rotate: 0deg;
    --scale: 1;
    // To reduce motion, progress bar fades in instead of wiping in.
    --wipe-scale: 1;
    --wipe-opacity: 0;
    --progress-bar-transition: none;

    &:dir(rtl) {
      --scale: -1 1;
@@ -505,38 +503,6 @@ html {
            &.progress-bar {
              width: $split-section-width;
              margin-inline: -35px;
              background-color: color-mix(in srgb, var(--in-content-button-text-color) 25%, transparent);
              transition: none;
              opacity: 1;
              // Prevent subpixel rendering differences between transitioning
              // and static states that would otherwise occur in RTL layout due
              // to the container and screen's `transform: rotateY(180deg)`
              scale: 1;

              .indicator {
                width: -moz-available;
                height: 100%;
                margin-inline: -1px;
                scale: 1;
                background: transparent;
                border: 0;
                border-radius: 0;
                opacity: 1;

                &.current,
                &.complete {
                  background-color: var(--checkbox-checked-bgcolor);
                }

                &.current {
                  transition: var(--transition);
                  transform-origin: left;

                  &:dir(rtl) {
                    transform-origin: right;
                  }
                }
              }
            }
          }

@@ -545,19 +511,15 @@ html {

            .steps.progress-bar {
              border-top: 1px solid var(--in-content-page-color);

              .indicator {
              background-color: var(--in-content-page-background);

                &.current,
                &.complete {
              .indicator {
                background-color: var(--in-content-accent-color);
              }
            }
          }
        }
      }
      }

      .section-secondary {
        --mr-secondary-position: center center / auto 350px;
@@ -1324,22 +1286,20 @@ html {
      height: 6px;
      padding-block: 0;
      margin-block: 42px 0;
      background-color: color-mix(in srgb, var(--in-content-button-text-color) 25%, transparent);
      justify-content: start;
      opacity: 1;
      transition: none;

      .indicator {
        border-radius: 0;
        width: -moz-available;
        height: 100%;
        margin-inline: 0;
      }
    }

    & .indicator.current,
    &.progress-bar .indicator.complete {
        background-color: var(--checkbox-checked-bgcolor);
        border: 0;
        border-radius: 0;
        opacity: 1;
      border-color: var(--checkbox-checked-bgcolor);

      // This is the only step shown, so visually hide it to maintain spacing.
      &:last-of-type:first-of-type {
        opacity: 0;
        transition: var(--progress-bar-transition);
      }
    }
  }
@@ -1667,20 +1627,11 @@ html {
    }

    .screen:not(.dialog-initial):not([pos='corner']) {
      .steps {
      .steps:not(.progress-bar) {
        opacity: 0.2;
      }
    }

    .screen {
      &[pos='split'] {
        .steps.progress-bar .indicator.current {
          scale: var(--wipe-scale);
          opacity: var(--wipe-opacity);
        }
      }
    }

    .screen:not([pos='corner']) {
      .welcome-text,
      .tiles-theme-section,
@@ -1755,7 +1706,7 @@ html {
        transition-delay: 0.3s;
      }

      .steps {
      .steps:not(.progress-bar) {
        opacity: 0.2;
        transition-delay: 0.5s;
      }
+56 −18
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ export const MultiStageAboutWelcome = props => {
  let { screens } = props;

  const [index, setScreenIndex] = useState(props.startScreen);
  const [previousOrder, setPreviousOrder] = useState(-1);
  useEffect(() => {
    const screenInitials = screens
      .map(({ id }) => id?.split("_")[1]?.[0])
@@ -36,25 +37,10 @@ export const MultiStageAboutWelcome = props => {
    if (props.updateHistory && index > window.history.state) {
      window.history.pushState(index, "");
    }
  }, [index]);

  useEffect(() => {
    if (props.updateHistory) {
      // Switch to the screen tracked in state (null for initial state)
      // or last screen index if a user navigates by pressing back
      // button from about:home
      const handler = ({ state }) =>
        setScreenIndex(Math.min(state, screens.length - 1));

      // Handle page load, e.g., going back to about:welcome from about:home
      handler(window.history);

      // Watch for browser back/forward button navigation events
      window.addEventListener("popstate", handler);
      return () => window.removeEventListener("popstate", handler);
    }
    return false;
  }, []);
    // Remember the previous screen index so we can animate the transition
    setPreviousOrder(index);
  }, [index]);

  const [flowParams, setFlowParams] = useState(null);
  const { metricsFlowUri } = props;
@@ -101,6 +87,39 @@ export const MultiStageAboutWelcome = props => {
    );
  };

  useEffect(() => {
    if (props.updateHistory) {
      const handleIn = ({ state }) => {
        setTransition(props.transitions ? "in" : "");
        setScreenIndex(Math.min(state, screens.length - 1));
      };
      // Switch to the screen tracked in state (null for initial state)
      // or last screen index if a user navigates by pressing back
      // button from about:home
      const handler = history => {
        if (transition === "out") {
          return;
        }
        setTransition(props.transitions ? "out" : "");
        setTimeout(
          () => handleIn(history),
          props.transitions ? TRANSITION_OUT_TIME : 0
        );
      };

      // Handle page load, e.g., going back to about:welcome from about:home
      handleIn(window.history);
      if (window.history.state) {
        setPreviousOrder(Math.min(window.history.state, screens.length - 1));
      }

      // Watch for browser back/forward button navigation events
      window.addEventListener("popstate", handler);
      return () => window.removeEventListener("popstate", handler);
    }
    return false;
  }, []);

  // Update top sites with default sites by region when region is available
  const [region, setRegion] = useState(null);
  useEffect(() => {
@@ -201,6 +220,7 @@ export const MultiStageAboutWelcome = props => {
              isLastCenteredScreen={isLastCenteredScreen}
              stepOrder={stepOrder}
              order={order}
              previousOrder={previousOrder}
              content={screen.content}
              navigate={handleTransition}
              topSites={topSites}
@@ -265,6 +285,23 @@ export const StepsIndicator = props => {
  return steps;
};

export const ProgressBar = ({ step, previousStep, totalNumberOfScreens }) => {
  const [progress, setProgress] = React.useState(
    previousStep / totalNumberOfScreens
  );
  useEffect(() => setProgress(step / totalNumberOfScreens), [
    step,
    totalNumberOfScreens,
  ]);
  return (
    <div
      className="indicator"
      role="presentation"
      style={{ width: `${progress * 100}%` }}
    />
  );
};

export class WelcomeScreen extends React.PureComponent {
  constructor(props) {
    super(props);
@@ -384,6 +421,7 @@ export class WelcomeScreen extends React.PureComponent {
        id={this.props.id}
        order={this.props.order}
        stepOrder={this.props.stepOrder}
        previousOrder={this.props.previousOrder}
        activeTheme={this.props.activeTheme}
        activeMultiSelect={this.props.activeMultiSelect}
        setActiveMultiSelect={this.props.setActiveMultiSelect}
+41 −26
Original line number Diff line number Diff line
@@ -8,7 +8,11 @@ import { Colorways } from "./MRColorways";
import { MobileDownloads } from "./MobileDownloads";
import { MultiSelect } from "./MultiSelect";
import { Themes } from "./Themes";
import { SecondaryCTA, StepsIndicator } from "./MultiStageAboutWelcome";
import {
  SecondaryCTA,
  StepsIndicator,
  ProgressBar,
} from "./MultiStageAboutWelcome";
import { LanguageSwitcher } from "./LanguageSwitcher";
import { CTAParagraph } from "./CTAParagraph";
import { HeroImage } from "./HeroImage";
@@ -44,6 +48,7 @@ export const MultiStageProtonScreen = props => {
      isFirstCenteredScreen={props.isFirstCenteredScreen}
      isLastCenteredScreen={props.isLastCenteredScreen}
      stepOrder={props.stepOrder}
      previousOrder={props.previousOrder}
      autoAdvance={props.autoAdvance}
      isRtamo={props.isRtamo}
      addonName={props.addonName}
@@ -251,6 +256,40 @@ export class ProtonScreen extends React.PureComponent {
    );
  }

  renderStepsIndicator() {
    const currentStep = (this.props.order ?? 0) + 1;
    const previousStep = (this.props.previousOrder ?? -1) + 1;
    const { content, totalNumberOfScreens: total } = this.props;
    return (
      <div
        className={`steps${content.progress_bar ? " progress-bar" : ""}`}
        data-l10n-id={"onboarding-welcome-steps-indicator2"}
        data-l10n-args={JSON.stringify({
          current: currentStep,
          total: total ?? 0,
        })}
        data-l10n-attrs="aria-valuetext"
        role="meter"
        aria-valuenow={currentStep}
        aria-valuemin={1}
        aria-valuemax={total}
      >
        {content.progress_bar ? (
          <ProgressBar
            step={currentStep}
            previousStep={previousStep}
            totalNumberOfScreens={total}
          />
        ) : (
          <StepsIndicator
            order={this.props.stepOrder}
            totalNumberOfScreens={total}
          />
        )}
      </div>
    );
  }

  renderSecondarySection(content) {
    return (
      <div
@@ -300,7 +339,6 @@ export class ProtonScreen extends React.PureComponent {
      isTheme,
      isFirstCenteredScreen,
      isLastCenteredScreen,
      totalNumberOfScreens: total,
    } = this.props;
    const includeNoodles = content.has_noodles;
    // The default screen position is "center"
@@ -323,8 +361,6 @@ export class ProtonScreen extends React.PureComponent {
        )
      : "";

    const currentStep = (this.props.order ?? 0) + 1;

    return (
      <main
        className={`screen ${this.props.id ||
@@ -404,28 +440,7 @@ export class ProtonScreen extends React.PureComponent {
                handleAction={this.props.handleAction}
              />
            </div>
            {hideStepsIndicator ? null : (
              <div
                className={`steps ${
                  content.progress_bar ? "progress-bar" : ""
                }`}
                data-l10n-id={"onboarding-welcome-steps-indicator2"}
                data-l10n-args={JSON.stringify({
                  current: currentStep,
                  total: total ?? 0,
                })}
                data-l10n-attrs="aria-valuetext"
                role="meter"
                aria-valuenow={currentStep}
                aria-valuemin={1}
                aria-valuemax={total}
              >
                <StepsIndicator
                  order={this.props.stepOrder}
                  totalNumberOfScreens={total}
                />
              </div>
            )}
            {hideStepsIndicator ? null : this.renderStepsIndicator()}
          </div>
        </div>
      </main>
Loading