<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 */

'use strict';
const RNTesterPage = require('../../components/RNTesterPage');
const React = require('react');

const infoLog = require('react-native/Libraries/Utilities/infoLog');

const {
  HeaderComponent,
  FooterComponent,
  ItemComponent,
  PlainInput,
  SeparatorComponent,
  Spindicator,
  genItemData,
  pressItem,
  renderSmallSwitchOption,
  renderStackedItem,
} = require('../../components/ListExampleShared');
const {
  Alert,
  Animated,
  Button,
  StyleSheet,
  Text,
  View,
} = require('react-native');

import type {Item} from '../../components/ListExampleShared';

const VIEWABILITY_CONFIG = {
  minimumViewTime: 3000,
  viewAreaCoveragePercentThreshold: 100,
  waitForInteraction: true,
};

const renderSectionHeader = ({section}) => (
  <View style={styles.header}>
    <Text style={styles.headerText}>SECTION HEADER: {section.key}</Text>
    <SeparatorComponent />
  </View>
);

const renderSectionFooter = ({section}) => (
  <View style={styles.header}>
    <Text style={styles.headerText}>SECTION FOOTER: {section.key}</Text>
    <SeparatorComponent />
  </View>
);

const CustomSeparatorComponent = ({highlighted, text}) => (
  <View
    style={[
      styles.customSeparator,
      highlighted && {backgroundColor: 'rgb(217, 217, 217)'},
    ]}>
    <Text style={styles.separatorText}>{text}</Text>
  </View>
);

class SectionListExample extends React.PureComponent<{...}, $FlowFixMeState> {
  state:
    | any
    | {|
        data: Array<Item>,
        debug: boolean,
        filterText: string,
        inverted: boolean,
        logViewable: boolean,
        virtualized: boolean,
      |} = {
    data: genItemData(1000),
    debug: false,
    filterText: '',
    logViewable: false,
    virtualized: true,
    inverted: false,
  };

  _scrollPos = new Animated.Value(0);
  _scrollSinkY = Animated.event(
    [{nativeEvent: {contentOffset: {y: this._scrollPos}}}],
    {useNativeDriver: true},
  );

  _sectionListRef: ?React.ElementRef<typeof Animated.SectionList> = null;
  _captureRef = ref => {
    this._sectionListRef = ref;
  };

  _scrollToLocation(sectionIndex: number, itemIndex: number) {
    this._sectionListRef &&
      this._sectionListRef.scrollToLocation({sectionIndex, itemIndex});
  }

