Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add code copy buttons to docs #883

Draft
wants to merge 20 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/.eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const highlightPlugin = require("./plugins/highlight");
const iconPlugin = require("./plugins/icons");
const tipPlugin = require("./plugins/tip");
const markdownPlugin = require("./plugins/markdown");
const copyButtonPlugin = require("./plugins/copy-button");

module.exports = function(eleventyConfig) {
eleventyConfig.setQuietMode(true); // Reduce the console output
Expand All @@ -15,6 +16,7 @@ module.exports = function(eleventyConfig) {
eleventyConfig.addPlugin(iconPlugin);
eleventyConfig.addPlugin(headerPlugin);
eleventyConfig.addPlugin(tipPlugin);
eleventyConfig.addPlugin(copyButtonPlugin);

// Version shortcode
eleventyConfig.addLiquidShortcode("version", function() {
Expand Down
39 changes: 39 additions & 0 deletions docs/assets/js/controllers/clipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as Stacks from '../../../../lib/ts/stacks';

Stacks.application.register("clipboard", class extends Stacks.StacksController {
static targets = ["source"];
sourceTarget!: HTMLElement;

connect() {
super.connect();
};

copy() {
const text = this.sourceTarget.innerText;
navigator.clipboard.writeText(text);
this.handleVisible();
}

private handleVisible() {
const { scope } = this.targets;

const hideElements = scope.findAllElements('[data-hide-on-copy]');
const showElements = scope.findAllElements('[data-show-on-copy]');

hideElements.forEach(el => {
el.classList.add("d-none");
});
showElements.forEach(el => {
el.classList.remove("d-none");
});

setTimeout(function () {
hideElements.forEach(el => {
el.classList.remove("d-none");
});
showElements.forEach(el => {
el.classList.add("d-none");
});
}, 3000);
}
});
1 change: 1 addition & 0 deletions docs/assets/js/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import "../../../lib/ts/index";
import "../less/stacks-documentation.less";
import "./controllers/clipboard";
import "./controllers/docs-resizer";
import * as Stacks from "../../../lib/ts/index";

Expand Down
33 changes: 31 additions & 2 deletions docs/assets/less/stacks-documentation.less
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,20 @@
white-space: normal;
}

// ============================================================================
// $ CODE COPY BUTTON
// ----------------------------------------------------------------------------
.stacks-copy-btn {
.svg-icon,
.svg-icon * {
pointer-events: none;
}

.iconCheckmark {
color: var(--green-500);
}
dancormier marked this conversation as resolved.
Show resolved Hide resolved
}


// ============================================================================
// $ LISTS
Expand All @@ -255,11 +269,26 @@
box-shadow: none;
});

> pre.s-code-block {
.stacks-copy-btn {
right: var(--su-static8);
top: var(--su-static8);
}

> pre.s-code-block,
> .stacks-clipboard-content pre.s-code-block {
border-radius: var(--br-md) var(--br-md) 0 0;
border: 1px solid var(--bc-medium);
display: flex; // flex layout for scroll padding
max-height: 24rem;

padding-right: var(--su32);
dancormier marked this conversation as resolved.
Show resolved Hide resolved

// pseudo element to pad scrollable region to compensate for copy button
&:after {
content: "";
display: block;
height: var(--su-static1);
width: var(--su-static128);
}
.dark-mode({
border-color: var(--bc-lighter);
});
Expand Down
36 changes: 36 additions & 0 deletions docs/plugins/copy-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const { default: Icons } = require("@stackoverflow/stacks-icons");

module.exports = {
configFunction(eleventyConfig) {
eleventyConfig.addPairedShortcode("copybutton", function(content, classes, btnClasses) {
var tooltipId = "tooltip-" + Math.floor(Math.random() * 1000);

var output = `
<div class="stacks-clipboard-content ps-relative ${classes}" data-controller="clipboard">
<button
class="stacks-copy-btn s-btn s-btn__muted s-btn__icon ps-absolute p4 ${btnClasses}"
data-action="clipboard#copy"
data-s-tooltip-placement="top"
data-controller="s-tooltip"
aria-describedby="${tooltipId}">
<span class="d-none" data-show-on-copy>${Icons["Checkmark"]}</span>
<span data-hide-on-copy>${Icons["Copy"]}</span>
</button>
<div class="s-popover s-popover__tooltip"
id="${tooltipId}"
role="tooltip"
aria-hidden="true">
<div class="s-popover--arrow"></div>
<span class="d-none" data-show-on-copy>Copied</span>
<span data-hide-on-copy>Copy</span>
</div>
<div data-clipboard-target="source">
${content}
</div>
</div>
`;

return output;
});
}
}
12 changes: 11 additions & 1 deletion docs/product/components/cards.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
<p class="stacks-copy">The base card styling applies a border and padding to the card.</p>
<p class="stacks-copy">Cards can be any size and it’s ok to increase the body text size for larger cards.</p>
<div class="stacks-preview">
{% copybutton %}
{% highlight html %}
<div class="s-card">
<h2 class="fs-body3 lh-sm fc-dark">…</h2>
<p class="fs-body1 fc-medium">…</p>
<button class="s-btn s-btn__primary s-btn__sm">…</button>
</div>
{% endhighlight %}
{% endcopybutton %}
<div class="stacks-preview--example">
<div class="s-card wmx3 mb12">
<h2 class="fs-body3 lh-sm fc-dark">Base card title</h2>
Expand All @@ -41,12 +43,14 @@ <h2 class="fs-body3 lh-sm fc-dark">Base card title</h2>
{% header "h2", "Box shadows" %}
<p class="stacks-copy">Applying <a href="{{ "/product/base/box-shadow/" | url }}">a <a href="{{ "/product/base/box-shadow/" | url }}"><code class="stacks-code">.bs-*</code> class</a> adds a box shadow to a card. Useful when giving users the impression they can interact with the card.</p>
<div class="stacks-preview">
{% copybutton %}
{% highlight html %}
<div class="s-card bs-sm">…</div>
<div class="s-card bs-md">…</div>
<div class="s-card bs-lg">…</div>
{% endhighlight %}
<div class="stacks-preview--example">
{% endcopybutton %}
<div class="stacks-preview--example">
<div class="d-flex flex__allitems4 md:fd-column gs12">
<div class="flex--item s-card bs-sm">
<h2 class="fs-body3 lh-sm fc-dark">Small box shadow</h2>
Expand All @@ -70,6 +74,7 @@ <h2 class="fs-body3 lh-sm fc-dark">Large box shadow</h2>
<p class="stacks-copy">The <code class="stacks-code">.s-card</code> class can be applied to an <code class="stacks-code">&lt;a&gt;</code> tag for instances where a whole card should link somewhere. If possible, linked cards should visually indication that they’re interactive (ex. including an <code class="stacks-code">.s-btn</code> or <code class="stacks-code">.s-link</code> somewhere).</p>
<p class="stacks-copy">A <code class="stacks-code">:hover</code> style for border color is automatically added to all linked cards. For linked cards with a box shadow (<code class="stacks-code">.bs-*</code>), adding <a href="{{ "/product/base/box-shadow/" | url }}">a <code class="stacks-code">.h:bs-*</code> class</a> will apply a hover style to the box shadow as well. Increasing the <code class="stacks-code">.bs-</code> size by <strong>a factor of one</strong> is usually best.</p>
<div class="stacks-preview">
{% copybutton %}
{% highlight html %}
<a href="…" class="s-card">
<h2 class="fs-body3 lh-sm fc-dark">…</h2>
Expand All @@ -83,6 +88,7 @@ <h2 class="fs-body3 lh-sm fc-dark">…</h2>
<p class="fs-body1 s-link">…</p>
</a>
{% endhighlight %}
{% endcopybutton %}
<div class="stacks-preview--example">
<div class="d-flex flex__allitems4 fw-wrap ai-stretch md:fd-column gs12">
<a href="#" class="flex--item s-card">
Expand Down Expand Up @@ -122,12 +128,14 @@ <h2 class="fs-body3 lh-sm fc-dark">Large box shadow on :hover</h2>
{% header "h2", "Muted" %}
<p class="stacks-copy">When a card is disabled or considered completed, apply the muted modifier to visually dim the card.</p>
<div class="stacks-preview">
{% copybutton %}
{% highlight html %}
<div class="s-card s-card__muted">
<h1 class="fs-body3 fc-dark">…</h1>
<p class="fs-body1 fc-light">…</p>
</div>
{% endhighlight %}
{% endcopybutton %}
<div class="stacks-preview--example">
<div class="d-flex flex__allitems4 md:fd-column gs12">
<div class="flex--item s-card s-card__muted">
Expand All @@ -147,13 +155,15 @@ <h2 class="fs-body3 lh-sm fc-dark">Linked card title</h2>
{% header "h2", "Stacked" %}
<p class="stacks-copy">First introduced for our collections feature in Teams, cards can also be stacked to imply multiple sections or items. No need to overthink it, we can just nest our cards. Note: You’ll need to compensate for the <code class="stacks-code">4px</code> of nesting on that right edge to keep things equidistant.</p>
<div class="stacks-preview">
{% copybutton %}
{% highlight html %}
<div class="s-card p0">
<div class="s-card ps-relative b4 l4">
</div>
</div>
{% endhighlight %}
{% endcopybutton %}
<div class="stacks-preview--example">
<div class="pr4">
<div class="s-card p0">
Expand Down
10 changes: 10 additions & 0 deletions docs/product/components/checkbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<section class="stacks-section">
{% header "h2", "Base style" %}
<div class="stacks-preview">
{% copybutton %}
{% highlight html %}
<!-- Base -->
<fieldset>
Expand All @@ -28,6 +29,7 @@
</div>
</fieldset>
{% endhighlight %}
{% endcopybutton %}
<div class="stacks-preview--example">
<!-- Base -->
<fieldset>
Expand Down Expand Up @@ -87,6 +89,7 @@
{% header "h2", "Examples" %}
{% header "h3", "Vertical group" %}
<div class="stacks-preview">
{% copybutton %}
{% highlight html %}
<fieldset class="d-flex gs8 gsy fd-column">
<legend class="flex--item s-label">Which types of fruit do you like? <span class="ml4 fw-normal fc-light">(Check all that apply)</span></legend>
Expand Down Expand Up @@ -116,6 +119,7 @@
</div>
</fieldset>
{% endhighlight %}
{% endcopybutton %}
<div class="stacks-preview--example">
<fieldset class="d-flex gs8 gsy fd-column">
<legend class="flex--item s-label">Which types of fruit do you like? <span class="ml4 fw-normal fc-light">(Check all that apply)</span></legend>
Expand Down Expand Up @@ -149,6 +153,7 @@

{% header "h3", "Horizontal group" %}
<div class="stacks-preview">
{% copybutton %}
{% highlight html %}
<fieldset class="d-flex gs8 gsy fd-column">
<legend class="flex--item s-label">Which types of fruit do you like? <span class="ml4 fw-normal fc-light">(Check all that apply)</span></legend>
Expand Down Expand Up @@ -182,6 +187,7 @@
</div>
</fieldset>
{% endhighlight %}
{% endcopybutton %}
<div class="stacks-preview--example">
<fieldset class="d-flex gs8 gsy fd-column">
<legend class="flex--item s-label">Which types of fruit do you like? <span class="ml4 fw-normal fc-light">(Check all that apply)</span></legend>
Expand Down Expand Up @@ -219,6 +225,7 @@

{% header "h3", "With description copy" %}
<div class="stacks-preview">
{% copybutton %}
{% highlight html %}
<fieldset class="d-flex gs8 gsy fd-column">
<legend class="flex--item s-label">Which types of fruit do you like? <span class="ml4 fw-normal fc-light">(Check all that apply)</span></legend>
Expand Down Expand Up @@ -263,6 +270,7 @@
</div>
</fieldset>
{% endhighlight %}
{% endcopybutton %}
<div class="stacks-preview--example">
<fieldset class="d-flex gs8 gsy fd-column">
<legend class="flex--item s-label">Which types of fruit do you like? <span class="ml4 fw-normal fc-light">(Check all that apply)</span></legend>
Expand Down Expand Up @@ -341,6 +349,7 @@

{% header "h3", "Validation examples" %}
<div class="stacks-preview">
{% copybutton %}
{% highlight html %}
<fieldset class="d-flex gs8 gsy fd-column">
<legend class="flex--item s-label">Which types of fruit do you like? <span class="ml4 fw-normal fc-light">(Check all that apply)</span></legend>
Expand Down Expand Up @@ -385,6 +394,7 @@
</div>
</fieldset>
{% endhighlight %}
{% endcopybutton %}
<div class="stacks-preview--example">
<fieldset class="d-flex gs8 gsy fd-column">
<legend class="flex--item s-label">Which types of fruit do you like? <span class="ml4 fw-normal fc-light">(Check all that apply)</span></legend>
Expand Down