Skip to content

Commit

Permalink
Release 2.4.0 (#92)
Browse files Browse the repository at this point in the history
* 2.4.0

* fix(heroku): build with NODE_ENV=production

* Add CSS utilities listing (#88)

* 2.2.0

* Add CodePen edit links to examples (#50)

* add CodePen links to all live examples

* simplify

* reposition CodePen link w/pencil icon

* nix .relative from example container

* rewrap codepen link in template conditional

* add margin to prevent overlap of kbd elements when stacked (#48)

* add margin to prevent overlap of kbd elements when stacked

* additional example to illustrate wrap behavior

* remove old kbd component, move into the markdown file

* move data stories text out of code example

* use spacing between kbd elements and update implementation suggestions

Co-authored-by: Shawn Allen <[email protected]>

* fix additional instances of kbd margins

* update docs to use mix of space and margin utilities

* apply spacing

Co-authored-by: Shawn Allen <[email protected]>

* docs: add subtitle and see_also links to title template

* chore(docs): make css usage docs a directory

* fix(docs): make color swatches inline-flex

* fix(docs): add bg-white to TOC

* feat(docs): add global "utilites" data

* feat(docs): add get_path template filter

* feat(docs): add CSS utilities page

* docs(utilities): add more utility listings

* docs(utilities): update intro para

Co-authored-by: Jackson Flint-Gonzales <[email protected]>

* Lint CSS; add expiring-todo-comments rules for JS + CSS (#55)

* chore(deps): install eslint-plugin-unicorn

* chore(lint): update deprecation comments to unicorn style

* chore(lint): enable unicorn/expiring-todo-comments

* chore(css): add todo comments for focus tweaks

* chore(lint): install and set up stylelint

* chore(lint): fix up stylelint errors

* chore(deps): install semver

* lint(css): tweak expiring todo comment version ranges (">=" instead of "^")

* lint(css): add local/expiring-todo-comments rule

* lint(js): fix up todo version comments

* chore(deps): upgrade to [email protected]

* chore(lint): stylelint --fix

* feat(tokens): add colors.grey.focus

* chore(lint): set allowWarningComments: true

* chore(lint): whitespace

* fix(lint): only shellcheck scripts/*.sh

* Lint markdown (#56)

* lint(markdown): install markdownlilnt-cli

* lint(markdown): add "lint-docs" npm script, et al

* lint(markdown): add markdownlint config, custom frontmatter rule

* lint(docs): lint whitespace, headings

* lint(ci): add markdownlint problem matcher

* chore(lint): test markdownlint problem matcher

* chore(lint): add some lines to bad markdown

* lint(markdown): tweak frontmatter error output

* lint(markdown): add no-empty rule, tag our rules as "local"

* lint(markdown): fix up resources landing page (placeholder)

* chore(lint): npm run lint-docs -- --fix

* fix: nix lint-css script (not yet implemented)

* fix(scripts): remove lint-css from run-p list (not yet implemented)

* Extract Tailwind preset (#87)

* chore(build): nix purge option from tailwind config

* chore(deps): move tailwind-interaction-variants to dependencies

* chore(browserslist): run browserslist --update-db

* feat(tailwind): add tailwind preset

* feat(tailwind): use tailwind preset in our config

* chore: delete redundant comment

* chore(tailwind): move corePlugins + variants to tailwind.theme

* fix(deps): move tailwindcss to dependencies

* fix(npm): add lib/tailwind to package files

* fix(npm): include tailwind.preset.js

* Editing buttons docs (#79)

* Testing editing buttons docs

* Added text from google doc

* Added images + small tweaks

* Trying a real button

* removing image

* update content to match google doc

* chore(docs): reduce noise in github API errors

* feat(docs): add docs/static/images

* fix(docs): rebuild package-lock.json

* fix(docs): safelist table[class=w-full] for styling

* chore(docs): add get/setAttribute() remark helpers

* chore(docs): reduce noise when version status fails

* feat(docs): update button docs

Co-authored-by: laurenajong <[email protected]>

* feat(docs): add basic yes/no table styling

* feat(tokens): add 12 + "full" to spacing

* feat(theme): add full (100%) to borderRadius

* chore(docs): add more spacing around button examples

* fix(docs): add icons to yes/no examples

* chore(docs): more consistent line breaks

* fix(heroku): create a review app on pr label

* fix(docs): add alt="" to decorative img

Co-authored-by: Jackson Flint-Gonzales <[email protected]>

* chore(lint): nuke hanging spaces

* chore(docs): delete icon-example.png reference design

* fix(docs): add empty link listener to prevent scrolling

* fix(docs): fix bad merge

Co-authored-by: Shawn Allen <[email protected]>
Co-authored-by: laurenajong <[email protected]>
Co-authored-by: Jackson Flint-Gonzales <[email protected]>

* Update color values from Figma (#97)

* fix(tokens): update color values from Figma

Saved as v2.4.1 in https://www.figma.com/file/PztEA9PIX00czGHf68Gsr5/?node-id=0%3A1

* chore(lint): fix spaces

* Release 2.4.0 fixes (#93)

* Editing buttons docs (#79)

* Testing editing buttons docs

* Added text from google doc

* Added images + small tweaks

* Trying a real button

* removing image

* update content to match google doc

* chore(docs): reduce noise in github API errors

* feat(docs): add docs/static/images

* fix(docs): rebuild package-lock.json

* fix(docs): safelist table[class=w-full] for styling

* chore(docs): add get/setAttribute() remark helpers

* chore(docs): reduce noise when version status fails

* feat(docs): update button docs

Co-authored-by: laurenajong <[email protected]>

* feat(docs): add basic yes/no table styling

* feat(tokens): add 12 + "full" to spacing

* feat(theme): add full (100%) to borderRadius

* chore(docs): add more spacing around button examples

* fix(docs): add icons to yes/no examples

* chore(docs): more consistent line breaks

* fix(heroku): create a review app on pr label

* fix(docs): add alt="" to decorative img

Co-authored-by: Jackson Flint-Gonzales <[email protected]>

* chore(lint): nuke hanging spaces

* chore(docs): delete icon-example.png reference design

* fix(docs): add empty link listener to prevent scrolling

* fix(docs): fix bad merge

Co-authored-by: Shawn Allen <[email protected]>
Co-authored-by: laurenajong <[email protected]>
Co-authored-by: Jackson Flint-Gonzales <[email protected]>

* fix(develop): move watching logic out of .eleventy.js

* chore(lint): line breaks

* docs(tailwind): cross-reference css pages

* docs(tailwind): add tailwind usage docs

* chore(lint): fix heading levels in Tailwind docs

Co-authored-by: laurenajong <[email protected]>
Co-authored-by: laurenajong <[email protected]>
Co-authored-by: Jackson Flint-Gonzales <[email protected]>

Co-authored-by: Jackson Flint-Gonzales <[email protected]>
Co-authored-by: laurenajong <[email protected]>
Co-authored-by: laurenajong <[email protected]>
  • Loading branch information
4 people authored Jun 6, 2022
1 parent 7448ff1 commit c63ce59
Show file tree
Hide file tree
Showing 53 changed files with 3,595 additions and 2,094 deletions.
15 changes: 1 addition & 14 deletions .eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,6 @@ const toc = require('./lib/eleventy/toc')
const { environment } = require('./lib/nunjucks')

module.exports = config => {
if (dev) {
const throttle = 100
const reloadOnChange = require('./lib/eleventy/reload')
reloadOnChange(__filename, [
'lib/**/*.js',
// we need to watch these ones explicitly because they
// change how examples and color swatches are rendered
'docs/_includes/{example,macros}.njk'
], throttle)

// throttle subsequent rebuilds
config.setWatchThrottleWaitTime(throttle)
}

config.addPlugin(navigation)
config.addPlugin(remark, remarkConfig)
config.addPlugin(toc, {
Expand All @@ -38,6 +24,7 @@ module.exports = config => {
config.setUseGitIgnore(false)
config.addWatchTarget('./dist')
config.addPassthroughCopy('dist')
config.addPassthroughCopy('docs/static')

return {
dir: {
Expand Down
10 changes: 8 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
module.exports = {
parser: '@babel/eslint-parser',
plugins: ['sfgov'],
plugins: [
'sfgov',
'unicorn'
],
extends: [
'plugin:sfgov/recommended'
],
rules: {
'unicorn/expiring-todo-comments': ['error', {
allowWarningComments: true
}]
},
overrides: [
{
files: ['src/js/*.js', 'src/icons/index.js'],
files: ['src/**/*.js'],
env: {
browser: true
},
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ jobs:
with:
node-version: 14
cache: npm

- run: npm ci

- uses: xt0rted/markdownlint-problem-matcher@v1
- run: npm run lint

# this sets NODE_ENV=production for all of the build scripts
Expand Down
15 changes: 15 additions & 0 deletions .markdownlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
default: false
heading-increment: true
heading-style: atx
first-heading-h1: { level: 2 }
front-matter:
required_keys:
- title
line-length: false
links: true
list-indent: true
no-bare-urls: false
no-empty: true
ul-indent: { indent: 2, start_indented: false }
ul-style: consistent
whitespace: true
23 changes: 23 additions & 0 deletions .stylelintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
extends: [
'stylelint-config-standard'
],
plugins: [
'./lib/stylelint/expiring-todo-comments'
],
rules: {
'at-rule-no-unknown': [true, {
ignoreAtRules: [
'apply',
'layer',
'responsive',
'screen',
'tailwind',
'variants'
]
}],
'local/expiring-todo-comments': [true, {
}],
'string-quotes': 'single'
}
}
6 changes: 4 additions & 2 deletions docs/_data/eleventyComputed.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ function getLastCommitFromGit (path) {
}

async function getLastCommitFromGitHub (path) {
if (process.env.NODE_ENV === 'development') return null

const args = { ...context, path, sha: branch, per_page: 1 }

// console.info('getting last commit from github:', args)
Expand All @@ -53,7 +55,7 @@ async function getLastCommitFromGitHub (path) {
res = await github.rest.repos.listCommits(args)
commits = res.data
} catch (error) {
console.warn('error loading commits for "%s"', path, error)
console.warn('error loading commits for "%s"', path)
gitMetaCache.set(path, null)
return null
}
Expand All @@ -71,7 +73,7 @@ async function getLastCommitFromGitHub (path) {
// console.info('caching git meta for "%s"', path, meta)
return meta
} else {
console.warn('unable to get commit for "%s"', path, res)
console.warn('unable to get commit for "%s"', path)
return null
}
}
Expand Down
1 change: 0 additions & 1 deletion docs/_data/examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,5 @@ async function getExamples () {
})
}


return examples
}
2 changes: 1 addition & 1 deletion docs/_data/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ async function getPublishedStatusVersion () {
console.warn('no published version status for %s', sha, statuses)
}
} catch (error) {
console.warn('unable to get published version status:', error)
console.warn('unable to get published version status:', error.message)
}
}
41 changes: 41 additions & 0 deletions docs/_data/utilities.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const postcss = require('postcss')
const { readFileSync } = require('fs')

const UTILITY_SELECTOR_PATTERN = /^\.[-:\w]+$/

module.exports = function getUtilities () {
const css = readFileSync('dist/css/utilities.css', 'utf8')
const root = postcss.parse(css)
/** @type [postcss.Declaration] */
const decls = []
root.walkRules(rule => {
if (UTILITY_SELECTOR_PATTERN.test(rule.selector)) {
rule.walkDecls((decl, index) => {
decls.push(decl)
})
}
})

return {
decls,
byClassname: Object.fromEntries(
decls.map(decl => [
decl.parent.selector.substring(1),
decl
])
),
byProperty: groupBy(
decls,
decl => decl.prop
)
}
}

function groupBy (list /** @type [any] */, keyFunction /** type Function */) {
return list.reduce((map, d, i) => {
const key = keyFunction(d, i)
if (key in map) map[key].push(d)
else map[key] = [d]
return map
}, {})
}
2 changes: 1 addition & 1 deletion docs/_includes/toc.njk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<nav
class="sticky top-0 pl-16 py-4 border-0 border-l-2 border-solid border-slate"
class="sticky top-0 pl-16 py-4 bg-white border-0 border-l-2 border-solid border-slate"
aria-hidden="true"
>
{% if title %}
Expand Down
168 changes: 160 additions & 8 deletions docs/components/buttons.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,190 @@
---
title: Buttons
---
Use buttons for major actions.

## Link buttons
Buttons draw more attention than a simple text link. Because of their larger surface and color, they are visually more findable and easier to click or tap.

This is some text about link buttons. We should explain why we want links to
look like buttons.
## When to use

Use a button when an action has more weight or significance. Examples:

* There is a clear primary action people should take
* Highlighting a suggested action in a page section
* A significant or destructive action will be applied and users need to be aware

If the action should not be prompted, a text link may be a better option.

## Types of buttons

### Primary button

This is the most common type of button. Use these to direct people to a clear primary action. To call out that these buttons are actionable, they are action blue (`{{ tokens.colors.action }}`).

```html
<button class="btn">
Do something
</button>
```

Try not to have more than 1 primary button on a page. Multiple primary buttons puts more cognitive load on people. It takes them more time and effort to figure out what to do.

### Inverse button

On some backgrounds, the primary button color will not have sufficient contrast. In this case, use inverse buttons, which have a white fill.

```html wrapper_class="bg-blue-dark p-20"
<div class="bg-blue-dark">
<button class="btn btn-inverse">
Do something
</button>
</div>
```

### Secondary button

```html
<button class="btn btn-secondary">
Do something
</button>
```

Secondary buttons don’t have as much visual weight because they are outlined instead of solid. Use these if your button is not an important action on the page.

Pair it side-by-side with a primary button to prompt toward the primary button’s action.

```html id="buttons-side-by-side"
<div class="flex gap-20">
<button class="btn btn-secondary">
Cancel
</button>
<button class="btn">
Continue
</button>
</div>
```

## Variations

### Block buttons

Block buttons stretch to fill the width of the screen or area instead of having a set width. They are often used on mobile layouts.

```html
<div class="bg-blue-1 p-20 text-slate text-body">
<div>COVID-19 vaccination appointments available only for San Francisco Health Network patients.</div>
<button class="btn btn-block my-20">
Check for availability
</button>
<div class="text-center">
Or call <a href="tel:1234567890" class="text-action">123-456-7890</a>
</div>
</div>
```

### Icons

Icons can be on the left or right of the text in a button. Do not use more than one icon in a button.

```html
<div class="flex justify-around items-center gap-16 title-xs">
<a href="#" class="btn btn-secondary flex gap-8">
<sfgov-icon symbol="arrow-left"></sfgov-icon>
<span>Previous</span>
</a>
<a href="#" class="text-action">1</a>
<span>...</span>
<a href="#" class="text-action">8</a>
<a href="#" class="text-action">9</a>
<span>10</span>
<a href="#" class="text-action">11</a>
<a href="#" class="btn btn-secondary flex gap-8">
<span>Next</span>
<sfgov-icon symbol="arrow-right"></sfgov-icon>
</a>
</div>
```

Icons should reinforce the meaning of the button’s text. In rare cases, an icon can be used without text. Only do this if the icon is extremely universally understood, such as an arrow or search magnifying glass. [Read more about icons](/foundations/icons/)

## Appearance

<img alt="" src="/static/images/button-specs.png" class="w-full">

Buttons have:
* corner radius of 8px
* 8px padding on the top and bottom
* 20px padding left and right, but can be variable on block buttons
* Body Bold text

## Usage

### Alignment

Buttons are typically left aligned with other content, not centered. For exceptions, see <a href="#block-buttons">block buttons</a>.

| <img class="w-1/1" alt="Left aligned button with left aligned text" src="/static/images/alignment-correct.png"> | <img class="w-1/1" alt="Center aligned button with left aligned text" src="/static/images/alignment-incorrect.png"> |
| ----------- | ----------- |
| Yes | No |
| Button is left aligned with other content | Button is centered |

### Arrangement of multiple buttons

For 2 or more button options, place them side by side instead of on top of one another if possible. This reduces the chance of accidentally clicking the wrong one and avoids alignment issues.

| <div class="flex gap-20"><button class="btn btn-secondary">Cancel</button><button class="btn">Continue</button></div> | <div><button class="btn btn-secondary mb-20">Cancel</button><br><button class="btn mb-20">Continue</button></div> |
| ----------- | ----------- |
| Yes | No |
| Choices are side by side | Choices are stacked |

### Writing button text

Button text should ideally be less than 15 characters. A maximum of 25 characters is OK if necessary.

Refer to the [button text library](https://sfgovdt.jira.com/wiki/spaces/SFGOV/pages/3221651460/Button+text+library) for common button uses.

Long button text is less legible, less impactful, and sometimes can even cause wrapping.

| <button class="btn mb-48">Apply now</button> | <button class="btn mb-48">Apply now for your Small Business Grant</button> |
| ----------- | ----------- |
| Yes | No |
| Button text is short | Button text is very long |

| <button class="btn mb-20">Apply now</button> | <button class="btn mb-20">Apply now for your<br>Small Business Grant</button> |
| ----------- | ----------- |
| Yes | No |
| Button text fits on one line | Button text wraps to fit |

## HTML implementation

Buttons styles can be applied to both HTML links (`<a>` elements) and interactive buttons (`<button>`).

### Link buttons

### Inline link
```html
<a class="btn" href="#">
This is a link
</a>
```

### Block link

```html
<a class="btn btn-block" href="#">
This is a block link
</a>
```

## HTML buttons

This is some text about actual styling actual `<button>` elements.
### HTML buttons

### Inline button
```html
<button class="btn">
This is a button
</button>
```

### Block button

```html
<button class="btn btn-block">
This is a block button
Expand Down
Loading

0 comments on commit c63ce59

Please sign in to comment.