From d07ddaa85dfffd8da786c2ce0b71561a19188057 Mon Sep 17 00:00:00 2001 From: "cinwell.li" Date: Tue, 29 Nov 2016 21:42:48 +0800 Subject: [PATCH] 0.6.0 (#12) * Fix ineffective option, fixed #10 * Feat: dropdown list, #6 * Fix repo url * Feat: sidebar with toggle * Update doc --- 404.dev.html | 8 +--- CHANGELOG.md | 8 ++++ docs/404.html | 6 ++- docs/README.md | 17 ++++++++ docs/zh-cn.md | 17 ++++++++ src/event.js | 11 +++++ src/index.js | 6 ++- src/render.js | 13 +++--- src/tpl.js | 8 ++++ themes/buble.css | 101 ++++++++++++++++++++++++++++++++++++++++++++ themes/pure.css | 101 ++++++++++++++++++++++++++++++++++++++++++++ themes/vue.css | 108 ++++++++++++++++++++++++++++++++++++++++++----- 12 files changed, 380 insertions(+), 24 deletions(-) diff --git a/404.dev.html b/404.dev.html index b2437dfdc..81e930dee 100644 --- a/404.dev.html +++ b/404.dev.html @@ -3,14 +3,10 @@ - + -
- + diff --git a/CHANGELOG.md b/CHANGELOG.md index a21a9ac7f..ea38ec938 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.6.0 +### Features +- Navbar support dropdown list, #6 +- Sidebar with toggle + +### Bug fixes +- Fix ineffective option, fixed #10 + ## 0.5.0 ### Features - Custom sidebars and navbars by markdown file diff --git a/docs/404.html b/docs/404.html index aad28f623..485fcec29 100644 --- a/docs/404.html +++ b/docs/404.html @@ -14,5 +14,9 @@
- + diff --git a/docs/README.md b/docs/README.md index 1be47040d..678b1c431 100644 --- a/docs/README.md +++ b/docs/README.md @@ -121,6 +121,14 @@ Root element. ``` +#### sidebar-toggle + +Sidebar with toggle + +```html + +``` + #### sidebar Custom sidebar. if it'set, the TOC will be disabeld. Bind global variables on the `data-sidebar`. @@ -196,6 +204,15 @@ The contents of the file can be: - [chinese](/zh-cn) ``` +If you write a sub level list, it will generate a dropdown list. + +```markdown +- [download](/download) +- language + - [en](/) + - [chinese](/zh-cn) +``` + ## FAQ ### Why use `404.html` instead of `index.html` diff --git a/docs/zh-cn.md b/docs/zh-cn.md index a664c4e22..150194440 100644 --- a/docs/zh-cn.md +++ b/docs/zh-cn.md @@ -119,6 +119,14 @@ docsify serve docs ``` +#### sidebar-toggle + +Sidebar 开关按钮 + +```html + +``` + #### sidebar 设置后 TOC 功能将不可用,适合导航较多的文档,`data-sidebar` 传入全局变量名。 @@ -193,6 +201,15 @@ docsify serve docs - [中文](/zh-cn) ``` +当然也支持二级列表,将生成一个下拉列表 +```markdown +- [download](/download) +- language + - [en](/) + - [中文](/zh-cn) +``` + + ## FAQ ### 为什么是 `404.html` 而不用 `index.html` diff --git a/src/event.js b/src/event.js index 4eff7bbf1..357c64c39 100644 --- a/src/event.js +++ b/src/event.js @@ -70,3 +70,14 @@ export function activeLink (dom, activeParent) { } }) } + +/** + * sidebar toggle + */ +export function bindToggle (dom) { + dom = typeof dom === 'object' ? dom : document.querySelector(dom) + if (!dom) return + const main = document.querySelector('main') + + dom.addEventListener('click', () => main.classList.toggle('close')) +} diff --git a/src/index.js b/src/index.js index 902a1ffa3..0596f5aae 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ const OPTIONS = { repo: '', maxLevel: 6, sidebar: '', + sidebarToggle: false, loadSidebar: null, loadNavbar: null } @@ -15,7 +16,7 @@ const script = document.currentScript || [].slice.call(document.getElementsByTag if (script) { for (const prop in OPTIONS) { const val = script.getAttribute('data-' + camel2kebab(prop)) - OPTIONS[prop] = isNil(val) ? OPTIONS[prop] : true + OPTIONS[prop] = isNil(val) ? OPTIONS[prop] : (val || true) } if (OPTIONS.loadSidebar === true) OPTIONS.loadSidebar = '_sidebar.md' if (OPTIONS.loadNavbar === true) OPTIONS.loadNavbar = '_navbar.md' @@ -34,7 +35,8 @@ const Docsify = function () { // Render markdown file load(`${loc}.md`) - .then(render.renderArticle, _ => render.renderArticle()) + .then(content => render.renderArticle(content, OPTIONS), + _ => render.renderArticle(null, OPTIONS)) // Render sidebar if (OPTIONS.loadSidebar) { diff --git a/src/render.js b/src/render.js index c812641ad..e4fc058e5 100644 --- a/src/render.js +++ b/src/render.js @@ -1,7 +1,7 @@ import marked from 'marked' import Prism from 'prismjs' import * as tpl from './tpl' -import { activeLink, scrollActiveSidebar } from './event' +import { activeLink, scrollActiveSidebar, bindToggle } from './event' import { genTree } from './util' const renderTo = function (dom, content) { @@ -38,17 +38,20 @@ marked.setOptions({ renderer }) export function renderApp (dom, replace, opts) { const nav = document.querySelector('nav') || document.createElement('nav') - dom[replace ? 'outerHTML' : 'innerHTML'] = tpl.corner(opts.repo) + tpl.main() + dom[replace ? 'outerHTML' : 'innerHTML'] = tpl.toggle(opts.sidebarToggle) + tpl.corner(opts.repo) + tpl.main() document.body.insertBefore(nav, document.body.children[0]) + + // bind toggle + bindToggle('button.sidebar-toggle') } /** * article */ -export function renderArticle (content = 'not found') { +export function renderArticle (content = 'not found', OPTIONS) { renderTo('article', marked(content)) - if (!renderSidebar.rendered) renderSidebar(null) - if (!renderNavbar.rendered) renderNavbar(null) + if (!renderSidebar.rendered) renderSidebar(null, OPTIONS) + if (!renderNavbar.rendered) renderNavbar(null, OPTIONS) } /** diff --git a/src/tpl.js b/src/tpl.js index 78a605e71..5c74a8b3e 100644 --- a/src/tpl.js +++ b/src/tpl.js @@ -7,6 +7,7 @@ export function corner (data) { if (!data) return '' if (!/\/\//.test(data)) data = 'https://github.com/' + data + data = data.replace(/^git\+/, '') return ` @@ -31,6 +32,13 @@ export function main () { ` } +export function toggle (bool) { + if (!bool) return '' + return `` +} + /** * Render tree * @param {Array} tree diff --git a/themes/buble.css b/themes/buble.css index a9324aa58..725a08745 100644 --- a/themes/buble.css +++ b/themes/buble.css @@ -21,6 +21,51 @@ nav { text-align: right; } +nav ul, nav li { + list-style: none; + display: inline-block; +} + +/* navbar dropdown */ +nav li { + position: relative; +} + +nav li ul { + padding: 0; + max-height: 0; + position: absolute; + top: 24px; + background-color: rgba(255, 255, 255, .6); + border: 1px solid #0074D9; + right: 0; + overflow: hidden; + opacity: 0; + overflow-y: auto; + transition: opacity .3s ease, max-height .5s ease; +} + +nav li:hover ul { + opacity: 1; + max-height: 100px; +} + +nav li ul li { + display: block; +} + +nav li ul a { + display: block; + font-size: 14px; + margin: 0; + padding: 4px 10px; + white-space: nowrap; +} + +nav li ul a.active { + border-bottom: 0; +} + nav a { margin: 0 1em; padding: 5px 0; @@ -108,6 +153,8 @@ main { width: 16em; z-index: 1; padding-top: 40px; + left: 0; + transition: left 250ms ease-out; } .sidebar ul { @@ -138,6 +185,32 @@ main { color: #333; } +/* sidebar toggle */ +.sidebar-toggle { + background-color: transparent; + border: 0; + bottom: 10px; + left: 10px; + position: absolute; + text-align: center; + transition: opacity .3s; + width: 30px; + z-index: 10; + outline: none; +} + +.sidebar-toggle:hover { + opacity: .4; +} + +.sidebar-toggle span { + background-color: #0074D9; + display: block; + height: 2px; + margin-bottom: 4px; + width: 16px; +} + /* main content */ .content { bottom: 0; @@ -148,15 +221,43 @@ main { top: 0; overflow-x: hidden; padding-top: 20px; + transition: left 250ms ease; +} + +main.close .sidebar { + left: -16em; +} + +main.close .content { + left: 0; } @media screen and (max-width: 600px) { + nav { + margin-top: 16px; + } + + nav li ul { + top: 30px; + } + .sidebar { left: -16em; + transition: left 250ms ease; } .content { left: 0; + min-width: 100vw; + transition: left 250ms ease-out; + } + + main.close .sidebar { + left: 0; + } + + main.close .content { + left: 16em; } } diff --git a/themes/pure.css b/themes/pure.css index a2aa812ba..b1e75160a 100644 --- a/themes/pure.css +++ b/themes/pure.css @@ -19,6 +19,51 @@ nav { text-align: right; } +nav ul, nav li { + list-style: none; + display: inline-block; +} + +/* navbar dropdown */ +nav li { + position: relative; +} + +nav li ul { + padding: 0; + max-height: 0; + position: absolute; + top: 24px; + background-color: rgba(255, 255, 255, .6); + border: 1px solid #000; + right: 0; + overflow: hidden; + opacity: 0; + overflow-y: auto; + transition: opacity .3s ease, max-height .5s ease; +} + +nav li:hover ul { + opacity: 1; + max-height: 100px; +} + +nav li ul li { + display: block; +} + +nav li ul a { + display: block; + font-size: 14px; + margin: 0; + padding: 4px 10px; + white-space: nowrap; +} + +nav li ul a.active { + border-bottom: 0; +} + nav a { margin: 0 1em; padding: 5px 0; @@ -91,6 +136,8 @@ main { width: 300px; z-index: 1; padding-top: 40px; + left: 0; + transition: left 250ms ease-out; } .sidebar ul { @@ -111,6 +158,32 @@ main { padding-left: 20px; } +/* sidebar toggle */ +.sidebar-toggle { + background-color: transparent; + border: 0; + bottom: 10px; + left: 10px; + position: absolute; + text-align: center; + transition: opacity .3s; + width: 30px; + z-index: 10; + outline: none; +} + +.sidebar-toggle:hover { + opacity: .4; +} + +.sidebar-toggle span { + background-color: #000; + display: block; + height: 2px; + margin-bottom: 4px; + width: 16px; +} + /* main content */ .content { bottom: 0; @@ -121,15 +194,43 @@ main { top: 0; overflow-x: hidden; padding-top: 20px; + transition: left 250ms ease; +} + +main.close .sidebar { + left: -300px; +} + +main.close .content { + left: 0; } @media screen and (max-width: 600px) { + nav { + margin-top: 16px; + } + + nav li ul { + top: 30px; + } + .sidebar { left: -300px; + transition: left 250ms ease; } .content { left: 0; + min-width: 100vw; + transition: left 250ms ease-out; + } + + main.close .sidebar { + left: 0; + } + + main.close .content { + left: 300px; } } diff --git a/themes/vue.css b/themes/vue.css index 0783e33c0..e192351a0 100644 --- a/themes/vue.css +++ b/themes/vue.css @@ -26,6 +26,46 @@ nav ul, nav li { display: inline-block; } +/* navbar dropdown */ +nav li { + position: relative; +} + +nav li ul { + padding: 0; + max-height: 0; + position: absolute; + top: 24px; + background-color: rgba(255, 255, 255, .6); + border: 1px solid #42b983; + right: 0; + overflow: hidden; + opacity: 0; + overflow-y: auto; + transition: opacity .3s ease, max-height .5s ease; +} + +nav li:hover ul { + opacity: 1; + max-height: 100px; +} + +nav li ul li { + display: block; +} + +nav li ul a { + display: block; + font-size: 14px; + margin: 0; + padding: 4px 10px; + white-space: nowrap; +} + +nav li ul a.active { + border-bottom: 0; +} + nav a { margin: 0 1em; padding: 5px 0; @@ -112,6 +152,8 @@ main { width: 300px; z-index: 1; padding-top: 40px; + left: 0; + transition: left 250ms ease-out; } .sidebar ul { @@ -124,7 +166,7 @@ main { } .sidebar li { - margin: 12px 15px; + margin: 6px 15px; } .sidebar ul li a { @@ -146,6 +188,32 @@ main { font-weight: 500; } +/* sidebar toggle */ +.sidebar-toggle { + background-color: transparent; + border: 0; + bottom: 10px; + left: 10px; + position: absolute; + text-align: center; + transition: opacity .3s; + width: 30px; + z-index: 10; + outline: none; +} + +.sidebar-toggle:hover { + opacity: .4; +} + +.sidebar-toggle span { + background-color: #42b983; + display: block; + height: 2px; + margin-bottom: 4px; + width: 16px; +} + /* main content */ .content { bottom: 0; @@ -156,15 +224,43 @@ main { top: 0; overflow-x: hidden; padding-top: 20px; + transition: left 250ms ease; +} + +main.close .sidebar { + left: -300px; +} + +main.close .content { + left: 0; } @media screen and (max-width: 600px) { + nav { + margin-top: 16px; + } + + nav li ul { + top: 30px; + } + .sidebar { left: -300px; + transition: left 250ms ease; } .content { left: 0; + min-width: 100vw; + transition: left 250ms ease-out; + } + + main.close .sidebar { + left: 0; + } + + main.close .content { + left: 300px; } } @@ -402,6 +498,7 @@ main { font-size: 0.8em; line-height: inherit; margin: 0 2px; + overflow-x: auto; padding: 3px 5px; white-space: inherit; } @@ -416,15 +513,6 @@ code .token { -moz-osx-font-smoothing: initial; } -pre code { - overflow-x: auto; - padding: 0; - background-color: #f8f8f8; - padding: 0.8em 0.8em 0.4em; - line-height: 1.1em; - border-radius: 2px; -} - pre::after { color: #ccc; content: attr(data-lang);