Steed-Asprey
Steed-Asprey

Reputation: 2191

React Native 'Unordered'-style List

How would one go about creating a list in React Native that looked similar to an unordered list (<ul>) in HTML? Does it require a flex based layout with two Views (one to contain the 'bullet' & the other the list item text) or is their an easier, less cumbersome way?

Upvotes: 54

Views: 77437

Answers (5)

HARSH GADA
HARSH GADA

Reputation: 31

Consider you a list called "ListItems", holding all the content you want in the unordered list, we can approach this problem as follows. This will give you the required format.

       <View>
          {ListItems.map(
            (item, index) => (
              <Text>
                {"\u2B24" + " "}
                {item}
              </Text>
            )
          )}
        </View>

Upvotes: 3

Prithin Babu
Prithin Babu

Reputation: 376

You could also try using a View, set it with a Text component inside a View with flexDirection: 'row'

<View style={{height:5, width: 5, backgroundColor: '#000', borderRadius: 20}} />

if you use Unicode, you won't be able to change the size or color, so I believe it would be better to use it like this

Upvotes: 0

Natesh bhat
Natesh bhat

Reputation: 13202

You can use this component for this purpose : Enjoy 🥳😇

export const UnorderedList = ({texts}: {texts: string[]}) => {
  return (
    <Column>
      {texts.map((t, index) => (
        <Row key={index}>
          <Column
            style={{
              alignSelf: 'flex-start',
              justifyContent: 'flex-start',
              marginRight: 12,
              transform: [{scale: 2.5}],
            }}>
            <Text
              style={{
                alignSelf: 'flex-start',
                justifyContent: 'flex-start',
              }}>
              {'\u2022'}
            </Text>
          </Column>
          <Column>
            <Text>{t}</Text>
          </Column>
        </Row>
      ))}
    </Column>
  );
};


const Column = ({children,style})=>{
   return <View
      style={[{display: 'flex', flexDirection: 'column'},style]}>
      {children}
    </View>
}

const Row = ({children,style})=>{
   return <View
      style={[{display: 'flex', flexDirection: 'row'},style]}>
      {children}
    </View>
}

Upvotes: 7

Jules Sam. Randolph
Jules Sam. Randolph

Reputation: 4230

One could use the @jsamr/react-native-li library which is serving this exact purpose.

Features

  • Supports over 40 ordered and unordered pre-defined markers
  • Easy to define new markers with a JS-based CSS Counter Styles Level 3 API
  • Right-to-left mode

Install

npm add --save @jsamr/react-native-li @jsamr/counter-style

Usage

Children of the MarkedList component will be wrapped in a marked view:

import React from 'react';
import { ScrollView, StyleSheet, Text } from 'react-native';
import disc from '@jsamr/counter-style/presets/disc';
import MarkedList from '@jsamr/react-native-li';

export default function App() {
  return (
    <ScrollView style={{ flexGrow: 1 }}>
      <MarkedList counterRenderer={disc}>
        {[...Array(100).keys()].map((index) => (
          <Text key={index} style={{ flexShrink: 1 }}>
            The World Wide Web Consortium (W3C)
            develops international standards
            for the web and HTML, CSS, and more.
          </Text>
        ))}
      </MarkedList>
    </ScrollView>
  );
}

Remark: “Marker” is CSS terminology for the ordered prefix.

Upvotes: 1

Michael Helvey
Michael Helvey

Reputation: 4023

Potentially, the easiest way would be just to use a unicode character for the bullet. That way you don't have wrap a bunch of components together.

For example, the following component that uses a ListView (see the renderRow function for the bullet):

class TestProject extends React.Component {

  constructor() {
    super();
    this.state = {
      dataSource: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
      }).cloneWithRows(['string1', 'string2', 'string3']),
    };
  }

  renderRow(data) {
    return (
      <Text>{`\u2022 ${data}`}</Text>
    );
  }

  render() {
    return (
      <ListView
        style={{margin: 40}}
        dataSource={this.state.dataSource}
        renderRow={this.renderRow}
      />
    );
  }
}

If you need to keep the text from wrapping around the bullet, you will actually need to use multiple components, as suggested in the question. For example:

renderRow(data) {
  return (
    <View style={{flexDirection: 'row'}}>
      <Text>{'\u2022'}</Text>
      <Text style={{flex: 1, paddingLeft: 5}}>{data}</Text>
    </View>
  );
}

Upvotes: 98

Related Questions