button: refactor for a11y #372

This commit is contained in:
Sören Weber 2022-11-28 18:42:51 +01:00
parent 322bf829bc
commit 39b8347b1f
No known key found for this signature in database
GPG key ID: BEC6D55545451B6D
8 changed files with 76 additions and 26 deletions

View file

@ -26,14 +26,14 @@ This only works in modern browsers.
## Variant generator ## Variant generator
{{% button style="secondary" icon="download" %}}Download variant{{% /button %}} {{% button style="secondary" icon="download" href="javascript:window.variants&&variants.getStylesheet();this.blur();" %}}Download variant{{% /button %}}
{{% button style="warning" icon="trash" %}}Reset variant{{% /button %}} {{% button style="warning" icon="trash" href="javascript:window.variants&&variants.resetVariant();this.blur();" %}}Reset variant{{% /button %}}
<div id="vargenerator" class="mermaid" style="background-color: var(--INTERNAL-MAIN-TEXT-color);">Graph</div> <div id="vargenerator" class="mermaid" style="background-color: var(--INTERNAL-MAIN-TEXT-color);">Graph</div>
{{% button style="secondary" icon="download" %}}Download variant{{% /button %}} {{% button style="secondary" icon="download" href="javascript:window.variants&&variants.getStylesheet();this.blur();" %}}Download variant{{% /button %}}
{{% button style="warning" icon="trash" %}}Reset variant{{% /button %}} {{% button style="warning" icon="trash" href="javascript:window.variants&&variants.resetVariant();this.blur();" %}}Reset variant{{% /button %}}
<script> <script>
window.variants && variants.generator( '#vargenerator', '.secondary a', '.warning a' ); window.variants && variants.generator( '#vargenerator' );
</script> </script>

View file

@ -18,6 +18,8 @@ This document shows you what's new in the latest release. For a detailed list of
- **Change**: The Korean language translation for this theme is now available with the language code `ko`. Formerly the country code `kr` was used instead. - **Change**: The Korean language translation for this theme is now available with the language code `ko`. Formerly the country code `kr` was used instead.
- **New**: The [`button` shortcode]({{% relref "shortcodes/button" %}}) can now also be used as a real button inside of HTML forms - although this is a pretty rare use case. The documentation was updated accordingly.
- **New**: The search now supports the Korean language. - **New**: The search now supports the Korean language.
--- ---

View file

