tag-plugin: tabs
This commit is contained in:
parent
f1bc0a3a8e
commit
030a5af7b6
|
@ -0,0 +1,8 @@
|
||||||
|
/* global hexo */
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const postTabs = require('./lib/tabs')(hexo);
|
||||||
|
hexo.extend.tag.register('tabs', postTabs, true);
|
||||||
|
hexo.extend.tag.register('subtabs', postTabs, true);
|
||||||
|
hexo.extend.tag.register('subsubtabs', postTabs, true);
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
* tabs.js | https://theme-next.js.org/docs/tag-plugins/tabs
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = ctx => function(args, content) {
|
||||||
|
const tabBlock = /<!--\s*tab (.*?)\s*-->\n([\w\W\s\S]*?)<!--\s*endtab\s*-->/g;
|
||||||
|
args = ctx.args.map(args, ['active', 'codeblock', 'color'], ['tabName']);
|
||||||
|
const tabName = args.tabName;
|
||||||
|
const tabActive = Number(args.active) || 0;
|
||||||
|
|
||||||
|
let match;
|
||||||
|
let tabId = 0;
|
||||||
|
let tabNav = '';
|
||||||
|
let tabContent = '';
|
||||||
|
|
||||||
|
if (!tabName) ctx.log.warn('Tabs block must have unique name!');
|
||||||
|
|
||||||
|
while ((match = tabBlock.exec(content)) !== null) {
|
||||||
|
let {caption, codeblock} = ctx.args.map(match[1].split(' '), ['codeblock'], ['caption']);
|
||||||
|
let postContent = ctx.render.renderSync({ text: match[2], engine: 'markdown' }).trim();
|
||||||
|
|
||||||
|
const abbr = tabName + ' ' + ++tabId;
|
||||||
|
const href = abbr.toLowerCase().split(' ').join('-');
|
||||||
|
|
||||||
|
const isActive = (tabActive > 0 && tabActive === tabId) || (tabActive === 0 && tabId === 1) ? ' active' : '';
|
||||||
|
tabNav += `<li class="tab${isActive}"><a href="#${href}">${caption || abbr}</a></li>`;
|
||||||
|
tabContent += `<div class="tab-pane${isActive}" ${codeblock ? 'codeblock="true"' : ''} id="${href}">${postContent}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
tabNav = `<ul class="nav-tabs">${tabNav}</ul>`;
|
||||||
|
tabContent = `<div class="tab-content fs14">${tabContent}</div>`;
|
||||||
|
|
||||||
|
return `<div class="tag-plugin tabs" id="${tabName.toLowerCase().split(' ').join('-')}">${tabNav + tabContent}</div>`;
|
||||||
|
};
|
|
@ -48,7 +48,7 @@ table:not([class])
|
||||||
background: var(--block)
|
background: var(--block)
|
||||||
td,th
|
td,th
|
||||||
padding: 0.5em 1em
|
padding: 0.5em 1em
|
||||||
border: 1px solid var(--hover-block)
|
border: 1px solid var(--block-hover)
|
||||||
line-height: 1.5
|
line-height: 1.5
|
||||||
tr
|
tr
|
||||||
word-break: keep-all
|
word-break: keep-all
|
||||||
|
|
|
@ -19,7 +19,7 @@ article.md .highlight
|
||||||
padding: 4px 0.5rem
|
padding: 4px 0.5rem
|
||||||
position: sticky
|
position: sticky
|
||||||
left: 0
|
left: 0
|
||||||
background: var(--hover-block)
|
background: var(--block-hover)
|
||||||
border-top-left-radius: "calc(%s - 1px)" % $border-block
|
border-top-left-radius: "calc(%s - 1px)" % $border-block
|
||||||
border-top-right-radius: "calc(%s - 1px)" % $border-block
|
border-top-right-radius: "calc(%s - 1px)" % $border-block
|
||||||
border-bottom: 1px solid var(--block-border)
|
border-bottom: 1px solid var(--block-border)
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
padding-right: 2rem
|
padding-right: 2rem
|
||||||
padding: 4px
|
padding: 4px
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
background: var(--hover-block)
|
background: var(--block-hover)
|
||||||
|
|
||||||
.sidebar-toggle.mobile
|
.sidebar-toggle.mobile
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
|
|
|
@ -90,7 +90,7 @@ hover-block($v, $h, $br = 4px)
|
||||||
padding: $v $h
|
padding: $v $h
|
||||||
trans2 color background
|
trans2 color background
|
||||||
&:hover
|
&:hover
|
||||||
background: var(--hover-block)
|
background: var(--block-hover)
|
||||||
|
|
||||||
|
|
||||||
inside-box($fs = $fs-15)
|
inside-box($fs = $fs-15)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
--site-bg: $c-site-bg-light
|
--site-bg: $c-site-bg-light
|
||||||
--block: $c-block-light
|
--block: $c-block-light
|
||||||
--block-border: mix($c-block-light, $c-text-light, 95)
|
--block-border: mix($c-block-light, $c-text-light, 95)
|
||||||
--hover-block: mix($c-block-light, $c-text-light, 98)
|
--block-hover: mix($c-block-light, $c-text-light, 98)
|
||||||
--text-p0: $c-title-light
|
--text-p0: $c-title-light
|
||||||
--text-p1: $c-text-light
|
--text-p1: $c-text-light
|
||||||
--text-p2: mix($c-text-light, $c-site-bg-light, 80)
|
--text-p2: mix($c-text-light, $c-site-bg-light, 80)
|
||||||
|
@ -16,7 +16,7 @@ body[theme='dark']
|
||||||
--site-bg: $c-site-bg-dark
|
--site-bg: $c-site-bg-dark
|
||||||
--block: $c-block-dark
|
--block: $c-block-dark
|
||||||
--block-border: mix($c-block-dark, $c-text-dark, 90)
|
--block-border: mix($c-block-dark, $c-text-dark, 90)
|
||||||
--hover-block: mix($c-block-dark, $c-text-dark, 95)
|
--block-hover: mix($c-block-dark, $c-text-dark, 95)
|
||||||
--text-p0: $c-title-dark
|
--text-p0: $c-title-dark
|
||||||
--text-p1: $c-text-dark
|
--text-p1: $c-text-dark
|
||||||
--text-p2: mix($c-text-dark, $c-site-bg-dark, 70)
|
--text-p2: mix($c-text-dark, $c-site-bg-dark, 70)
|
||||||
|
|
|
@ -38,7 +38,7 @@ article.md
|
||||||
&:first-child
|
&:first-child
|
||||||
margin-top: 0
|
margin-top: 0
|
||||||
h3
|
h3
|
||||||
margin-top: 3rem
|
margin-top: 1.5rem
|
||||||
font-weight: 400
|
font-weight: 400
|
||||||
h4,h5,h6
|
h4,h5,h6
|
||||||
font-weight: 500
|
font-weight: 500
|
||||||
|
@ -70,6 +70,10 @@ article.md code
|
||||||
font-family: $ff-code
|
font-family: $ff-code
|
||||||
word-break: break-all
|
word-break: break-all
|
||||||
font-size: $fs-p
|
font-size: $fs-p
|
||||||
|
background: var(--block)
|
||||||
|
padding: 2px
|
||||||
|
border-radius: 2px
|
||||||
|
border: 1px solid var(--block-border)
|
||||||
|
|
||||||
// div
|
// div
|
||||||
article.md>div
|
article.md>div
|
||||||
|
|
|
@ -22,7 +22,7 @@ nav.cap
|
||||||
white-space: nowrap
|
white-space: nowrap
|
||||||
trans1 background
|
trans1 background
|
||||||
&.active, &:hover
|
&.active, &:hover
|
||||||
background: var(--hover-block)
|
background: var(--block-hover)
|
||||||
color: var(--text-p1)
|
color: var(--text-p1)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
min-width: 280px
|
min-width: 280px
|
||||||
width: 40vw
|
width: 40vw
|
||||||
max-width: 460px
|
max-width: 460px
|
||||||
border: 1px solid var(--hover-block)
|
border: 1px solid var(--block-hover)
|
||||||
.img
|
.img
|
||||||
min-width: 100%
|
min-width: 100%
|
||||||
min-height: 140px
|
min-height: 140px
|
||||||
|
|
|
@ -47,12 +47,12 @@
|
||||||
line-height: 1.2
|
line-height: 1.2
|
||||||
border-radius: 4px
|
border-radius: 4px
|
||||||
&:hover
|
&:hover
|
||||||
background: var(--hover-block)
|
background: var(--block-hover)
|
||||||
&.active
|
&.active
|
||||||
color: var(--theme-highlight) !important
|
color: var(--theme-highlight) !important
|
||||||
|
|
||||||
#toc .doc-tree
|
#toc .doc-tree
|
||||||
border-left: 2px solid var(--hover-block)
|
border-left: 2px solid var(--block-hover)
|
||||||
a.doc-tree-link
|
a.doc-tree-link
|
||||||
color: var(--text-p3)
|
color: var(--text-p3)
|
||||||
padding: 0.5rem
|
padding: 0.5rem
|
||||||
|
@ -65,10 +65,10 @@
|
||||||
color: var(--text-p2)
|
color: var(--text-p2)
|
||||||
font-size: $fs-14
|
font-size: $fs-14
|
||||||
&:hover
|
&:hover
|
||||||
background: var(--hover-block)
|
background: var(--block-hover)
|
||||||
|
|
||||||
#toc .widget-body.wiki
|
#toc .widget-body.wiki
|
||||||
.doc-tree.active
|
.doc-tree.active
|
||||||
border-color: var(--text-meta)
|
border-color: var(--text-meta)
|
||||||
.doc-tree.active:only-child
|
.doc-tree.active:only-child
|
||||||
border-color: var(--hover-block)
|
border-color: var(--block-hover)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
.md .checkbox
|
.md .checkbox
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
|
||||||
margin: 0.25em 0
|
margin: 0.25em 0
|
||||||
font-size: $fs-15
|
font-size: $fs-15
|
||||||
line-height: 1.2
|
line-height: 1.2
|
||||||
|
@ -21,6 +20,8 @@
|
||||||
margin-right: 8px
|
margin-right: 8px
|
||||||
if hexo-config('tag_plugins.checkbox.interactive') != true
|
if hexo-config('tag_plugins.checkbox.interactive') != true
|
||||||
pointer-events: none
|
pointer-events: none
|
||||||
|
span
|
||||||
|
margin-top: 1px
|
||||||
/* Checkbox */
|
/* Checkbox */
|
||||||
input[type=checkbox]
|
input[type=checkbox]
|
||||||
&:before, &:after
|
&:before, &:after
|
||||||
|
@ -155,7 +156,7 @@
|
||||||
|
|
||||||
|
|
||||||
.tag-plugin.checkbox
|
.tag-plugin.checkbox
|
||||||
--theme: $color-theme
|
--theme: $c-blue
|
||||||
|
|
||||||
.tag-plugin.checkbox[color='red']
|
.tag-plugin.checkbox[color='red']
|
||||||
--theme: mix($c-red, $c-card-light, 90)
|
--theme: mix($c-red, $c-card-light, 90)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
margin: 0
|
margin: 0
|
||||||
border-left: 1px solid var(--block-border)
|
border-left: 1px solid var(--block-border)
|
||||||
display: inline-block
|
display: inline-block
|
||||||
background: var(--hover-block)
|
background: var(--block-hover)
|
||||||
line-height: 0
|
line-height: 0
|
||||||
height: 100%
|
height: 100%
|
||||||
font-size: 1rem
|
font-size: 1rem
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
>img
|
>img
|
||||||
trans2 transform box-shadow
|
trans2 transform box-shadow
|
||||||
&:hover
|
&:hover
|
||||||
background: var(--hover-block)
|
background: var(--block-hover)
|
||||||
img
|
img
|
||||||
transform: scale(1.2) rotate(8deg)
|
transform: scale(1.2) rotate(8deg)
|
||||||
box-shadow: $boxshadow-card-float
|
box-shadow: $boxshadow-card-float
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
$tbr = $border-block
|
||||||
|
|
||||||
|
.tag-plugin.tabs
|
||||||
|
display: block
|
||||||
|
position: relative
|
||||||
|
margin-top: 1rem
|
||||||
|
margin-bottom: 1rem
|
||||||
|
border-radius: $tbr
|
||||||
|
border: 1px solid var(--block-border)
|
||||||
|
font-size: $fs-14
|
||||||
|
|
||||||
|
.tag-plugin.tabs
|
||||||
|
ul.nav-tabs
|
||||||
|
display: flex
|
||||||
|
overflow-x: auto
|
||||||
|
white-space: nowrap
|
||||||
|
justify-content: flex-start
|
||||||
|
margin: 0 !important
|
||||||
|
padding: 8px 8px 0 8px
|
||||||
|
background: var(--block)
|
||||||
|
border-radius: $tbr $tbr 0 0
|
||||||
|
line-height: 1.5
|
||||||
|
li.tab
|
||||||
|
list-style-type: none
|
||||||
|
margin-top: 0
|
||||||
|
margin-bottom: 0
|
||||||
|
&:last-child
|
||||||
|
padding-right: 1rem
|
||||||
|
a
|
||||||
|
display: block
|
||||||
|
cursor: pointer
|
||||||
|
border-radius: $tbr $tbr 0 0
|
||||||
|
padding: 0.5rem
|
||||||
|
text-align: center
|
||||||
|
font-size: $fs-14
|
||||||
|
line-height: inherit
|
||||||
|
font-weight: 700
|
||||||
|
color: var(--text-p3)
|
||||||
|
border: 1px solid transparent
|
||||||
|
&:hover
|
||||||
|
color: var(--text-p1)
|
||||||
|
i
|
||||||
|
pointer-events: none
|
||||||
|
&.active a
|
||||||
|
cursor: default
|
||||||
|
color: var(--text-p1)
|
||||||
|
background: var(--card)
|
||||||
|
border: 1px solid var(--block-border)
|
||||||
|
border-bottom: 1px solid var(--card)
|
||||||
|
|
||||||
|
.tab-content
|
||||||
|
border-top: 1px solid var(--block-border)
|
||||||
|
margin-top: -1px
|
||||||
|
background: var(--card)
|
||||||
|
border-radius: 0 0 $tbr $tbr
|
||||||
|
.tab-pane
|
||||||
|
padding: 1rem
|
||||||
|
&:not(.active)
|
||||||
|
display: none
|
||||||
|
&.active
|
||||||
|
display: block
|
||||||
|
>
|
||||||
|
p,.tabs,ul,ol,.highlight,.note
|
||||||
|
&:first-child
|
||||||
|
margin-top: 0
|
||||||
|
&:last-child
|
||||||
|
margin-bottom: 0
|
||||||
|
|
||||||
|
|
||||||
|
.tag-plugin.tabs .tab-pane[codeblock]
|
||||||
|
padding: 0
|
||||||
|
.highlight
|
||||||
|
border: none
|
||||||
|
border-radius: 0
|
||||||
|
background: transparent
|
||||||
|
margin: 0
|
|
@ -230,7 +230,36 @@ const init = {
|
||||||
$this.innerText = relativeValue
|
$this.innerText = relativeValue
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
/**
|
||||||
|
* Tabs tag listener (without twitter bootstrap).
|
||||||
|
*/
|
||||||
|
registerTabsTag: function() {
|
||||||
|
// Binding `nav-tabs` & `tab-content` by real time permalink changing.
|
||||||
|
document.querySelectorAll('.tabs ul.nav-tabs .tab').forEach(element => {
|
||||||
|
element.addEventListener('click', event => {
|
||||||
|
event.preventDefault();
|
||||||
|
// Prevent selected tab to select again.
|
||||||
|
if (element.classList.contains('active')) return;
|
||||||
|
// Add & Remove active class on `nav-tabs` & `tab-content`.
|
||||||
|
[...element.parentNode.children].forEach(target => {
|
||||||
|
target.classList.toggle('active', target === element);
|
||||||
|
});
|
||||||
|
// https://stackoverflow.com/questions/20306204/using-queryselector-with-ids-that-are-numbers
|
||||||
|
const tActive = document.getElementById(element.querySelector('a').getAttribute('href').replace('#', ''));
|
||||||
|
[...tActive.parentNode.children].forEach(target => {
|
||||||
|
target.classList.toggle('active', target === tActive);
|
||||||
|
});
|
||||||
|
// Trigger event
|
||||||
|
tActive.dispatchEvent(new Event('tabs:click', {
|
||||||
|
bubbles: true
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
window.dispatchEvent(new Event('tabs:register'));
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,7 +267,7 @@ const init = {
|
||||||
init.toc()
|
init.toc()
|
||||||
init.sidebar()
|
init.sidebar()
|
||||||
init.relativeDate(document.querySelectorAll('#post-meta time'))
|
init.relativeDate(document.querySelectorAll('#post-meta time'))
|
||||||
|
init.registerTabsTag()
|
||||||
|
|
||||||
// scrollreveal
|
// scrollreveal
|
||||||
if (stellar.plugins.scrollreveal) {
|
if (stellar.plugins.scrollreveal) {
|
||||||
|
|
Loading…
Reference in New Issue