src/components/NewsList.js (50 lines of code) (raw):

import React, {useState} from 'react' import {Box, Flex, Text, StyledOcticon, themeGet} from '@primer/components' import Article, {iconForType} from './Article' import styled from 'styled-components' export default function NewsList({items, defaultFilter, ...rest}) { const [filter, updateFilter] = useState(defaultFilter) const setFilter = value => updateFilter(filter === value ? null : value) const types = items.reduce((types, {type}) => { types.add(type) return types }, new Set()) if (filter) { items = items.filter(item => item.type === filter) } return ( <Box mt={[4, 0]} {...rest}> <Text fontSize={2} fontFamily="mono"> <Flex flexWrap="wrap" mb={[8, 9]} flexDirection={['column', 'column', 'row', 'row']}> <FilterButton mb={[3, 3, 3, 0]} mr={5} onClick={() => setFilter(null)} selected={filter === null}> All </FilterButton> {Array.from(types) .sort() .map(type => ( <FilterButton mb={[3, 3, 3, 0]} mr={5} onClick={() => setFilter(type)} key={type} selected={filter === type} > <StyledOcticon icon={iconForType[type]} size={20} mr={2} /> {`${type.charAt(0).toUpperCase()}${type.slice(1)}`}s </FilterButton> ))} </Flex> </Text> <Box> {items.map(article => ( <Article {...article} key={article.url} /> ))} </Box> </Box> ) } const FilterButton = styled(props => { return ( <Flex alignItems="center" as="a" {...props} color={props.selected ? 'blue.2' : 'blue.3'}> {props.children} </Flex> ) })` cursor: pointer; &:hover { color: ${props => themeGet(props.selected ? 'colors.blue.2' : 'colors.blue.3')}; text-decoration: ${props => (props.selected ? 'none' : 'underline')}; } `