Reputation: 2191
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 View
s (one to contain the 'bullet' & the other the list item text) or is their an easier, less cumbersome way?
Upvotes: 54
Views: 77437
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
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
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
Reputation: 4230
One could use the @jsamr/react-native-li
library which is serving this exact purpose.
npm add --save @jsamr/react-native-li @jsamr/counter-style
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
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