Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor underline nav #377

Merged
merged 19 commits into from
Nov 7, 2017
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .storybook/lib/storiesFromMarkdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,27 @@ import select from 'unist-util-select'
import findBefore from 'unist-util-find-before'
import htmlToReact from 'html-to-react'
import parsePairs from 'parse-pairs'
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import {Octicon} from '../Octicon'

const htmlParser = new htmlToReact.Parser()

const railsOcticonToReact = (html) => {
// <%= octicon "tools" %> to <Octicon name="tools" />
const octre = /<%= octicon ["']([a-z\-]+)["'] %>/gi
html = html.replace(octre, (match, name) => {
return ReactDOMServer.renderToStaticMarkup(<Octicon name={name} />)
})
return html
}

const isValidNode = () => {
return true;
}

const nodeToStory = (node, file) => {
const html = node.value
let html = railsOcticonToReact(node.value)
const element = htmlParser.parse(html)
const pairs = node.lang.replace(/^html\s*/, '')
const attrs = pairs.length ? parsePairs(pairs) : {}
Expand Down
135 changes: 124 additions & 11 deletions modules/primer-navigation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Primer comes with several navigation components. Some were designed with singula

The menu is a vertical list of navigational links. **A menu's width and placement must be set by you.** If you like, just use our grid columns as a parent. Otherwise, apply a custom `width`.

```html
```html title="Menu"
<nav class="menu" aria-label="Person settings">
<a class="menu-item selected" href="#url" aria-current="page">Account</a>
<a class="menu-item" href="#url">Profile</a>
Expand All @@ -59,7 +59,7 @@ The menu is a vertical list of navigational links. **A menu's width and placemen

There are a few subcomponents and add-ons that work well with the menu, including avatars, counters, and Octicons.

```html
```html title="Menu with octicons, avatars and counters"
<nav class="menu" aria-label="Person settings">
<a class="menu-item selected" href="#url" aria-current="page">
<%= octicon "tools" %>
Expand All @@ -83,7 +83,7 @@ There are a few subcomponents and add-ons that work well with the menu, includin

You can also add optional headings to a menu. Feel free to use nearly any semantic element with the `.menu-heading` class, including inline elements, headings, and more.

```html
```html title="Menu with heading"
<nav class="menu" aria-labelledby="menu-heading">
<span class="menu-heading" id="menu-heading">Menu heading</span>
<a class="menu-item selected" href="#url" aria-current="page">Account</a>
Expand All @@ -93,12 +93,123 @@ You can also add optional headings to a menu. Feel free to use nearly any semant
</nav>
```

## Underline nav

`.UnderlineNav` is navigation that is typically used at the top of a page as the main page navigation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be worded better, it says navigation twice and descriptions could be a little more helpful. Suggest something like this but feel free to edit:

Use UnderlineNav to style navigation with a minimal underlined selected state. This component comes with variations to accommodate icons, counters, and button actions; and is typically used for navigation placed at the top of the page.


```html title="UnderlineNav"
<nav class="UnderlineNav">
<div class="UnderlineNav-items">
<a href="#url" role="tab" title="Item 1" class="UnderlineNav-item selected">Item 1</a>
<a href="#url" role="tab" title="Item 2" class="UnderlineNav-item">Item 2</a>
<a href="#url" role="tab" title="Item 3" class="UnderlineNav-item">Item 3</a>
<a href="#url" role="tab" title="Item 4" class="UnderlineNav-item">Item 4</a>
</div>
</nav>
```

Use `.UnderlineNav-actions` to use another element alongside the underline nav
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use is used twice here, could be worded better, suggest something like this:

Use .UnderlineNav-actions to place another element, such as a button, to the opposite side of the navigation items.


```html title="UnderlineNav-actions"
<nav class="UnderlineNav" aria-label="Foo bar">
<div class="UnderlineNav-items">
<a href="#url" class="UnderlineNav-item selected">Item 1</a>
<a href="#url" class="UnderlineNav-item">Item 2</a>
<a href="#url" class="UnderlineNav-item">Item 3</a>
<a href="#url" class="UnderlineNav-item">Item 4</a>
</div>
<div class="UnderlineNav-actions">
<a class="btn">Button</a>
</div>
</nav>
```

You can right align the navigation with `.UnderlineNav--right`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To keep in style with our newer docs (i.e. less wordy and command tense), suggest changing this to:

Use .UnderlineNav--right to right align the navigation.


```html title="UnderlineNav--right"
<nav class="UnderlineNav UnderlineNav--right">
<div class="UnderlineNav-items">
<a href="#url" role="tab" title="Item 1" class="UnderlineNav-item selected">Item 1</a>
<a href="#url" role="tab" title="Item 2" class="UnderlineNav-item">Item 2</a>
<a href="#url" role="tab" title="Item 3" class="UnderlineNav-item">Item 3</a>
<a href="#url" role="tab" title="Item 4" class="UnderlineNav-item">Item 4</a>
</div>
</nav>
```

This also works when adding actions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest changing description to: UnderlineNav--right also works with when used with UnderlineNav-actions.


```html title="UnderlineNav--right with actions"
<nav class="UnderlineNav UnderlineNav--right" aria-label="Foo bar">
<div class="UnderlineNav-actions">
<a class="btn">Button</a>
</div>
<div class="UnderlineNav-items">
<a href="#url" class="UnderlineNav-item selected">Item 1</a>
<a href="#url" class="UnderlineNav-item">Item 2</a>
<a href="#url" class="UnderlineNav-item">Item 3</a>
<a href="#url" class="UnderlineNav-item">Item 4</a>
</div>
</nav>
```


The navigation will work with added counters and/or octicons
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, use a more commanding tone, such as:

Counters and octicons can be used with navigation items:


```html title="UnderlineNav with Counter"
<nav class="UnderlineNav" aria-label="Foo bar">
<div class="UnderlineNav-items">
<a href="#url" class="UnderlineNav-item selected">
<%= octicon "tools" %>
Item 1
</a>
<a href="#url" class="UnderlineNav-item">
<%= octicon "tools" %>
Item 2
<span class="Counter">10</span>
</a>
<a href="#url" class="UnderlineNav-item">
<%= octicon "tools" %>
Item 3
</a>
<a href="#url" class="UnderlineNav-item">
<%= octicon "tools" %>
Item 4
</a>
</div>
</nav>
```

Use `.UnderlineNav--full` to use a container within the components
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting change wording to something like:

Use UnderlineNav--full in combination with container styles to make navigation fill the width of the container.

I couldn't find a way to avoid using "container" twice but I think it's okay.


```html title="UnderlineNav--full"
<nav class="UnderlineNav UnderlineNav--full" aria-label="Foo bar">
<div class="container-lg">
<div class="UnderlineNav-items">
<a href="#url" class="UnderlineNav-item selected">Item 1</a>
<a href="#url" class="UnderlineNav-item">Item 2
<span class="Counter">10</span>
</a>
<a href="#url" class="UnderlineNav-item">Item 3</a>
<a href="#url" class="UnderlineNav-item">Item 4</a>
</div>
<div class="UnderlineNav-actions">
<a class="btn">Button</a>
</div>
</div>
</nav>
```






## Tabnav

When you need to toggle between different views, consider using a tabnav. It'll given you a left-aligned horizontal row of... tabs!

```html
```html title="tabnav"
<div class="tabnav">
<nav class="tabnav-tabs" aria-label="Foo bar">
<a href="#url" class="tabnav-tab selected" aria-current="page">Foo tab</a>
Expand All @@ -109,7 +220,7 @@ When you need to toggle between different views, consider using a tabnav. It'll

Use `.float-right` to align additional elements in the `.tabnav`:

```html
```html title="tabnav with buttons"
<div class="tabnav">
<a class="btn btn-sm float-right" href="#url" role="button">Button</a>
<nav class="tabnav-tabs" aria-label="Foo bar">
Expand All @@ -121,7 +232,7 @@ Use `.float-right` to align additional elements in the `.tabnav`:

Additional bits of text and links can be styled for optimal placement with `.tabnav-extra`:

```html
```html title="tabnav-extra"
<div class="tabnav">
<div class="tabnav-extra float-right">
Tabnav widget text here.
Expand All @@ -133,7 +244,7 @@ Additional bits of text and links can be styled for optimal placement with `.tab
</div>
```

```html
```html title="tabnav with everything"
<div class="tabnav">
<div class="float-right">
<a class="tabnav-extra" href="#url">
Expand All @@ -154,7 +265,7 @@ Additional bits of text and links can be styled for optimal placement with `.tab

A vertical list of filters. Grey text on white background. Selecting a filter from the list will fill its background with blue and make the text white.

```html
```html title="filter-list"
<ul class="filter-list">
<li>
<a href="#url" class="filter-item selected" aria-current="page">
Expand All @@ -180,7 +291,7 @@ A vertical list of filters. Grey text on white background. Selecting a filter fr

`.subnav` is navigation that is typically used when on a dashboard type interface with another set of navigation above it. This helps distinguish navigation hierarchy.

```html
```html title="subnav"
<nav class="subnav" aria-label="Respository">
<a href="#url" class="subnav-item selected" aria-current="page">Item 1</a>
<a href="#url" class="subnav-item">Item 2</a>
Expand All @@ -190,7 +301,7 @@ A vertical list of filters. Grey text on white background. Selecting a filter fr

You can have `subnav-search` in the subnav bar.

```html
```html title="subnav-search"
<div class="subnav">
<nav class="subnav-links" aria-label="Repository">
<a href="#url" class="subnav-item selected" aria-current="page">Item 1</a>
Expand All @@ -207,7 +318,7 @@ You can have `subnav-search` in the subnav bar.

You can also use a `subnav-search-context` to display search help in a select menu.

```html
```html title="subnav-search-context"
<div class="subnav">
<nav class="subnav-links">
<a href="#url" class="subnav-item selected">Item 1</a>
Expand Down Expand Up @@ -244,6 +355,8 @@ You can also use a `subnav-search-context` to display search help in a select me
</div>
</div>
```


<!-- %enddocs -->

## License
Expand Down
1 change: 1 addition & 0 deletions modules/primer-navigation/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
@import "./lib/tabnav.scss";
@import "./lib/filter-list.scss";
@import "./lib/subnav.scss";
@import "./lib/underline-nav.scss";
79 changes: 79 additions & 0 deletions modules/primer-navigation/lib/underline-nav.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
.UnderlineNav {
display: flex;
justify-content: space-between;
border-bottom: 1px solid $gray-200;
}

.UnderlineNav-items {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel a little worried having UnderlineNav-items and UnderlineNav-item will be a bit confusing and not immediately obvious what they do. Could we change UnderlineNav-items to UnderlineNav-body? That's a pattern we use elsewhere and I think it makes sense because you have actions to handle other content. Otherwise best I could think of was UnderlineNav-items-container or wrapper but they get a little long 😬

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing to UnderlineNav-body 👍

display: flex;
margin-bottom: -1px;
}

.UnderlineNav-item {
padding: $spacer-3 $spacer-2;
margin-right: $spacer-3;
font-size: $body-font-size;
line-height: $lh-default;
color: $text-gray;
text-align: center;
border-bottom: 2px solid transparent;

.Counter {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to avoid nesting other component selectors like this because it creates dependencies and means overriding if we want to act differently. We could just use the ml-1 utility. How strongly do you feel this needs to be built into the pattern?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this from the component. My only concern is that people will use inconsistent spacing, but I think it needs to be flexible because markup spacing affects this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this, and the other similar scenarios, are tricky. This is where I feel like we should handle the Counter styling in context with the UnderlineNav in other parts of the code (say helpers or something), rather than Sass. Handling it in the Sass means adding additional classes to apply to components that may already require a number of classes. That's not the worst but can feel like overkill and be a contributor to CSS bloat. We don't have a good solution for handling elsewhere in the code base right now, but it keeps coming up and is something that's on our radar. If we start to see this particular use case being styled incorrectly, then the best option is to have another class to apply to the Counter rather than nesting it.

margin-left: $spacer-1;
}

.octicon {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar thoughts here to nesting Counter. We could have an element class to account for it, such as UnderlineNav-octicon as utilities won't work because you need the hover styles.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the spacing from the component (same concern as Counter) but kept the color styles in under .UnderlineNav-octicon

margin-right: $spacer-1;
color: $gray-400;
}

&:hover,
&:focus {
color: $text-gray-dark;
text-decoration: none;
border-bottom-color: $gray-300;
transition: 0.2s ease;

.octicon {
color: $gray-500;
}
}

&.selected {
font-weight: $font-weight-bold;
color: $text-gray-dark;
border-bottom-color: $orange-600;

.octicon {
color: $gray-500;
}
}
}

.UnderlineNav--right {
justify-content: flex-end;

.UnderlineNav-item {
margin-right: 0;
margin-left: $spacer-3;
}

.UnderlineNav-actions {
flex: 1 1 auto;
}
}

.UnderlineNav-actions {
align-self: center;
}

.UnderlineNav--full {
display: block;

.container-lg,
.container-md,
.container-xl {
Copy link
Member

@broccolini broccolini Nov 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here re nesting other Primer styles. UnderlineNav-container may work? It's a little bit of a quirky one and potentially could be done with utilities but I can image this tripping people up so probably good to offer it as part of the component styles.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this to .UnderlineNav-container 👍

display: flex;
justify-content: space-between;
}
}
10 changes: 10 additions & 0 deletions modules/primer-navigation/stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import { storiesOf } from '@storybook/react'
import storiesFromMarkdown from '../../.storybook/lib/storiesFromMarkdown'

const stories = storiesOf('Navigation', module)

storiesFromMarkdown(require.context('.', true, /\.md$/))
.forEach(({title, story}) => {
stories.add(title, story)
})
5 changes: 3 additions & 2 deletions script/after_success
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#!/bin/bash
set -e

branch=$TRAVIS_BRANCH
branch=$TRAVIS_PULL_REQUEST_BRANCH
event=$TRAVIS_EVENT_TYPE

# only publish canary releases on PRs against dev
if [[ "$event" = "pull_request" && "$branch" = "dev" ]]; then
if [[ "$event" = "pull_request" ]] && [[ !("$branch" =~ ^release-.*) ]] && [[ !("$branch" = "master") ]];
then
script/release-pr --yes
fi