components#ProgressCircles TypeScript Examples

The following examples show how to use components#ProgressCircles. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Tutorial.tsx    From mobile with Apache License 2.0 5 votes vote down vote up
TutorialScreen = () => {
  const navigation = useNavigation();
  const {width: viewportWidth} = useWindowDimensions();
  const carouselRef = useRef(null);
  const [currentStep, setCurrentStep] = useState(0);
  const [i18n] = useI18n();
  const close = useCallback(() => navigation.goBack(), [navigation]);

  const isStart = currentStep === 0;
  const isEnd = currentStep === tutorialData.length - 1;

  const renderItem = useCallback<CarouselProps<TutorialKey>['renderItem']>(
    ({item, index}) => {
      return (
        <View style={styles.flex} accessibilityElementsHidden={index !== currentStep}>
          <TutorialContent item={item} isActive={tutorialData[currentStep] === item} />
        </View>
      );
    },
    [currentStep],
  );

  const nextItem = useCallback(() => {
    if (carouselRef.current) {
      if (isEnd) {
        close();
        return;
      }
      (carouselRef.current! as CarouselStatic<TutorialKey>).snapToNext();
    }
  }, [close, isEnd]);

  const prevItem = useCallback(() => {
    if (carouselRef.current) {
      (carouselRef.current! as CarouselStatic<TutorialKey>).snapToPrev();
    }
  }, []);

  return (
    <Box backgroundColor="overlayBackground" flex={1}>
      <SafeAreaView style={styles.flex}>
        <Toolbar
          title=""
          navIcon="icon-back-arrow"
          navText={i18n.translate('Tutorial.Close')}
          navLabel={i18n.translate('Tutorial.Close')}
          onIconClicked={close}
        />
        <Carousel
          ref={carouselRef}
          data={tutorialData}
          renderItem={renderItem}
          sliderWidth={viewportWidth}
          itemWidth={viewportWidth}
          onSnapToItem={newIndex => setCurrentStep(newIndex)}
          importantForAccessibility="no"
          accessible={false}
        />
        <Box flexDirection="row" padding="l">
          <Box flex={1}>
            {!isStart && (
              <Button text={i18n.translate(`Tutorial.ActionBack`)} variant="subduedText" onPress={prevItem} />
            )}
          </Box>
          <Box flex={1} justifyContent="center">
            <ProgressCircles numberOfSteps={tutorialData.length} activeStep={currentStep + 1} marginBottom="none" />
          </Box>
          <Box flex={1}>
            <Button
              text={i18n.translate(`Tutorial.Action${isEnd ? 'End' : 'Next'}`)}
              variant="text"
              onPress={nextItem}
            />
          </Box>
        </Box>
      </SafeAreaView>
    </Box>
  );
}
Example #2
Source File: Onboarding.tsx    From mobile with Apache License 2.0 4 votes vote down vote up
OnboardingScreen = () => {
  const [i18n] = useI18n();
  const [currentIndex, setCurrentIndex] = useState(0);
  const carouselRef = useRef(null);
  const {setOnboarded} = useStorage();
  const navigation = useNavigation();
  const startExposureNotificationService = useStartExposureNotificationService();

  const handlePermissions = useCallback(async () => {
    setOnboarded(true);
    navigation.reset({
      index: 0,
      routes: [{name: 'Home'}],
    });
    await startExposureNotificationService();
  }, [navigation, setOnboarded, startExposureNotificationService]);

  const maxWidth = useMaxContentWidth();

  const renderItem = useCallback(
    ({item}: {item: ViewKey}) => {
      const ItemComponent = viewComponents[item];
      return (
        <Box maxWidth={maxWidth} alignSelf="center">
          <ItemComponent />
        </Box>
      );
    },
    [maxWidth],
  );

  const nextItem = useCallback(() => {
    if (carouselRef.current) {
      if (currentIndex === contentData.length - 1) {
        handlePermissions();
        return;
      }
      (carouselRef.current! as CarouselStatic<ViewKey>).snapToNext();
    }
  }, [currentIndex, handlePermissions]);

  const prevItem = useCallback(() => {
    if (carouselRef.current) {
      (carouselRef.current! as CarouselStatic<ViewKey>).snapToPrev();
    }
  }, []);

  const isStart = currentIndex === 0;
  const isEnd = currentIndex === contentData.length - 1;

  const BackButton = <Button text={i18n.translate('Onboarding.ActionBack')} variant="subduedText" onPress={prevItem} />;
  const LanguageButton = <LanguageToggle />;

  const [layout, setLayout] = useState<LayoutRectangle | undefined>();
  const onLayout = useCallback(({nativeEvent: {layout}}: LayoutChangeEvent) => {
    setLayout(layout);
  }, []);

  return (
    <Box flex={1} backgroundColor="overlayBackground">
      <SafeAreaView style={styles.flex}>
        <Header isOverlay />
        <Box flex={1} justifyContent="center" onLayout={onLayout}>
          {layout && (
            <Carousel
              ref={carouselRef}
              data={contentData}
              renderItem={renderItem}
              sliderWidth={layout.width}
              itemWidth={layout.width}
              itemHeight={layout.height}
              onSnapToItem={newIndex => setCurrentIndex(newIndex)}
            />
          )}
        </Box>
        <Box flexDirection="row" padding="l">
          <Box flex={1}>{isStart ? LanguageButton : BackButton}</Box>
          <Box flex={1} justifyContent="center">
            <ProgressCircles alignSelf="center" numberOfSteps={contentData.length} activeStep={currentIndex + 1} />
          </Box>
          <Box flex={1}>
            <Button
              text={i18n.translate(`Onboarding.Action${isEnd ? 'End' : 'Next'}`)}
              variant="text"
              onPress={nextItem}
            />
          </Box>
        </Box>
      </SafeAreaView>
    </Box>
  );
}
Example #3
Source File: Onboarding.tsx    From mobile with Apache License 2.0 4 votes vote down vote up
OnboardingScreen = () => {
  const navigation = useNavigation();
  const {width: viewportWidth} = useWindowDimensions();
  const carouselRef = useRef<Carousel<OnboardingKey>>(null);
  const [currentStep, setCurrentStep] = useState(0);
  const i18n = useI18n();
  const {setOnboarded, setOnboardedDatetime} = useStorage();
  const startExposureNotificationService = useStartExposureNotificationService();
  const isStart = currentStep === 0;
  const isEnd = currentStep === onboardingData.length - 1;
  const {isScreenReaderEnabled} = useAccessibilityService();
  const currentStepForRenderItem = isScreenReaderEnabled ? currentStep : -1;

  const renderItem: ListRenderItem<OnboardingKey> = useCallback(
    ({item, index}) => {
      return (
        <View style={styles.flex} accessibilityElementsHidden={index !== currentStepForRenderItem}>
          <OnboardingContent key={item} item={item} isActive={index === currentStepForRenderItem} />
        </View>
      );
    },
    [currentStepForRenderItem],
  );

  const onSnapToNewPage = useCallback(
    async (index: number) => {
      // we want the EN permission dialogue to appear on the last step.
      if (index === onboardingData.length - 1) {
        try {
          await startExposureNotificationService();
        } catch (error) {
          if (error.message === 'API_NOT_CONNECTED') {
            navigation.reset({
              index: 0,
              routes: [{name: 'ErrorScreen'}],
            });
          }
        }
      }
    },
    [navigation, startExposureNotificationService],
  );

  const nextItem = useCallback(async () => {
    if (isEnd) {
      await setOnboarded(true);
      await setOnboardedDatetime(getCurrentDate());
      navigation.reset({
        index: 0,
        routes: [{name: 'Home'}],
      });
      return;
    }
    carouselRef.current?.snapToNext();
  }, [isEnd, navigation, setOnboarded, setOnboardedDatetime]);

  const prevItem = useCallback(() => {
    carouselRef.current?.snapToPrev();
  }, []);

  const onSnapToItem = useCallback(
    (newIndex: number) => {
      setCurrentStep(newIndex);
      onSnapToNewPage(newIndex);
    },
    [onSnapToNewPage],
  );

  return (
    <Box backgroundColor="overlayBackground" flex={1}>
      <SafeAreaView style={styles.flex}>
        <View style={styles.flex}>
          <Carousel
            ref={carouselRef}
            data={onboardingData}
            renderItem={renderItem}
            sliderWidth={viewportWidth}
            itemWidth={viewportWidth}
            onSnapToItem={onSnapToItem}
            importantForAccessibility="no"
            accessible={false}
            initialNumToRender={1}
          />
        </View>
        <Box flexDirection="row" borderTopWidth={2} borderTopColor="gray5">
          <Box flex={0} style={{...styles.offset1}}>
            {!isStart && (
              <Button text={i18n.translate(`Onboarding.ActionBack`)} variant="navigation" onPress={prevItem} />
            )}
          </Box>

          <Box flex={2} justifyContent="center" style={{...styles.offset2}}>
            <ProgressCircles numberOfSteps={onboardingData.length} activeStep={currentStep + 1} marginBottom="none" />
          </Box>

          <Box flex={0} style={{...styles.offset3}}>
            <Button
              color="bodyTextWhite"
              testID="onboardingNextButton"
              text={i18n.translate(`Onboarding.Action${isEnd ? 'End' : 'Next'}`)}
              variant="navigation"
              onPress={nextItem}
            />
          </Box>
        </Box>
      </SafeAreaView>
    </Box>
  );
}
Example #4
Source File: Tutorial.tsx    From mobile with Apache License 2.0 4 votes vote down vote up
TutorialScreen = () => {
  const navigation = useNavigation();
  const {width: viewportWidth} = useWindowDimensions();
  const carouselRef = useRef<Carousel<TutorialKey>>(null);
  const [currentStep, setCurrentStep] = useState(0);
  const i18n = useI18n();
  const close = useCallback(() => navigation.goBack(), [navigation]);

  const isStart = currentStep === 0;
  const isEnd = currentStep === tutorialData.length - 1;

  const {isScreenReaderEnabled} = useAccessibilityService();
  const currentStepForRenderItem = isScreenReaderEnabled ? currentStep : -1;

  const renderItem: ListRenderItem<TutorialKey> = useCallback(
    ({item, index}) => {
      return (
        <View style={styles.flex} accessibilityElementsHidden={index !== currentStepForRenderItem}>
          <TutorialContent key={item} item={item} isActive={index === currentStepForRenderItem} />
        </View>
      );
    },
    [currentStepForRenderItem],
  );

  const nextItem = useCallback(() => {
    if (isEnd) {
      close();
      return;
    }
    carouselRef.current?.snapToNext();
  }, [close, isEnd]);

  const prevItem = useCallback(() => {
    carouselRef.current?.snapToPrev();
  }, []);

  const onSnapToItem = useCallback((newIndex: number) => {
    setCurrentStep(newIndex);
  }, []);

  return (
    <Box backgroundColor="overlayBackground" flex={1}>
      <SafeAreaView style={styles.flex}>
        <Toolbar
          title=""
          navIcon="icon-back-arrow"
          navText={i18n.translate('Tutorial.Close')}
          navLabel={i18n.translate('Tutorial.Close')}
          onIconClicked={close}
        />
        <View style={styles.flex}>
          <Carousel
            ref={carouselRef}
            data={tutorialData}
            renderItem={renderItem}
            sliderWidth={viewportWidth}
            itemWidth={viewportWidth}
            onSnapToItem={onSnapToItem}
            importantForAccessibility="no"
            accessible={false}
            removeClippedSubviews={false}
          />
        </View>
        <Box flexDirection="row" borderTopWidth={2} borderTopColor="gray5">
          <Box flex={0} style={{...styles.offset1}}>
            {!isStart && (
              <Button text={i18n.translate(`Tutorial.ActionBack`)} variant="navigation" onPress={prevItem} />
            )}
          </Box>

          <Box flex={2} justifyContent="center" style={{...styles.offset2}}>
            <ProgressCircles numberOfSteps={tutorialData.length} activeStep={currentStep + 1} marginBottom="none" />
          </Box>

          <Box flex={0} style={{...styles.offset3}}>
            <Button
              testID="howItWorksNextButton"
              text={i18n.translate(`Tutorial.Action${isEnd ? 'End' : 'Next'}`)}
              variant="navigation"
              onPress={nextItem}
            />
          </Box>
        </Box>
      </SafeAreaView>
    </Box>
  );
}