mirror of
https://github.com/McShelby/hugo-theme-relearn.git
synced 2024-11-27 01:33:04 +00:00
parent
0c0b906ae1
commit
0b5bb6e7b3
6 changed files with 252 additions and 3 deletions
119
exampleSite/content/shortcodes/tabs.en.md
Normal file
119
exampleSite/content/shortcodes/tabs.en.md
Normal file
|
@ -0,0 +1,119 @@
|
|||
---
|
||||
title: Tabbed views
|
||||
description : "Synchronize selection of content in different tabbed views"
|
||||
---
|
||||
|
||||
Choose which content to see across the page. Very handy for providing code
|
||||
snippets for multiple languages or providing configuration in different formats.
|
||||
|
||||
## Code example
|
||||
|
||||
{{</* tabs */>}}
|
||||
{{%/* tab name="python" */%}}
|
||||
```python
|
||||
print("Hello World!")
|
||||
```
|
||||
{{%/* /tab */%}}
|
||||
{{%/* tab name="R" */%}}
|
||||
```R
|
||||
> print("Hello World!")
|
||||
```
|
||||
{{%/* /tab */%}}
|
||||
{{%/* tab name="Bash" */%}}
|
||||
```Bash
|
||||
echo "Hello World!"
|
||||
```
|
||||
{{%/* /tab */%}}
|
||||
{{</* /tabs */>}}
|
||||
|
||||
Renders as:
|
||||
|
||||
{{< tabs >}}
|
||||
{{% tab name="python" %}}
|
||||
```python
|
||||
print("Hello World!")
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{% tab name="R" %}}
|
||||
```R
|
||||
> print("Hello World!")
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{% tab name="Bash" %}}
|
||||
```Bash
|
||||
echo "Hello World!"
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{< /tabs >}}
|
||||
|
||||
Tab views with the same tabs that belong to the same group sychronize their selection:
|
||||
|
||||
{{< tabs >}}
|
||||
{{% tab name="python" %}}
|
||||
```python
|
||||
print("Hello World!")
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{% tab name="R" %}}
|
||||
```R
|
||||
> print("Hello World!")
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{% tab name="Bash" %}}
|
||||
```Bash
|
||||
echo "Hello World!"
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{< /tabs >}}
|
||||
|
||||
## Config example
|
||||
|
||||
{{</* tabs groupId="config" */>}}
|
||||
{{%/* tab name="json" */%}}
|
||||
```json
|
||||
{
|
||||
"Hello": "World"
|
||||
}
|
||||
```
|
||||
{{%/* /tab */%}}
|
||||
{{%/* tab name="XML" */%}}
|
||||
```xml
|
||||
<Hello>World</Hello>
|
||||
```
|
||||
{{%/* /tab */%}}
|
||||
{{%/* tab name="properties" */%}}
|
||||
```properties
|
||||
Hello = World
|
||||
```
|
||||
{{%/* /tab */%}}
|
||||
{{</* /tabs */>}}
|
||||
|
||||
Renders as:
|
||||
|
||||
{{< tabs groupId="config" >}}
|
||||
{{% tab name="json" %}}
|
||||
```json
|
||||
{
|
||||
"Hello": "World"
|
||||
}
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{% tab name="XML" %}}
|
||||
```xml
|
||||
<Hello>World</Hello>
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{% tab name="properties" %}}
|
||||
```properties
|
||||
Hello = World
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{< /tabs >}}
|
||||
|
||||
{{% notice warning %}}
|
||||
When using tab views with different content sets, make sure to use a common `groupId` for equal sets but distinct
|
||||
`groupId` for different sets. The `groupId` defaults to `'default'`.
|
||||
**Take this into account across the whole site!**
|
||||
The tab selection is restored automatically based on the `groupId` and if it cannot find a tab item because it came
|
||||
from the `'default'` group on a different page then all tabs will be empty at first.
|
||||
{{% /notice %}}
|
|
@ -17,6 +17,7 @@
|
|||
<link href="{{"css/auto-complete.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
|
||||
<link href="{{"css/atom-one-dark-reasonable.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
|
||||
<link href="{{"css/theme.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
|
||||
<link href="{{"css/tabs.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
|
||||
<link href="{{"css/hugo-theme.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
|
||||
{{with .Site.Params.themeVariant}}
|
||||
<link href="{{(printf "css/theme-%s.css" .) | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
|
||||
|
|
12
layouts/shortcodes/tab.html
Normal file
12
layouts/shortcodes/tab.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
{{ if .Parent }}
|
||||
{{ $name := trim (.Get "name") " " }}
|
||||
{{ if not (.Parent.Scratch.Get "tabs") }}
|
||||
{{ .Parent.Scratch.Set "tabs" slice }}
|
||||
{{ end }}
|
||||
{{ with .Inner }}
|
||||
{{ $.Parent.Scratch.Add "tabs" (dict "name" $name "content" . ) }}
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
{{- errorf "[%s] %q: tab shortcode missing its parent" site.Language.Lang .Page.Path -}}
|
||||
{{ end}}
|
||||
|
21
layouts/shortcodes/tabs.html
Normal file
21
layouts/shortcodes/tabs.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
{{ with .Inner }}{{/* don't do anything, just call it */}}{{ end }}
|
||||
{{ $groupId := default "default" (.Get "groupId") }}
|
||||
<div class="tab-panel">
|
||||
<div class="tab-nav">
|
||||
{{ range $idx, $tab := .Scratch.Get "tabs" }}
|
||||
<button
|
||||
data-tab-item="{{ .name }}"
|
||||
data-tab-group="{{ $groupId }}"
|
||||
class="tab-nav-button btn {{ cond (eq $idx 0) "active" ""}}"
|
||||
onclick="switchTab('{{ $groupId }}','{{ .name }}')"
|
||||
>{{ .name }}</button>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
{{ range $idx, $tab := .Scratch.Get "tabs" }}
|
||||
<div data-tab-item="{{ .name }}" data-tab-group="{{ $groupId }}" class="tab-item {{ cond (eq $idx 0) "active" ""}}">
|
||||
{{ .content }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
43
static/css/tabs.css
Normal file
43
static/css/tabs.css
Normal file
|
@ -0,0 +1,43 @@
|
|||
#body .tab-nav-button {
|
||||
border-width: 1px 1px 1px 1px !important;
|
||||
border-color: #ccc !important;
|
||||
border-radius: 4px 4px 0 0 !important;
|
||||
background-color: #ddd !important;
|
||||
float: left;
|
||||
display: block;
|
||||
position: relative;
|
||||
margin-left: 4px;
|
||||
bottom: -1px;
|
||||
}
|
||||
#body .tab-nav-button:first-child {
|
||||
margin-left: 0px;
|
||||
}
|
||||
#body .tab-nav-button.active {
|
||||
background-color: #fff !important;
|
||||
border-bottom-color: #fff !important;
|
||||
}
|
||||
|
||||
#body .tab-panel {
|
||||
margin-top: 32px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
#body .tab-content {
|
||||
display: block;
|
||||
clear: both;
|
||||
padding: 8px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #ccc;
|
||||
}
|
||||
#body .tab-content .tab-item{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#body .tab-content .tab-item.active{
|
||||
display: block;
|
||||
}
|
||||
|
||||
#body .tab-item pre{
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
|
@ -47,6 +47,57 @@ function fallbackMessage(action) {
|
|||
return actionMsg;
|
||||
}
|
||||
|
||||
function switchTab(tabGroup, tabId) {
|
||||
allTabItems = jQuery("[data-tab-group='"+tabGroup+"']");
|
||||
targetTabItems = jQuery("[data-tab-group='"+tabGroup+"'][data-tab-item='"+tabId+"']");
|
||||
|
||||
// if event is undefined then switchTab was called from restoreTabSelection
|
||||
// so it's not a button event and we don't need to safe the selction or
|
||||
// prevent page jump
|
||||
var isButtonEvent = event != undefined;
|
||||
|
||||
if(isButtonEvent){
|
||||
// save button position relative to viewport
|
||||
var yposButton = event.target.getBoundingClientRect().top;
|
||||
}
|
||||
|
||||
allTabItems.removeClass("active");
|
||||
targetTabItems.addClass("active");
|
||||
|
||||
if(isButtonEvent){
|
||||
// reset screen to the same position relative to clicked button to prevent page jump
|
||||
var yposButtonDiff = event.target.getBoundingClientRect().top - yposButton;
|
||||
window.scrollTo(window.scrollX, window.scrollY+yposButtonDiff);
|
||||
|
||||
// Store the selection to make it persistent
|
||||
if(window.localStorage){
|
||||
var selectionsJSON = window.localStorage.getItem("tabSelections");
|
||||
if(selectionsJSON){
|
||||
var tabSelections = JSON.parse(selectionsJSON);
|
||||
}else{
|
||||
var tabSelections = {};
|
||||
}
|
||||
tabSelections[tabGroup] = tabId;
|
||||
window.localStorage.setItem("tabSelections", JSON.stringify(tabSelections));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function restoreTabSelections() {
|
||||
if(window.localStorage){
|
||||
var selectionsJSON = window.localStorage.getItem("tabSelections");
|
||||
if(selectionsJSON){
|
||||
var tabSelections = JSON.parse(selectionsJSON);
|
||||
}else{
|
||||
var tabSelections = {};
|
||||
}
|
||||
Object.keys(tabSelections).forEach(function(tabGroup) {
|
||||
var tabItem = tabSelections[tabGroup];
|
||||
switchTab(tabGroup, tabItem);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// for the window resize
|
||||
$(window).resize(function() {
|
||||
setMenuHeight();
|
||||
|
@ -83,6 +134,8 @@ $(window).resize(function() {
|
|||
|
||||
|
||||
jQuery(document).ready(function() {
|
||||
restoreTabSelections();
|
||||
|
||||
jQuery('#sidebar .category-icon').on('click', function() {
|
||||
$( this ).toggleClass("fa-angle-down fa-angle-right") ;
|
||||
$( this ).parent().parent().children('ul').toggle() ;
|
||||
|
|
Loading…
Reference in a new issue