Skip to content

Commit

Permalink
Add "Overview" object for use on the Article Listing page (#1406)
Browse files Browse the repository at this point in the history
This PR adds an "Overview" object which is used on the Article Listing pages to show a full list of topics and a search bar. The Article Listings prototype was updated to use this component
  • Loading branch information
Paul-Hebert authored Jul 16, 2021
1 parent 3f415c9 commit 7bce713
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 83 deletions.
5 changes: 5 additions & 0 deletions .changeset/five-turkeys-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cloudfour/patterns': major
---

Renamed the Heading property from `permalink_id` to `id` and allowed you to use `id` when `permalink` is false.
5 changes: 5 additions & 0 deletions .changeset/shaggy-pumpkins-hug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cloudfour/patterns': minor
---

Added Overview object for use in Article Listings
2 changes: 2 additions & 0 deletions src/components/heading/heading.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ The `c-heading` class may include a permalink using [a technique from Marcy Sutt
- `c-heading__content`: The actual semantic heading element (usually `<h1>``<h6>`), including the `id` referenced by `c-heading__permalink`.
- `c-heading__permalink`: The `<a>` element that exposes the permalink to the user. This element is kept separate from the actual heading so it won't disrupt a user's ability to navigate via headings.

You can specify an ID that will be used for the heading (and therefore the permalink hash) using the `id` property. (The `id` property can also be used without permalinking.)

Note that the layout of this pattern is optimized for [our prose containers](/docs/objects-container--prose#prose) with generous horizontal whitespace.

<!--
Expand Down
16 changes: 8 additions & 8 deletions src/components/heading/heading.twig
Original file line number Diff line number Diff line change
Expand Up @@ -47,37 +47,37 @@
{% endset %}

{#
If a `permalink` is desired but no `permalink_id` is specified, we try
creating a `permalink_id` from the value of `content`.
If a `permalink` is desired but no `id` is specified, we try
creating a `id` from the value of `content`.
Since Twig lacks a built-in slugify function, this is pretty fragile and
should be considered a fallback.
#}

{% if permalink and not permalink_id and content is not empty %}
{% set permalink_id = content|lower|escape('url')|replace({'%20': '-'}) %}
{% if permalink and not id and content is not empty %}
{% set id = content|lower|escape('url')|replace({'%20': '-'}) %}
{% endif %}

{#
Permalink heading markup based on this example from accessibility expert
Marcy Sutton: http://codepen.io/marcysutton/pen/rLKvgZ
#}

{% if permalink and permalink_id %}
{% if permalink and id %}
<div class="{{ _heading_class }}">
<a class="c-heading__permalink" href="#{{ permalink_id }}">
<a class="c-heading__permalink" href="#{{ id }}">
{% include '@cloudfour/components/icon/icon.twig' with {
name: 'link',
aria_hidden: 'true'
} only %}
<span class="u-hidden-visually">Permalink to {{ _content }}</span>
</a>
<{{ tag_name }} class="c-heading__content" id="{{ permalink_id }}">
<{{ tag_name }} class="c-heading__content" id="{{ id }}">
{{ _content }}
</{{ tag_name }}>
</div>
{% else %}
<{{ tag_name }} class="{{ _heading_class }}">
<{{ tag_name }} class="{{ _heading_class }}" {% if id %}id="{{id}}"{% endif %}>
{{ _content }}
</{{ tag_name }}>
{% endif %}
40 changes: 40 additions & 0 deletions src/objects/overview/demo/advanced.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{% embed '@cloudfour/objects/overview/overview.twig' with {
labelledby_id: 'more-topics'
} %}
{% block header %}
{% include '@cloudfour/components/heading/heading.twig' with {
level: -1,
weight: "light",
content: 'More Topics',
id: 'more-topics'
} only %}
{% endblock %}
{% block actions %}
{#
In the future we could swap this out for the Input Group component
that's currently in the works.
#}
<label>
<span class="u-hidden-visually">Search</span>
{% include '@cloudfour/components/input/input.twig' %}
</label>
{% endblock %}
{% block content %}
{% embed '@cloudfour/objects/list/list.twig' with {
"tag_name": "ul",
"class": "o-list--2-column@m o-list--3-column@l"
} %}
{% block content %}
{% for topic in topics %}
<li class="u-space-block-end-0">
{% include '@cloudfour/components/dot-leader/dot-leader.twig' with {
label: topic.title,
count: topic.count,
href: 'https://cloudfour.com/thinks/'
} only %}
</li>
{% endfor %}
{% endblock %}
{% endembed %}
{% endblock %}
{% endembed %}
11 changes: 11 additions & 0 deletions src/objects/overview/demo/basic.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{% embed '@cloudfour/objects/overview/overview.twig' %}
{% block header %}
Header
{% endblock %}
{% block actions %}
Actions
{% endblock %}
{% block content %}
Content
{% endblock %}
{% endembed %}
56 changes: 56 additions & 0 deletions src/objects/overview/overview.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
@use "../../compiled/tokens/scss/breakpoint";
@use '../../mixins/ms';
@use "../../compiled/tokens/scss/size";
@use '../../mixins/fluid';

/**
* The Overview stacks content vertically on small screens.
* On large screens the header and actions are stacked horizontally above the content.
* The specific spacing values were inferred from the Article Listing prototype.
*/

.o-overview__header {
margin-bottom: ms.step(1);
}

.o-overview__actions {
margin-bottom: ms.step(3);
}

@supports (display: grid) {
@media (min-width: breakpoint.$l) {
.o-overview {
@include fluid.column-gap(
breakpoint.$s,
breakpoint.$xl,
size.$spacing-gap-fluid-min,
size.$spacing-gap-fluid-max
);

align-items: center;
display: grid;
grid-template-areas:
'header header actions'
'content content content';
grid-template-columns: repeat(3, 1fr);
row-gap: ms.step(3);
}

.o-overview__header,
.o-overview__actions {
margin: 0;
}

.o-overview__header {
grid-area: header;
}

.o-overview__actions {
grid-area: actions;
}

.o-overview__content {
grid-area: content;
}
}
}
79 changes: 79 additions & 0 deletions src/objects/overview/overview.stories.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Story, Canvas, Meta } from '@storybook/addon-docs/blocks';
import basicDemo from './demo/basic.twig';
import advancedDemo from './demo/advanced.twig'; // The '!!raw-loader!' syntax is a non-standard, Webpack-specific, syntax.
// See: https://github.com/webpack-contrib/raw-loader#examples
// For now, it seems likely Storybook is pretty tied to Webpack, therefore, we are
// okay with the following Webpack-specific raw loader syntax. It's better to leave
// the ESLint rule enabled globally, and only thoughtfully disable as needed (e.g.
// within a Storybook docs page and not within an actual component).
// This can be revisited in the future if Storybook no longer relies on Webpack.
// eslint-disable-next-line @cloudfour/import/no-webpack-loader-syntax
import basicDemoSource from '!!raw-loader!./demo/basic.twig';
// eslint-disable-next-line @cloudfour/import/no-webpack-loader-syntax
import advancedDemoSource from '!!raw-loader!./demo/advanced.twig';
import topics from '../../components/dot-leader/demo/topics.json';

<!--
Inline stories disabled so media queries will behave as expected within
embedded examples.
-->

<Meta
title="Objects/Overview"
parameters={{ docs: { inlineStories: false } }}
/>

# Overview

The Overview object can be used to provide an overview of a site section. For example, it is used to provide an index of article categories, as well as a form to search for articles.

It handles the responsive layout of `header`, `actions`, and `content` blocks. On small screens they are stacked vertically. On large screens the `header` and `actions` blocks stack horizontally above the `content` block.

It should usually be placed in a [Container](/docs/objects-container--basic).

<Canvas>
<Story
name="Basic"
height="300px"
parameters={{
docs: {
source: {
code: basicDemoSource,
},
},
}}
>
{basicDemo()}
</Story>
</Canvas>

## Advanced Usage

Here's a more complex usage example, showing how the Overview object could be used on the article listing page.

<Canvas>
<Story
name="Advanced Usage"
height="300px"
parameters={{
docs: {
source: {
code: advancedDemoSource,
},
},
}}
>
{advancedDemo({ topics })}
</Story>
</Canvas>

## Template Properties

- `overview_tag` - defaults to `section` but can be switched out for any HTML tag.
- `labelledby_id` - an optional ID to use with the `aria-labelledby` attribute.

## Template blocks

- `header` - should generally contain a [Heading](/docs/components-heading--levels)
- `actions` - could contain a searchbar or other actions
- `content` the primary overview content. For example, a list of categories.
14 changes: 14 additions & 0 deletions src/objects/overview/overview.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<{{overview_tag|default('section')}}
class="o-overview"
{% if labelledby_id %}aria-labelledby="{{labelledby_id}}"{% endif %}
>
<header class="o-overview__header">
{% block header %}{% endblock %}
</header>
<div class="o-overview__actions">
{% block actions %}{% endblock %}
</div>
<div class="o-overview__content">
{% block content %}{% endblock %}
</div>
</{{overview_tag|default('section')}}>
43 changes: 0 additions & 43 deletions src/prototypes/article-listing/example/example.scss
Original file line number Diff line number Diff line change
Expand Up @@ -74,31 +74,8 @@
}
}

.topics-header {
padding-bottom: ms.step(3);

@media (min-width: breakpoint.$l) {
display: grid;
@include fluid.grid-gap(
breakpoint.$s,
breakpoint.$xl,
size.$spacing-gap-fluid-min,
size.$spacing-gap-fluid-max
);
grid-template-columns: repeat(3, minmax(max-content, 1fr));
padding-bottom: ms.step(3);
}
}

.search-content {
align-items: center;
display: flex;
grid-column: 3 / -1;
padding-top: ms.step(1);

@media (min-width: breakpoint.$l) {
padding-top: 0;
}
}

.search-input {
Expand All @@ -115,24 +92,4 @@
.search-btn .c-icon {
font-size: ms.step(1);
}

.topics-content {
@media (min-width: breakpoint.$m) {
columns: 2;
@include fluid.grid-gap(
breakpoint.$s,
breakpoint.$xl,
size.$spacing-gap-fluid-min,
size.$spacing-gap-fluid-max
);
}

@media (min-width: breakpoint.$l) {
columns: 3;
}
}

.topics-content li {
margin-bottom: ms.step(0);
}
}
Loading

0 comments on commit 7bce713

Please sign in to comment.