Skip to content

Commit

Permalink
feat(www): update tags design, add 'View All Tags' buttons (#10936)
Browse files Browse the repository at this point in the history
  • Loading branch information
LMulvey authored and pieh committed Feb 5, 2019
1 parent 9168d1f commit 368cb72
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 59 deletions.
29 changes: 22 additions & 7 deletions www/src/components/tags-section.js
@@ -1,5 +1,8 @@
import React from "react"
import { Link } from "gatsby"
import TagsIcon from "react-icons/lib/ti/tags"

import Button from "./button"
import { rhythm, scale } from "../utils/typography"
const _ = require(`lodash`)

Expand All @@ -15,15 +18,27 @@ const TagsSection = ({ tags }) => {
)
})
return (
<em
style={{
...scale(-1 / 5),
display: `block`,
marginBottom: rhythm(1),
<div
css={{
display: `flex`,
flexFlow: `row nowrap`,
justifyContent: `space-between`,
alignItems: `baseline`,
}}
>
Tagged with {tagLinks}
</em>
<em
style={{
...scale(-1 / 5),
display: `block`,
marginBottom: rhythm(1),
}}
>
Tagged with {tagLinks}
</em>
<Button tiny key="blog-post-view-all-tags-button" to="/blog/tags">
View All Tags <TagsIcon />
</Button>
</div>
)
}

Expand Down
203 changes: 153 additions & 50 deletions www/src/pages/blog/tags.js
Expand Up @@ -10,60 +10,163 @@ import { Helmet } from "react-helmet"
import { Link } from "gatsby"
import Layout from "../../components/layout"
import Container from "../../components/container"
import SearchIcon from "../../components/search-icon"
import styles from "../../views/shared/styles"
import { colors } from "../../utils/presets"
import { rhythm, options } from "../../utils/typography"

const TagsPage = ({
data: {
allMarkdownRemark: { group },
},
location,
}) => {
const uniqGroup = group.reduce((lookup, tag) => {
const key = kebabCase(tag.fieldValue.toLowerCase())
if (!lookup[key]) {
lookup[key] = Object.assign(tag, {
slug: `/blog/tags/${key}`,
})
let currentLetter = ``

class TagsPage extends React.Component {
static propTypes = {
data: PropTypes.shape({
allMarkdownRemark: PropTypes.shape({
group: PropTypes.arrayOf(
PropTypes.shape({
fieldValue: PropTypes.string.isRequired,
totalCount: PropTypes.number.isRequired,
}).isRequired
),
}),
}),
}

constructor(props) {
super(props)
this.state = {
filterQuery: ``,
}
return lookup
}, {})
}

return (
<Layout location={location}>
<Container>
<Helmet title="Tags" />
<div>
<h1>Tags</h1>
<ul>
{Object.keys(uniqGroup)
.sort((tagA, tagB) => tagA.localeCompare(tagB))
.map(key => {
const tag = uniqGroup[key]
return (
<li key={tag.fieldValue}>
<Link to={tag.slug}>
{tag.fieldValue} ({tag.totalCount})
</Link>
</li>
)
})}
</ul>
</div>
</Container>
</Layout>
)
}
handleChange = ({ target: { name, value } }) => {
currentLetter = ``
this.setState({ [name]: value })
}

TagsPage.propTypes = {
data: PropTypes.shape({
allMarkdownRemark: PropTypes.shape({
group: PropTypes.arrayOf(
PropTypes.shape({
fieldValue: PropTypes.string.isRequired,
totalCount: PropTypes.number.isRequired,
}).isRequired
),
}),
}),
render() {
const {
data: {
allMarkdownRemark: { group },
},
location,
} = this.props
const { filterQuery } = this.state
const uniqGroup = group.reduce((lookup, tag) => {
const key = kebabCase(tag.fieldValue.toLowerCase())
if (!lookup[key]) {
lookup[key] = Object.assign(tag, {
slug: `/blog/tags/${key}`,
})
}
return lookup
}, {})
const results = Object.keys(uniqGroup)
.sort((tagA, tagB) => tagA.localeCompare(tagB))
.filter(key => uniqGroup[key].fieldValue.includes(filterQuery))

return (
<Layout location={location}>
<Container>
<Helmet title="Tags" />
<div>
<div
css={{
display: `flex`,
flexFlow: `row nowrap`,
justifyContent: `space-between`,
alignItems: `center`,
paddingTop: rhythm(options.blockMarginBottom * 2),
paddingBottom: rhythm(options.blockMarginBottom),
borderBottom: `1px solid ${colors.ui.border}`,
}}
>
<h1 css={{ margin: 0 }}>
Tags ({Object.keys(uniqGroup).length || 0})
</h1>
<div>
<label css={{ position: `relative` }}>
<input
css={{
...styles.searchInput,
}}
id="tagsFilter"
name="filterQuery"
type="search"
placeholder="Search tags"
aria-label="Tag Search"
title="Filter tag list"
value={filterQuery}
onChange={this.handleChange}
/>
<SearchIcon
overrideCSS={{
fill: colors.lilac,
position: `absolute`,
left: `5px`,
top: `50%`,
width: `16px`,
height: `16px`,
pointerEvents: `none`,
transform: `translateY(-50%)`,
}}
/>
</label>
</div>
</div>
<ul
css={{
display: `flex`,
flexFlow: `row wrap`,
justifyContent: `start`,
padding: 0,
margin: 0,
}}
>
{results.length > 0 ? (
results.map(key => {
const tag = uniqGroup[key]
const firstLetter = tag.fieldValue.charAt(0).toLowerCase()
const buildTag = (
<li
key={tag.fieldValue}
css={{
padding: `10px 5px`,
margin: `15px`,
listStyleType: `none`,
}}
>
<Link to={tag.slug}>
{tag.fieldValue} ({tag.totalCount})
</Link>
</li>
)

if (currentLetter !== firstLetter) {
currentLetter = firstLetter
return (
<React.Fragment>
<h4 css={{ width: `100%`, flexBasis: `100%` }}>
{currentLetter.toUpperCase()}
</h4>
{buildTag}
</React.Fragment>
)
}
return buildTag
})
) : (
<h4>
No tags found for &quot;
{filterQuery}
&quot; 😔
</h4>
)}
</ul>
</div>
</Container>
</Layout>
)
}
}

export default TagsPage
Expand Down
8 changes: 6 additions & 2 deletions www/src/templates/tags.js
@@ -1,7 +1,9 @@
import React from "react"
import { Link, graphql } from "gatsby"
import { graphql } from "gatsby"
import TagsIcon from "react-icons/lib/ti/tags"

import BlogPostPreviewItem from "../components/blog-post-preview-item"
import Button from "../components/button"
import Container from "../components/container"
import Layout from "../components/layout"
import { rhythm } from "../utils/typography"
Expand All @@ -17,14 +19,16 @@ const Tags = ({ pageContext, data, location }) => {
<Layout location={location}>
<Container>
<h1>{tagHeader}</h1>
<Button tiny key="blog-post-view-all-tags-button" to="/blog/tags">
View All Tags <TagsIcon />
</Button>
{edges.map(({ node }) => (
<BlogPostPreviewItem
post={node}
key={node.fields.slug}
css={{ marginBottom: rhythm(2) }}
/>
))}
<Link to="/blog/tags">All tags</Link>
</Container>
</Layout>
)
Expand Down
14 changes: 14 additions & 0 deletions www/src/templates/template-blog-list.js
@@ -1,8 +1,10 @@
import React from "react"
import { graphql } from "gatsby"
import { Helmet } from "react-helmet"
import TagsIcon from "react-icons/lib/ti/tags"

import Layout from "../components/layout"
import Button from "../components/button"
import Container from "../components/container"
import BlogPostPreviewItem from "../components/blog-post-preview-item"
import Pagination from "../components/pagination"
Expand Down Expand Up @@ -99,6 +101,18 @@ class BlogPostsIndex extends React.Component {
/>
))}
<Pagination context={this.props.pageContext} />
<div
css={{
display: `flex`,
flexFlow: `row nowrap`,
width: `100%`,
justifyContent: `flex-end`,
}}
>
<Button key="blog-view-all-tags-button" to="/blog/tags" small>
View All Tags <TagsIcon />
</Button>
</div>
<EmailCaptureForm signupMessage="Enjoying our blog? Receive the next post in your inbox!" />
</Container>
</main>
Expand Down

0 comments on commit 368cb72

Please sign in to comment.