@ -47,11 +47,12 @@ Once the button is clicked, it opens another browser tab for the given URL.
| Name | Default | Notes | | Name | Default | Notes |
|:----------------------|:----------------|:------------| |:----------------------|:----------------|:------------|
| **href** | _&lt;empty&gt;_ | The destination URL for the button. If this parameter is not set, the button will do nothing but is still displayed as clickable. | | **href** | _&lt;empty&gt;_ | Either the destination URL for the button or JavaScript code to be executed on click. If this parameter is not set, the button will do nothing but is still displayed as clickable.<br><br>- if starting with `javascript:` all following text will be executed in your browser<br>- every other string will be interpreted as URL|
| **style** | `transparent` | The color scheme used to paint the button.<br><br>- by severity: `info`, `note`, `tip`, `warning`<br>- by brand color: `primary`, `secondary`<br>- by color: `blue`, `green`, `grey`, `orange`, `red`<br>- by special color: `default`, `transparent` | | **style** | `transparent` | The color scheme used to paint the button.<br><br>- by severity: `info`, `note`, `tip`, `warning`<br>- by brand color: `primary`, `secondary`<br>- by color: `blue`, `green`, `grey`, `orange`, `red`<br>- by special color: `default`, `transparent` |
| **icon** | see notes | [Font Awesome icon name]({{%relref "cont/icons#finding-an-icon" %}}) set to the left of the title. Depending on the **style** there may be a default icon. Any given value will overwrite the default.<br><br>- for severity styles: a nice matching icon for the severity<br>- for all other colors: _&lt;empty&gt;_<br><br>If you want no icon for a severity style, you have to set this parameter to `" "` (a non empty string filled with spaces) | | **icon** | see notes | [Font Awesome icon name]({{%relref "cont/icons#finding-an-icon" %}}) set to the left of the title. Depending on the **style** there may be a default icon. Any given value will overwrite the default.<br><br>- for severity styles: a nice matching icon for the severity<br>- for all other colors: _&lt;empty&gt;_<br><br>If you want no icon for a severity style, you have to set this parameter to `" "` (a non empty string filled with spaces) |
| **iconposition** | `left` | Places the icon to the `left` or `right` of the title. | | **iconposition** | `left` | Places the icon to the `left` or `right` of the title. |
| **target** | see notes | The destination frame/window for the URL. This behaves similar to normal links. If the parameter is not given it defaults to:<br><br>- `_blank` for any address starting with `http://` or `https://`<br>- no specific value for all other links | | **target** | see notes | The destination frame/window if **href** is an URL. Otherwise the parameter is not used. This behaves similar to normal links. If the parameter is not given it defaults to:<br><br>- `_blank` for any address starting with `http://` or `https://`<br>- no specific value for all other links |
| **type** | see notes | The [button type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) if **href** is JavaScript. Otherwise the parameter is not used. If the parameter is not given it defaults to `button` |
| _**&lt;content&gt;**_ | see notes | Arbitrary text for the button title. Depending on the **style** there may be a default title. Any given value will overwrite the default.<br><br>- for severity styles: the matching title for the severity<br>- for all other colors: _&lt;empty&gt;_<br><br>If you want no title for a severity style, you have to set this parameter to `" "` (a non empty string filled with spaces) | | _**&lt;content&gt;**_ | see notes | Arbitrary text for the button title. Depending on the **style** there may be a default title. Any given value will overwrite the default.<br><br>- for severity styles: the matching title for the severity<br>- for all other colors: _&lt;empty&gt;_<br><br>If you want no title for a severity style, you have to set this parameter to `" "` (a non empty string filled with spaces) |
## Examples ## Examples
@ -146,7 +147,7 @@ Once the button is clicked, it opens another browser tab for the given URL.
### Other ### Other
#### Severity Style with all Defaults #### Severity Style with All Defaults
````go ````go
{{%/* button href="https://gohugo.io/" style="tip" %}}{{% /button */%}} {{%/* button href="https://gohugo.io/" style="tip" %}}{{% /button */%}}
@ -154,10 +155,43 @@ Once the button is clicked, it opens another browser tab for the given URL.
{{% button href="https://gohugo.io/" style="tip" %}}{{% /button %}} {{% button href="https://gohugo.io/" style="tip" %}}{{% /button %}}
#### Button to internal page #### Button to Internal Page
````go ````go
{{%/* button href="/" %}}Home{{% /button */%}} {{%/* button href="/" %}}Home{{% /button */%}}
```` ````
{{% button href="/" %}}Home{{% /button %}} {{% button href="/" %}}Home{{% /button %}}
#### Button with JavaScript Action
If your JavaScript action does not change the focus afterwards, make sure to call `this.blur()` in the end to unselect the button.
````go
{{%/* button style="primary" icon="bullhorn" href="javascript:alert('Hello world!');this.blur();" %}}Shout it out{{% /button */%}}
````
{{% button style="primary" icon="bullhorn" href="javascript:alert('Hello world!');this.blur();" %}}Shout it out{{% /button %}}
#### Button within a `form` Element
To use native HTML elements in your Markdown, add this in your `config.toml`
````toml
[markup.goldmark.renderer]
unsafe = true
````
````html
<form action="../../search.html" method="get">
<input name="search-by-detail" class="search-by" type="search">
{{%/* button type="submit" style="secondary" icon="search" %}}Search{{% /button */%}}
</form>
````
<form action="../../search.html" method="get">
<div class="searchform" style="width: 20vw;">
<input name="search-by-detail" class="search-by" type="search" placeholder="Search...">
{{% button type="submit" style="secondary" icon="search" %}}Search{{% /button %}}
</div>
</form>

View file

@ -4,13 +4,15 @@
<form action="javascript:triggerSearch()"> <form action="javascript:triggerSearch()">
<div class="searchform"> <div class="searchform">
<label class="a11y-only" for="search-by">{{ T "Search" }}</label> <label class="a11y-only" for="search-by-detail">{{ T "Search" }}</label>
<input data-search-input id="search-by-detail" class="search-by" name="search-by" type="search" placeholder="{{ T "Search-placeholder" }}"> <input data-search-input id="search-by-detail" class="search-by" name="search-by" type="search" placeholder="{{ T "Search-placeholder" }}">
<span class="btn cstyle secondary"> {{ partial "shortcodes/button.html" (dict
<button type="submit" title="{{ T "Search" }}"> "context" .
<i class="fas fa-search"></i> {{ T "Search" }} "type" "submit"
</button> "style" "secondary"
</span> "icon" "search"
"content" (T "Search")
)}}
</div> </div>
</form> </form>
<div class="searchhint"> <div class="searchhint">

View file

