From b771e2297e0af858391b4b3a04e322625b9e49ba Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 12 Apr 2019 02:12:00 -0700 Subject: [PATCH] Avoid an unstyled rendering moment with code examples This renders the tabs and all the jQuery classes server-side, so that the code examples are rendered correctly on the page's first load rather than waiting for the JavaScript to activate. This also has a side effect of making them look correct with JavaScript disabled. This also adds a little additional styling in the noscript stylesheet to make code examples look better on a narrow viewport with JavaScript disabled. --- helpers/sass_helpers.rb | 39 +++++++++++++++++++++++++-------- source/assets/css/noscript.scss | 33 ++++++++++++++++++++++++++++ source/assets/js/sass.js | 22 +------------------ 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/helpers/sass_helpers.rb b/helpers/sass_helpers.rb index 41262b7..4317ea6 100644 --- a/helpers/sass_helpers.rb +++ b/helpers/sass_helpers.rb @@ -215,17 +215,23 @@ module SassHelpers @unique_id ||= 0 @unique_id += 1 id = @unique_id - contents = [] + ul_contents = [] + ul_contents << _syntax_tab("SCSS", "scss", id, enabled: scss) if scss + ul_contents << _syntax_tab("Sass", "sass", id, enabled: !scss) if sass + ul_contents << _syntax_tab("CSS", "css", id) if css + + contents = [ + content_tag(:ul, ul_contents, + class: "ui-tabs-nav ui-helper-reset ui-helper-clearfix") + ] if scss contents << - _syntax_div("SCSS Syntax", "scss", scss_sections, scss_paddings, id) + _syntax_div("SCSS Syntax", "scss", scss_sections, scss_paddings, id, enabled: scss) end - if sass contents << - _syntax_div("Sass Syntax", "sass", sass_sections, sass_paddings, id) + _syntax_div("Sass Syntax", "sass", sass_sections, sass_paddings, id, enabled: !scss) end - if css contents << _syntax_div("CSS Output", "css", css_sections, css_paddings, id) @@ -245,8 +251,7 @@ module SassHelpers end text = content_tag(:div, contents, - class: "code-example #{'can-split' if can_split}", - "data-unique-id": @unique_id, + class: "code-example ui-tabs #{'can-split' if can_split}", "style": ("--split-location: #{split_location * 100}%" if split_location)) # Newlines between tags cause Markdown to parse these blocks incorrectly. @@ -274,15 +279,31 @@ module SassHelpers end end + # Returns the text of an example tab for a single syntax. + def _syntax_tab(name, syntax, id, enabled: false) + content_tag(:li, [ + content_tag(:a, name, href: "#example-#{id}-#{syntax}", class: "ui-tabs-anchor") + ], class: [ + "ui-tabs-tab", + ('css-tab' if syntax == 'css'), + ('ui-tabs-active' if enabled) + ].compact.join(' ')) + end + # Returns the text of an example div for a single syntax. - def _syntax_div(name, syntax, sections, paddings, id) + def _syntax_div(name, syntax, sections, paddings, id, enabled: false) + inactive = syntax == 'scss' ? '' : 'ui-tabs-panel-inactive' content_tag(:div, [ content_tag(:h3, name, class: 'visuallyhidden'), *sections.zip(paddings).map do |section, padding| padding = 0 if padding.nil? || padding.negative? _render_markdown("```#{syntax}\n#{section}#{"\n" * padding}\n```") end - ], id: "example-#{id}-#{syntax}", class: syntax) + ], id: "example-#{id}-#{syntax}", class: [ + "ui-tabs-panel", + syntax, + ('ui-tabs-panel-inactive' unless enabled) + ].compact.join(' ')) end # Returns the version for the given implementation (`:dart`, `:ruby`, or diff --git a/source/assets/css/noscript.scss b/source/assets/css/noscript.scss index 866d45a..384ffbb 100644 --- a/source/assets/css/noscript.scss +++ b/source/assets/css/noscript.scss @@ -1,6 +1,8 @@ // Styles that are included only when JavaScript is disabled. These override the // default styles to make them work better without JS. +@import "functions"; + // Make the in-page table of contents fully open by default, since we can't // dynamically expand it. .page-sections li a.section { @@ -8,3 +10,34 @@ + ul {display: block; } } +@mixin -sequence-css-tabs { + .code-example { + ul { display: none; } + + .ui-tabs-panel { + position: relative; + + pre::after { + position: absolute; + top: 5px; + right: 5px; + opacity: 0.5; + } + } + + .scss pre::after { content: "SCSS"; } + .sass pre::after { content: "Sass"; } + .css { + display: block; + pre::after { content: "CSS"; } + } + } +} + +@media screen and (max-width: sl-px-to-rem(1500.00001px)) { + body.documentation { @include -sequence-css-tabs } +} + +@media screen and (max-width: sl-px-to-rem(1000.00001px)) { + body.guide { @include -sequence-css-tabs } +} diff --git a/source/assets/js/sass.js b/source/assets/js/sass.js index e3061de..01416cb 100644 --- a/source/assets/js/sass.js +++ b/source/assets/js/sass.js @@ -28,26 +28,8 @@ tab.click(function () { $(function() { $(".code-example").each(function() { var figure = $(this); - var id = figure.attr("data-unique-id"); - var ul = $(""); - - if (figure.find(".scss").length) { - ul.append("
  • SCSS
  • "); - } - - if (figure.find(".sass").length) { - ul.append("
  • Sass
  • "); - } - - var hasCssTab = figure.find(".css").length; - if (hasCssTab) { - ul.append( - $("
  • ") - .prepend("CSS")); - } - - figure.prepend(ul).tabs({ + figure.tabs({ active: 0, beforeActivate: function(event, ui) { // If multiple panels are visible, the CSS tab shouldn't be clickable. @@ -70,8 +52,6 @@ $(function() { } }); var allPanels = figure.find(".ui-tabs-panel"); - - allPanels.slice(1).addClass('ui-tabs-panel-inactive'); allPanels.css('display', ''); });