diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f79af7fb..ac0feba7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Features * **component** Remove the format option from Newsletter component +* **component:** Allow an optional icon in buttons (#893) # 19.0.0 diff --git a/assets/sass/protocol/components/_button.scss b/assets/sass/protocol/components/_button.scss index 702832a64..5272c1b2f 100644 --- a/assets/sass/protocol/components/_button.scss +++ b/assets/sass/protocol/components/_button.scss @@ -291,3 +291,31 @@ a.mzp-c-button { text-decoration: underline; } } + +// * -------------------------------------------------------------------------- */ +// Icon + +.mzp-c-button-icon-start, +.mzp-c-button-icon-end { + display: inline-block; + font-size: 1em; + height: 1em; + line-height: 1em; + vertical-align: baseline; + width: 1em; + + img, + svg { + height: 100%; + margin-bottom: -0.15em; + width: 100%; + } +} + +.mzp-c-button-icon-start { + @include bidi(((margin-right, 0.5ch, 0), (margin-left, 0, 0.5ch),)); +} + +.mzp-c-button-icon-end { + @include bidi(((margin-left, 0.5ch, 0), (margin-right, 0, 0.5ch),)); +} diff --git a/components/button/button--with-icon.html b/components/button/button--with-icon.html new file mode 100644 index 000000000..08115d4d0 --- /dev/null +++ b/components/button/button--with-icon.html @@ -0,0 +1,63 @@ +
+{% render '@button', { label: 'Button with Icon', + iconEnd: + '' } +%} +
+ ++{% render '@button', { label: 'Button with Icon', + iconStart: + '' } +%} +
+ ++{% render '@button', { class: 'mzp-t-xl mzp-t-product', label: 'Download Firefox', link: 'https://www.mozilla.org/firefox/new/', + iconEnd: + '' } +%} +
+ ++{% render '@button', { class: 'mzp-t-product mzp-t-secondary', label: 'Try Reader Mode', + iconStart: + '' } +%} +
+ ++{% render '@button', { class: 'mzp-t-sm mzp-t-secondary', label: 'Previous', link: '#', + iconStart: + '' } +%} + +{% render '@button', { class: 'mzp-t-sm mzp-t-secondary', label: 'Next', link: '#', + iconEnd: + '' } +%} +
+ ++ {% render '@button', { label: 'Character', iconEnd: '❤︎' } %} +
+ ++ {% render '@button', { label: 'Emoji', iconEnd: '❤️' } %} +
diff --git a/components/button/button--with-icon.readme.md b/components/button/button--with-icon.readme.md new file mode 100644 index 000000000..9e0cdba91 --- /dev/null +++ b/components/button/button--with-icon.readme.md @@ -0,0 +1,47 @@ +You can add an icon to a button as an inline image enclosed in a `span` with the +class `mzp-c-button-icon-start` if the icon appears before the text label or +`mzp-c-button-icon-end` if it appears after the label. + +You can optionally use a standard unicode character or symbol, but be aware not +all platforms will support all characters. Icon fonts are also an option, with +all the usual caveats about using webfonts. You can use an emoji but they also +may not be supported equally across platforms and even on supporting platforms +they’ll be rendered in completely different styles by different systems. For +consistency and reliability, use an image. + +### Tips +- Prefer simple, single-color icons. Complex images likely won’t render well at + such a small size. Multicolored icons or logos may not adapt to different + backgrounds as the button state changes. + +- Prefer embedded SVG over an external `img` (whether SVG or other format). An + inline SVG icon can more easily change color for the different button states + and style variants. Be aware that very old browsers don’t support SVG. + +- Consider the text direction of the page language. Arrows in particular indicate + a specific orientation that may be confusing in text that flows the opposite + direction. The “Next” and “Previous” buttons shown here are a good example of + how this can go wrong. In a right-to-left language, the “Next” arrow moves to + the left of the text label, but still points to the right. A properly + bi-directional design should reverse those icons as well. + +### Tips for inline SVG +- Optimize SVG files for embedding inline in the HTML document. Strip out unnecessary + comments or metadata added by editing tools. Use [SVGO](https://svgo.dev/) + either locally on [online](https://jakearchibald.github.io/svgomg/). + +- Merge shapes and paths where possible to reduce the number of elements and points. + +- Avoid unnecessary grouping of elements. + +- Define colors with `currentColor`. This will inherit the icon’s color from the + button text, including color changes in hover and focus states. An icon with + its own defined colors will need to accommodate background color changes, + either with a color that is visible on all backgrounds, or facilitating a + color change some other way besides `currentColor` (e.g. with additional CSS). + +### No-Nos +- Don’t add multiple icons to a button. Technically Protocol doesn’t prevent it, + it’s just a bad idea. + + diff --git a/components/button/button.config.yml b/components/button/button.config.yml index 2f9cb6e81..a5624c355 100644 --- a/components/button/button.config.yml +++ b/components/button/button.config.yml @@ -16,54 +16,54 @@ variants: preview: '@preview-dark' notes: A light variation of the secondary button for dark backgrounds, adding the class `mzp-t-dark` (the button itself is light). context: - class: mzp-t-secondary mzp-t-dark + class: 'mzp-t-secondary mzp-t-dark' label: Secondary Button - name: Product notes: Use this theme style for product-related transactions, such as downloading software or creating an account. context: - class: mzp-t-product + class: 'mzp-t-product' label: Download Firefox - name: Product Secondary notes: This secondary product button theme should be used when the CTA is a product-related transaction, but not the main action a person should take on a page. context: - class: mzp-t-product mzp-t-secondary + class: 'mzp-t-product mzp-t-secondary' label: Download Firefox - name: Product Secondary Dark preview: '@preview-dark' notes: A light variation of the secondary product button for use on dark backgrounds. Add the class `mzp-t-dark` (the button itself is light). context: - class: mzp-t-product mzp-t-secondary mzp-t-dark + class: 'mzp-t-product mzp-t-secondary mzp-t-dark' label: Download Firefox - name: Neutral notes: A neutral button for less important actions. context: - class: mzp-t-neutral + class: 'mzp-t-neutral' label: Neutral Button - name: Neutral Dark preview: '@preview-dark' notes: A light variation of the neutral button for use on dark backgrounds. Add the class `mzp-t-dark` (the button itself is light). context: - class: mzp-t-neutral mzp-t-dark + class: 'mzp-t-neutral mzp-t-dark' label: Neutral Button - name: Size small notes: A small button. Use this size with caution because small buttons are harder to read and present smaller targets for pointing devices (clicks and taps). context: - class: mzp-t-sm + class: 'mzp-t-sm' label: Small Button - name: Size medium notes: A medium button. context: - class: mzp-t-md + class: 'mzp-t-md' label: Medium Button - name: Size large notes: This is the default size if no size class is provided. context: - class: mzp-t-lg + class: 'mzp-t-lg' label: Large Button - name: Size Extra Large notes: An extra large button. Use this sparingly. context: - class: mzp-t-xl + class: 'mzp-t-xl' label: Extra Large Button - name: Disabled notes: | diff --git a/components/button/button.html b/components/button/button.html index 8a9c6f4b7..5bb67e49a 100644 --- a/components/button/button.html +++ b/components/button/button.html @@ -6,9 +6,35 @@ # link - URL # type - type attribute value (button, submit, reset) # disabled - Boolean +# iconStart - markup +# iconEnd - markup #} -{%- if href -%} -{{ label }} +{%- if link -%} + + {%- if iconStart %} + + {% endif -%} + {{ label }} + {%- if iconEnd %} + + {% endif -%} + {%- else -%} - + {%- endif -%}