@ -1,9 +1,17 @@
{{- $context := .context }} {{- $context := .context }}
{{- $content := .content }} {{- $content := .content }}
{{- $href := .href | default "" }} {{- $href := (trim .href " ") | default "" }}
{{- $style := .style | default "transparent" }} {{- $style := .style | default "transparent" }}
{{- $target := .target | default "" }} {{- $target := .target | default "" }}
{{- if and (eq (len $target) 0) (or (strings.HasPrefix $href "http://") (strings.HasPrefix $href "https://") ) }} {{- $type := .type | default "" }}
{{- $isButton := false }}
{{- if or (not $href) (strings.HasPrefix $href "javascript:") }}
{{- $isButton = true }}
{{- $href = substr $href (len "javascript:") }}
{{- if not $type }}
{{- $type = "button" }}
{{- end }}
{{- else if and (eq (len $target) 0) (or (strings.HasPrefix $href "http://") (strings.HasPrefix $href "https://") ) }}
{{- $target = "_blank" }} {{- $target = "_blank" }}
{{- end }} {{- end }}
{{- $title := .title | default ($content) | default ($style | T) }} {{- $title := .title | default ($content) | default ($style | T) }}
@ -21,7 +29,11 @@
{{- $iconposition := .iconposition | default "left" }} {{- $iconposition := .iconposition | default "left" }}
{{- with $context }} {{- with $context }}
<span class="btn cstyle {{ $style }}"> <span class="btn cstyle {{ $style }}">
{{- if $isButton }}
<button{{ if $href }} onclick="{{ $href | safeJS }}"{{ end }}{{ if gt (len $type) 0 }} type="{{ $type }}"{{ end }}>
{{- else }}
<a{{ if $href }} href="{{ $href }}"{{ if gt (len $target) 0 }} target="{{ $target }}" rel="noopener"{{ end }}{{ end }}> <a{{ if $href }} href="{{ $href }}"{{ if gt (len $target) 0 }} target="{{ $target }}" rel="noopener"{{ end }}{{ end }}>
{{- end }}
{{- if and $icon (eq $iconposition "left") }} {{- if and $icon (eq $iconposition "left") }}
<i class="{{ $icon }}"></i> <i class="{{ $icon }}"></i>
{{- end }} {{- end }}
@ -29,6 +41,10 @@
{{- if and $icon (eq $iconposition "right") }} {{- if and $icon (eq $iconposition "right") }}
<i class="{{ $icon }}"></i> <i class="{{ $icon }}"></i>
{{- end }} {{- end }}
{{- if $isButton }}
</button>
{{- else }}
</a> </a>
{{- end }}
</span> </span>
{{- end }} {{- end }}

View file

@ -8,4 +8,5 @@
"style" (.Get "style") "style" (.Get "style")
"title" (.Get "title") "title" (.Get "title")
"target" (.Get "target") "target" (.Get "target")
"type" (.Get "type")
) }} ) }}

View file

@ -67,7 +67,7 @@ pre {
#body code, #body strong, #body b, #body code, #body strong, #body b,
#body li, #body dd, #body dt, #body li, #body dd, #body dt,
#body p, #body p,
#body a { #body a, #body button {
/* better contrast for colored elements */ /* better contrast for colored elements */
color: black; color: black;
} }
@ -112,7 +112,8 @@ body,
margin-top: 1.5rem; margin-top: 1.5rem;
padding-top: .75rem; padding-top: .75rem;
} }
#body #body-inner .footline a { #body #body-inner .footline a,
#body #body-inner .btn a {
text-decoration: none; text-decoration: none;
} }
#body #body-inner a { #body #body-inner a {

View file

@ -223,7 +223,7 @@ var variants = {
} }
}, },
generator: function( vargenerator, vardownload, varreset ){ generator: function( vargenerator ){
var graphDefinition = this.generateGraph(); var graphDefinition = this.generateGraph();
var graphs = document.querySelectorAll( vargenerator ); var graphs = document.querySelectorAll( vargenerator );
graphs.forEach( function( e ){ e.innerHTML = graphDefinition; }); graphs.forEach( function( e ){ e.innerHTML = graphDefinition; });
@ -234,12 +234,6 @@ var variants = {
this.styleGraph(); this.styleGraph();
} }
}.bind( this ), 25 ); }.bind( this ), 25 );
var downloads = document.querySelectorAll( vardownload );
downloads.forEach( function( e ){ e.addEventListener('click', this.getStylesheet.bind( this )); }.bind( this ) );
var resets = document.querySelectorAll( varreset );
resets.forEach( function( e ){ e.addEventListener('click', this.resetVariant.bind( this )); }.bind( this ) );
}, },
download: function(data, mimetype, filename){ download: function(data, mimetype, filename){