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.
This commit is contained in:
Natalie Weizenbaum 2019-04-12 02:12:00 -07:00
parent e7ffef4fc9
commit b771e2297e
3 changed files with 64 additions and 30 deletions

View File

@ -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

View File

@ -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 }
}

View File

@ -28,26 +28,8 @@ tab.click(function () {
$(function() {
$(".code-example").each(function() {
var figure = $(this);
var id = figure.attr("data-unique-id");
var ul = $("<ul></ul>");
if (figure.find(".scss").length) {
ul.append("<li><a href='#example-" + id + "-scss'>SCSS</a></li>");
}
if (figure.find(".sass").length) {
ul.append("<li><a href='#example-" + id + "-sass'>Sass</a></li>");
}
var hasCssTab = figure.find(".css").length;
if (hasCssTab) {
ul.append(
$("<li class='css-tab'></li>")
.prepend("<a href='#example-" + id + "-css'>CSS</a>"));
}
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', '');
});