diff --git a/src/v2/examples/themes.md b/src/v2/examples/themes.md new file mode 100644 index 0000000000..c360b566ac --- /dev/null +++ b/src/v2/examples/themes.md @@ -0,0 +1,116 @@ +--- +title: Themes +type: examples +is_new: true +order: 13 +--- +> With the examples below built by our partners from [Creative Tim](https://creative-tim.com?affiliate_id=116187) you can see how a real world application is built, the technology stack behind it and how most of the concepts you've learned so far apply in a real world application. + +{% raw %} +
+
+ + +
+

{{product.title}}

+ {{product.price}}$ +
+
{{product.description}}
+
+
+ + See More Themes + +
+
+ +{% endraw %} diff --git a/themes/vue/source/css/_header.styl b/themes/vue/source/css/_header.styl index 231427f9be..b63e8c62c9 100644 --- a/themes/vue/source/css/_header.styl +++ b/themes/vue/source/css/_header.styl @@ -1,5 +1,15 @@ $header-height = 40px +red-dot-before(leftPos = -8px) + content: "" + width: 0 + height: 0 + border 2px solid $red + border-radius 50% + position: absolute + top: calc(50% - 1px) + left: leftPos + #header background-color: #fff height: $header-height @@ -47,6 +57,8 @@ body.docs top: 50% margin-top: -4px left: 8px + &.new::before + red-dot-before(8px) .nav-link padding-bottom: 3px @@ -55,6 +67,8 @@ body.docs border-bottom: 3px solid $green &.team margin-left: 10px + &.new::before + red-dot-before() .new-label position: absolute @@ -130,4 +144,4 @@ body.docs @media print #header - display: none \ No newline at end of file + display: none diff --git a/themes/vue/source/css/_themes-example.styl b/themes/vue/source/css/_themes-example.styl new file mode 100644 index 0000000000..cc4d92ddfe --- /dev/null +++ b/themes/vue/source/css/_themes-example.styl @@ -0,0 +1,65 @@ +$media-width = 1300px +$item-margin-bottom = 10px +$item-box-shadow = 0 2rem 1.5rem -1.5rem rgba(33,37,41,.15), 0 0 1.5rem 0.5rem rgba(33,37,41,.05) +$item-box-shadow-hover = 0 2.25rem 1.5rem -1.5rem rgba(33,37,41,.2),0 0 1.5rem .5rem rgba(33,37,41,.05); + +.themes-grid + display: flex + flex-wrap: wrap + justify-content space-between + .item-preview + width: 290px + margin-bottom 25px + .item-preview-img + transition: .15s box-shadow,.15s transform + border-radius: .5rem + box-shadow $item-box-shadow + overflow: hidden + display block + &:hover + transform: translateY(-0.25rem) + box-shadow: $item-box-shadow-hover + img + max-width: 100% + height: auto + border-radius: .5rem + vertical-align: middle + border-style: none + .item-preview-title-container + display flex + justify-content space-between + align-items center + h3.item-preview-title + margin-top: .7rem + margin-bottom: 0 + &.free::after + content: "FREE"; + display: inline-block + font-size: 10px + font-weight: 600 + color: #fff + background-color: $green + line-height: 14px + padding: 0 4px + border-radius: 3px + margin-left: 5px + vertical-align: middle + position: relative + top: -1px + .item-preview-price + margin-top: .7rem + .item-preview-description + font-size: .9rem + .see-more-container + display: flex + justify-content center + width: 100% + .see-more-link + color: $green + +@media screen and (max-width: $media-width) + .themes-grid + justify-content center + .item-preview + justify-content center + width: 380px diff --git a/themes/vue/source/css/index.styl b/themes/vue/source/css/index.styl index 0613877a05..3795a04679 100644 --- a/themes/vue/source/css/index.styl +++ b/themes/vue/source/css/index.styl @@ -3,6 +3,7 @@ @import "_sidebar" @import "_sponsors-index" @import "_modal" +@import "_themes-example" $width = 900px $space = 40px diff --git a/themes/vue/source/css/page.styl b/themes/vue/source/css/page.styl index e6bc76ae1c..c80a2ed9d6 100644 --- a/themes/vue/source/css/page.styl +++ b/themes/vue/source/css/page.styl @@ -14,6 +14,7 @@ @import "_modal" @import "_scrimba" @import "_vue-mastery" +@import "_themes-example" #header box-shadow: 0 0 1px rgba(0,0,0,.25) diff --git a/themes/vue/source/js/common.js b/themes/vue/source/js/common.js index 945afeeb86..b04f3b7050 100644 --- a/themes/vue/source/js/common.js +++ b/themes/vue/source/js/common.js @@ -2,6 +2,7 @@ initHashLevelRedirects() initMobileMenu() initVideoModal() + initNewNavLinks() if (PAGE_TYPE) { initVersionSelect() initApiSpecLinks() @@ -189,6 +190,50 @@ } } + /** + * Initializes a list of links to mark as "updated" by adding a red dot next to them + */ + + function initNewNavLinks() { + var linkExpirePeriod = 60 * 24 * 3600 * 1000 // 2 months + var links = [ + { + title: 'Learn', + updatedOn: new Date("Fri Mar 1 2019") + }, + { + title: 'Examples', + updatedOn: new Date("Fri Mar 1 2019") + } + ] + var today = new Date().getTime() + var updatedLinks = links + .filter(function (link) { + return link.updatedOn.getTime() + linkExpirePeriod > today + }) + .map(function (link) { + return link.title + }) + + var navLinks = document.querySelectorAll('#nav a.nav-link') + var newLinks = [] + navLinks.forEach(function (link) { + if (updatedLinks.indexOf(link.textContent) !== -1) { + newLinks.push(link) + } + }) + newLinks.forEach(function (link) { + var classes = link.classList + var linkKey = `visisted-${link.textContent}` + if (localStorage.getItem(linkKey) || classes.contains('current')) { + classes.remove('updated-link') + localStorage.setItem(linkKey, 'true') + } else { + classes.add('new') + } + }) + } + /** * Mobile burger menu button and gesture for toggling sidebar */ @@ -329,7 +374,6 @@ } else { headers = content.querySelectorAll('h3') each.call(headers, function (h) { - console.log(h) sectionContainer.appendChild(makeLink(h)) allHeaders.push(h) }) @@ -364,9 +408,15 @@ }) .forEach(makeHeaderClickable) - smoothScroll.init({ + new SmoothScroll('a[href*="#"]', { speed: 400, - offset: 0 + offset: function (anchor, toggle) { + let dataTypeAttr = anchor.attributes['data-type'] + if(dataTypeAttr && dataTypeAttr.nodeValue === 'theme-product-title') { + return 300 + } + return 0 + } }) } diff --git a/themes/vue/source/js/smooth-scroll.min.js b/themes/vue/source/js/smooth-scroll.min.js index d9529950e0..f831786ae2 100644 --- a/themes/vue/source/js/smooth-scroll.min.js +++ b/themes/vue/source/js/smooth-scroll.min.js @@ -1,2 +1,2 @@ -/*! smooth-scroll v10.2.1 | (c) 2016 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */ -!(function(e,t){"function"==typeof define&&define.amd?define([],t(e)):"object"==typeof exports?module.exports=t(e):e.smoothScroll=t(e)})("undefined"!=typeof global?global:this.window||this.global,(function(e){"use strict";var t,n,o,r,a,c,l,i={},u="querySelector"in document&&"addEventListener"in e,s={selector:"[data-scroll]",selectorHeader:null,speed:500,easing:"easeInOutCubic",offset:0,callback:function(){}},d=function(){var e={},t=!1,n=0,o=arguments.length;"[object Boolean]"===Object.prototype.toString.call(arguments[0])&&(t=arguments[0],n++);for(var r=function(n){for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(t&&"[object Object]"===Object.prototype.toString.call(n[o])?e[o]=d(!0,e[o],n[o]):e[o]=n[o])};n=0&&t.item(n)!==this;);return n>-1});e&&e!==document;e=e.parentNode)if(e.matches(t))return e;return null},m=function(e){"#"===e.charAt(0)&&(e=e.substr(1));for(var t,n=String(e),o=n.length,r=-1,a="",c=n.charCodeAt(0);++r=1&&t<=31||127==t||0===r&&t>=48&&t<=57||1===r&&t>=48&&t<=57&&45===c?"\\"+t.toString(16)+" ":t>=128||45===t||95===t||t>=48&&t<=57||t>=65&&t<=90||t>=97&&t<=122?n.charAt(r):"\\"+n.charAt(r)}return"#"+a},p=function(e,t){var n;return"easeInQuad"===e&&(n=t*t),"easeOutQuad"===e&&(n=t*(2-t)),"easeInOutQuad"===e&&(n=t<.5?2*t*t:-1+(4-2*t)*t),"easeInCubic"===e&&(n=t*t*t),"easeOutCubic"===e&&(n=--t*t*t+1),"easeInOutCubic"===e&&(n=t<.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1),"easeInQuart"===e&&(n=t*t*t*t),"easeOutQuart"===e&&(n=1- --t*t*t*t),"easeInOutQuart"===e&&(n=t<.5?8*t*t*t*t:1-8*--t*t*t*t),"easeInQuint"===e&&(n=t*t*t*t*t),"easeOutQuint"===e&&(n=1+--t*t*t*t*t),"easeInOutQuint"===e&&(n=t<.5?16*t*t*t*t*t:1+16*--t*t*t*t*t),n||t},g=function(e,t,n){var o=0;if(e.offsetParent)do o+=e.offsetTop,e=e.offsetParent;while(e);return o=Math.max(o-t-n,0),Math.min(o,v()-b())},b=function(){return Math.max(document.documentElement.clientHeight,e.innerHeight||0)},v=function(){return Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},y=function(e){return e&&"object"==typeof JSON&&"function"==typeof JSON.parse?JSON.parse(e):{}},O=function(e){return e?f(e)+e.offsetTop:0},S=function(t,n,o){o||(t.focus(),document.activeElement.id!==t.id&&(t.setAttribute("tabindex","-1"),t.focus(),t.style.outline="none"),e.scrollTo(0,n))};i.animateScroll=function(n,o,c){var i=y(o?o.getAttribute("data-options"):null),u=d(t||s,c||{},i),f="[object Number]"===Object.prototype.toString.call(n),h=f||!n.tagName?null:n;if(f||h){var m=e.pageYOffset;u.selectorHeader&&!r&&(r=document.querySelector(u.selectorHeader)),a||(a=O(r));var b,E,I=f?n:g(h,a,parseInt(u.offset,10)),H=I-m,A=v(),j=0,C=function(t,r,a){var c=e.pageYOffset;(t==r||c==r||e.innerHeight+c>=A)&&(clearInterval(a),S(n,r,f),u.callback(n,o))},M=function(){j+=16,b=j/parseInt(u.speed,10),b=b>1?1:b,E=m+H*p(u.easing,b),e.scrollTo(0,Math.floor(E)),C(E,I,l)},w=function(){clearInterval(l),l=setInterval(M,16)};0===e.pageYOffset&&e.scrollTo(0,0),w()}};var E=function(t){var r;try{r=m(decodeURIComponent(e.location.hash))}catch(t){r=m(e.location.hash)}n&&(n.id=n.getAttribute("data-scroll-id"),i.animateScroll(n,o),n=null,o=null)},I=function(r){if(0===r.button&&!r.metaKey&&!r.ctrlKey&&(o=h(r.target,t.selector),o&&"a"===o.tagName.toLowerCase()&&o.hostname===e.location.hostname&&o.pathname===e.location.pathname&&/#/.test(o.href))){var a;try{a=m(decodeURIComponent(o.hash))}catch(e){a=m(o.hash)}if("#"===a){r.preventDefault(),n=document.body;var c=n.id?n.id:"smooth-scroll-top";return n.setAttribute("data-scroll-id",c),n.id="",void(e.location.hash.substring(1)===c?E():e.location.hash=c)}n=document.querySelector(a),n&&(n.setAttribute("data-scroll-id",n.id),n.id="",o.hash===e.location.hash&&(r.preventDefault(),E()))}},H=function(e){c||(c=setTimeout((function(){c=null,a=O(r)}),66))};return i.destroy=function(){t&&(document.removeEventListener("click",I,!1),e.removeEventListener("resize",H,!1),t=null,n=null,o=null,r=null,a=null,c=null,l=null)},i.init=function(n){u&&(i.destroy(),t=d(s,n||{}),r=t.selectorHeader?document.querySelector(t.selectorHeader):null,a=O(r),document.addEventListener("click",I,!1),e.addEventListener("hashchange",E,!1),r&&e.addEventListener("resize",H,!1))},i})); \ No newline at end of file +/*! smooth-scroll v15.2.1 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */ +!(function(t,e){"function"==typeof define&&define.amd?define([],(function(){return e(t)})):"object"==typeof exports?module.exports=e(t):t.SmoothScroll=e(t)})("undefined"!=typeof global?global:"undefined"!=typeof window?window:this,(function(C){"use strict";var L={ignore:"[data-scroll-ignore]",header:null,topOnEmptyHash:!0,speed:500,speedAsDuration:!1,durationMax:null,durationMin:null,clip:!0,offset:0,easing:"easeInOutCubic",customEasing:null,updateURL:!0,popstate:!0,emitEvents:!0},H=function(){var n={};return Array.prototype.forEach.call(arguments,(function(t){for(var e in t){if(!t.hasOwnProperty(e))return;n[e]=t[e]}})),n},r=function(t){"#"===t.charAt(0)&&(t=t.substr(1));for(var e,n=String(t),o=n.length,a=-1,r="",i=n.charCodeAt(0);++ao.durationMax?o.durationMax:o.durationMin&&a=S)return w.cancelScroll(!0),o=e,a=u,0===(n=i)&&document.body.focus(),a||(n.focus(),document.activeElement!==n&&(n.setAttribute("tabindex","-1"),n.focus(),n.style.outline="none"),C.scrollTo(0,o)),Q("scrollStop",c,i,s),!(A=d=null)},O=function(t){var e,n,o;d||(d=t),v+=t-d,f=l+y*(n=r=1<(r=0===E?0:v/E)?1:r,"easeInQuad"===(e=c).easing&&(o=n*n),"easeOutQuad"===e.easing&&(o=n*(2-n)),"easeInOutQuad"===e.easing&&(o=n<.5?2*n*n:(4-2*n)*n-1),"easeInCubic"===e.easing&&(o=n*n*n),"easeOutCubic"===e.easing&&(o=--n*n*n+1),"easeInOutCubic"===e.easing&&(o=n<.5?4*n*n*n:(n-1)*(2*n-2)*(2*n-2)+1),"easeInQuart"===e.easing&&(o=n*n*n*n),"easeOutQuart"===e.easing&&(o=1- --n*n*n*n),"easeInOutQuart"===e.easing&&(o=n<.5?8*n*n*n*n:1-8*--n*n*n*n),"easeInQuint"===e.easing&&(o=n*n*n*n*n),"easeOutQuint"===e.easing&&(o=1+--n*n*n*n*n),"easeInOutQuint"===e.easing&&(o=n<.5?16*n*n*n*n*n:1+16*--n*n*n*n*n),e.customEasing&&(o=e.customEasing(n)),o||n),C.scrollTo(0,Math.floor(f)),b(f,g)||(A=C.requestAnimationFrame(O),d=t)};0===C.pageYOffset&&C.scrollTo(0,0),m=i,h=c,u||history.pushState&&h.updateURL&&history.pushState({smoothScroll:JSON.stringify(h),anchor:m.id},document.title,m===document.documentElement?"#top":"#"+m.id),Q("scrollStart",c,i,s),w.cancelScroll(!0),C.requestAnimationFrame(O)}};var e=function(t){if(!("matchMedia"in C&&C.matchMedia("(prefers-reduced-motion)").matches)&&0===t.button&&!t.metaKey&&!t.ctrlKey&&"closest"in t.target&&(a=t.target.closest(o))&&"a"===a.tagName.toLowerCase()&&!t.target.closest(I.ignore)&&a.hostname===C.location.hostname&&a.pathname===C.location.pathname&&/#/.test(a.href)){var e=r(a.hash),n=I.topOnEmptyHash&&"#"===e?document.documentElement:document.querySelector(e);(n=n||"#top"!==e?n:document.documentElement)&&(t.preventDefault(),(function(t){if(history.replaceState&&t.updateURL&&!history.state){var e=C.location.hash;e=e||"",history.replaceState({smoothScroll:JSON.stringify(t),anchor:e||C.pageYOffset},document.title,e||C.location.href)}})(I),w.animateScroll(n,a))}},n=function(t){if(null!==history.state&&history.state.smoothScroll&&history.state.smoothScroll===JSON.stringify(I)){var e=history.state.anchor;"string"==typeof e&&e&&!(e=document.querySelector(r(history.state.anchor)))||w.animateScroll(e,null,{updateURL:!1})}};return w.destroy=function(){I&&(document.removeEventListener("click",e,!1),C.removeEventListener("popstate",n,!1),w.cancelScroll(),A=M=a=I=null)},w.init=function(t){if(!("querySelector"in document&&"addEventListener"in C&&"requestAnimationFrame"in C&&"closest"in C.Element.prototype))throw"Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.";w.destroy(),I=H(L,t||{}),M=I.header?document.querySelector(I.header):null,document.addEventListener("click",e,!1),I.updateURL&&I.popstate&&C.addEventListener("popstate",n,!1)},w.init(t),w}}));