  render(): React.Node {
    const filterRegex = new RegExp(String(this.state.filterText), 'i');
    const filter = item =>
      filterRegex.test(item.text) || filterRegex.test(item.title);
    const filteredData = this.state.data.filter(filter);
    const filteredSectionData = [];
    let startIndex = 0;
    const endIndex = filteredData.length - 1;
    for (let ii = 10; ii <= endIndex + 10; ii += 10) {
      filteredSectionData.push({
        key: `${filteredData[startIndex].key} - ${
          filteredData[Math.min(ii - 1, endIndex)].key
        }`,
        data: filteredData.slice(startIndex, ii),
      });
      startIndex = ii;
    }
    return (
      <RNTesterPage noSpacer={true} noScroll={true}>
        <View style={styles.searchRow}>
          <PlainInput
            onChangeText={filterText => {
              this.setState(() => ({filterText}));
            }}
            placeholder="Search..."
            value={this.state.filterText}
          />
          <View style={styles.optionSection}>
            {renderSmallSwitchOption(this, 'virtualized')}
            {renderSmallSwitchOption(this, 'logViewable')}
            {renderSmallSwitchOption(this, 'debug')}
            {renderSmallSwitchOption(this, 'inverted')}
            <Spindicator value={this._scrollPos} />
          </View>
          <View style={styles.scrollToRow}>
            <Text>scroll to:</Text>
            <Button
              title="Item A"
              onPress={() => this._scrollToLocation(2, 1)}
            />
            <Button
              title="Item B"
              onPress={() => this._scrollToLocation(3, 6)}
            />
            <Button
              title="Item C"
              onPress={() => this._scrollToLocation(6, 3)}
            />
          </View>
        </View>
        <SeparatorComponent />
        <Animated.SectionList
          ref={this._captureRef}
          ListHeaderComponent={HeaderComponent}
          ListFooterComponent={FooterComponent}
          SectionSeparatorComponent={info => (
            <CustomSeparatorComponent {...info} text="SECTION SEPARATOR" />
          )}
          ItemSeparatorComponent={info => (
            <CustomSeparatorComponent {...info} text="ITEM SEPARATOR" />
          )}
          debug={this.state.debug}
          inverted={this.state.inverted}
          disableVirtualization={!this.state.virtualized}
          onRefresh={() => Alert.alert('onRefresh: nothing to refresh :P')}
          onScroll={this._scrollSinkY}
          onViewableItemsChanged={this._onViewableItemsChanged}
          refreshing={false}
          renderItem={this._renderItemComponent}
          renderSectionHeader={renderSectionHeader}
          renderSectionFooter={renderSectionFooter}
          stickySectionHeadersEnabled
          sections={[
            {<commit_msg>Added examples for SectionList (#30390)<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 */

'use strict';
const RNTesterPage = require('../../components/RNTesterPage');
const React = require('react');

const infoLog = require('react-native/Libraries/Utilities/infoLog');

const {
  HeaderComponent,
  FooterComponent,
  ItemComponent,
  PlainInput,
  SeparatorComponent,
  Spindicator,
  genItemData,
  pressItem,
  renderSmallSwitchOption,
  renderStackedItem,
} = require('../../components/ListExampleShared');
const {
  Alert,
  Animated,
  Button,
  StyleSheet,
  Text,
  View,
} = require('react-native');

import type {Item} from '../../components/ListExampleShared';

const VIEWABILITY_CONFIG = {
  minimumViewTime: 3000,
  viewAreaCoveragePercentThreshold: 100,
  waitForInteraction: true,
};

const renderSectionHeader = ({section}) => (
  <View style={styles.header}>
    <Text style={styles.headerText}>SECTION HEADER: {section.key}</Text>
    <SeparatorComponent />
  </View>
);

const renderSectionFooter = ({section}) => (
  <View style={styles.header}>
    <Text style={styles.headerText}>SECTION FOOTER: {section.key}</Text>
    <SeparatorComponent />
  </View>
);

const CustomSeparatorComponent = ({highlighted, text}) => (
  <View
    style={[
      styles.customSeparator,
      highlighted && {backgroundColor: 'rgb(217, 217, 217)'},
    ]}>
    <Text style={styles.separatorText}>{text}</Text>
  </View>
);

const EmptySectionList = () => (
  <View style={{alignItems: 'center'}}>
    <Text style={{fontSize: 20}}>This is rendered when the list is empty</Text>
  </View>
);

class SectionListExample extends React.PureComponent<{...}, $FlowFixMeState> {
  state:
    | any
    | {|
        data: Array<Item>,
        debug: boolean,
        filterText: string,
        inverted: boolean,
        logViewable: boolean,
        virtualized: boolean,
      |} = {
    data: genItemData(1000),
    debug: false,
    filterText: '',
    logViewable: false,
    virtualized: true,
    inverted: false,
  };

  _scrollPos = new Animated.Value(0);
  _scrollSinkY = Animated.event(
    [{nativeEvent: {contentOffset: {y: this._scrollPos}}}],
    {useNativeDriver: true},
  );

  _sectionListRef: ?React.ElementRef<typeof Animated.SectionList> = null;
  _captureRef = ref => {
    this._sectionListRef = ref;
  };

  _scrollToLocation(sectionIndex: number, itemIndex: number) {
    this._sectionListRef &&
      this._sectionListRef.scrollToLocation({sectionIndex, itemIndex});
  }

  render(): React.Node {
    const filterRegex = new RegExp(String(this.state.filterText), 'i');
    const filter = item =>
      filterRegex.test(item.text) || filterRegex.test(item.title);
    const filteredData = this.state.data.filter(filter);
    const filteredSectionData = [];
    let startIndex = 0;
    const endIndex = filteredData.length - 1;
    for (let ii = 10; ii <= endIndex + 10; ii += 10) {
      filteredSectionData.push({
        key: `${filteredData[startIndex].key} - ${
          filteredData[Math.min(ii - 1, endIndex)].key
        }`,
        data: filteredData.slice(startIndex, ii),
      });
      startIndex = ii;
    }
    return (
      <RNTesterPage noSpacer={true} noScroll={true}>
        <View style={styles.searchRow}>
          <PlainInput
            onChangeText={filterText => {
              this.setState(() => ({filterText}));
            }}
            placeholder="Search..."
            value={this.state.filterText}
          />
          <View style={styles.optionSection}>
            {renderSmallSwitchOption(this, 'virtualized')}
            {renderSmallSwitchOption(this, 'logViewable')}
            {renderSmallSwitchOption(this, 'debug')}
            {renderSmallSwitchOption(this, 'inverted')}
            <Spindicator value={this._scrollPos} />
          </View>
          <View style={styles.scrollToRow}>
            <Text>scroll to:</Text>
            <Button
              title="Item A"
              onPress={() => this._scrollToLocation(2, 1)}
            />
            <Button
              title="Item B"
              onPress={() => this._scrollToLocation(3, 6)}
            />
            <Button
              title="Item C"
              onPress={() => this._scrollToLocation(6, 3)}
            />
          </View>
        </View>
        <SeparatorComponent />
        <Animated.SectionList
          ref={this._captureRef}
          ListHeaderComponent={HeaderComponent}
          ListFooterComponent={FooterComponent}
          SectionSeparatorComponent={info => (
            <CustomSeparatorComponent {...info} text="SECTION SEPARATOR" />
          )}
          ItemSeparatorComponent={info => (
            <CustomSeparatorComponent {...info} text="ITEM SEPARATOR" />
          )}
          debug={this.state.debug}
          inverted={this.state.inverted}
          disableVirtualization={!this.state.virtualized}
          onRefresh={() => Alert.alert('onRefresh: nothing to refresh :P')}
          onScroll={this._scrollSinkY}
          onViewableItemsChanged={this._onViewableItemsChanged}
          refreshing={false}
          renderItem={this._renderItemComponent}
          renderSectionHeader={renderSectionHeader}
          renderSectionFooter={renderSectionFooter}
          stickySectionHeadersEnabled
          initialNumToRender={10}
          ListEmptyComponent={EmptySectionList}
          onEndReached={() =>
            Alert.alert(
              'onEndReached called',
              'You have reached the end of this list',
            )
          }
          onEndReachedThreshold={0}
          sections={[
            {
{'fraction_non_alphanumeric': 0.1332972582972583, 'fraction_numerical': 0.007395382395382395, 'mean_word_length': 2.5840336134453783, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 103, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2496242', 'n_tokens_mistral': 3208, 'n_tokens_neox': 3158, 'n_words': 623}