From f0421bafb870e72c7c34d45859387b0dd2a02161 Mon Sep 17 00:00:00 2001 From: Bartosz Sokorski Date: Thu, 2 Jun 2022 03:00:27 +0200 Subject: [PATCH 1/2] Add "Copy to clipboard" button --- .gitignore | 1 + package-lock.json | 47 +++++++++++++++++++ package.json | 1 + rollup.config.js | 7 +++ src/app.js | 2 + src/css/_clipboard.css | 37 +++++++++++++++ src/css/app.css | 11 +++-- src/js/controllers/clipboard_controller.js | 28 +++++++++++ static/images/checkmark.svg | 18 +++++++ static/images/content_copy.svg | 18 +++++++ themes/poetry/layouts/docs/single.html | 3 +- .../poetry/layouts/shortcodes/clipboard.html | 3 ++ 12 files changed, 169 insertions(+), 7 deletions(-) create mode 100644 src/css/_clipboard.css create mode 100644 src/js/controllers/clipboard_controller.js create mode 100644 static/images/checkmark.svg create mode 100644 static/images/content_copy.svg create mode 100644 themes/poetry/layouts/shortcodes/clipboard.html diff --git a/.gitignore b/.gitignore index 1954e36..b1352b4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ assets/assets /resources .python-version .vscode +.idea .vercel .env diff --git a/package-lock.json b/package-lock.json index 9e02915..213bf0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,7 @@ "prettier-plugin-go-template": "^0.0.13", "rollup": "^2.50.2", "rollup-plugin-postcss": "^4.0.0", + "rollup-plugin-svg-import": "^1.6.0", "rollup-plugin-terser": "^7.0.2", "stimulus-use": "^0.50.0", "tailwindcss": "^3.0.11" @@ -9146,6 +9147,31 @@ "node": ">=8" } }, + "node_modules/rollup-plugin-svg-import": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-svg-import/-/rollup-plugin-svg-import-1.6.0.tgz", + "integrity": "sha512-WYFJ4DMSiC3TTUwTjrTklmXjwWp6GWLIWf7fbmR1pER/7c6vWNjx3WjsQrbOE3+9HmUWW3hWIgH2vrItWfdG1g==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^4.1.1" + }, + "peerDependencies": { + "rollup": ">=1.29.0 <3.0.0" + } + }, + "node_modules/rollup-plugin-svg-import/node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/rollup-plugin-terser": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", @@ -17152,6 +17178,27 @@ } } }, + "rollup-plugin-svg-import": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-svg-import/-/rollup-plugin-svg-import-1.6.0.tgz", + "integrity": "sha512-WYFJ4DMSiC3TTUwTjrTklmXjwWp6GWLIWf7fbmR1pER/7c6vWNjx3WjsQrbOE3+9HmUWW3hWIgH2vrItWfdG1g==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^4.1.1" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "requires": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + } + } + } + }, "rollup-plugin-terser": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", diff --git a/package.json b/package.json index b962c37..01e10b7 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@rollup/plugin-eslint": "^8.0.1", "@rollup/plugin-node-resolve": "^13.0.0", "@rollup/plugin-replace": "^4.0.0", + "rollup-plugin-svg-import": "^1.6.0", "algoliasearch": "^4.9.1", "atomic-algolia": "^0.3.19", "autoprefixer": "^10.2.5", diff --git a/rollup.config.js b/rollup.config.js index 32d2ec7..ca4f31f 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -5,6 +5,7 @@ import eslint from "@rollup/plugin-eslint" import { terser } from "rollup-plugin-terser" import postcss from "rollup-plugin-postcss" import replace from "@rollup/plugin-replace" +import svg from "rollup-plugin-svg-import" import path from "path" @@ -38,6 +39,9 @@ const dev = { configFile: path.resolve(__dirname, "babel.config.json"), babelHelpers: "bundled", }), + svg({ + stringify: true, + }), ], } @@ -72,6 +76,9 @@ const prod = { babelHelpers: "bundled", }), terser(), + svg({ + stringify: true, + }), ], } diff --git a/src/app.js b/src/app.js index b8090c9..5378a07 100644 --- a/src/app.js +++ b/src/app.js @@ -9,8 +9,10 @@ import SelectController from "./js/controllers/select_controller" import ModeSwitchController from "./js/controllers/mode_switch_controller" import FlyoverController from "./js/controllers/flyover_controller" import TabsController from "./js/controllers/tabs_controller" +import ClipboardController from "./js/controllers/clipboard_controller" const application = Application.start() +application.register("clipboard", ClipboardController) application.register("transition", TransitionController) application.register("click-outside", ClickOutsideController) application.register("menu", MenuController) diff --git a/src/css/_clipboard.css b/src/css/_clipboard.css new file mode 100644 index 0000000..33bf451 --- /dev/null +++ b/src/css/_clipboard.css @@ -0,0 +1,37 @@ +.clipboard-button { + position: absolute; + right: 0; + padding: 2px 7px 5px 7px; + margin: 5px; + color: rgb(14 165 233 / var(--tw-border-opacity)); + --tw-border-opacity: 0.4; + background-color: rgb(186 230 253 / var(--tw-bg-opacity)); + --tw-bg-opacity: 0.1; + border: 1px solid rgb(14 165 233 / var(--tw-border-opacity)); + border-radius: 6px; + font-size: 0.8em; + z-index: 10; + opacity: 0.5; + transition: 0.1s; +} +.clipboard-button > svg { + fill: rgb(208 212 252 / var(--tw-text-opacity)); +} +.clipboard-button:hover { + cursor: pointer; + border-color: #696969; + background-color: #e0e0e0; +} +.clipboard-button:hover > svg { + fill: #696969; +} +.clipboard-button:focus { + outline: 0; +} +.highlight { + position: relative; +} +.highlight:hover > .clipboard-button { + opacity: 1; + transition: 0.2s; +} diff --git a/src/css/app.css b/src/css/app.css index 749cfc6..463fca5 100644 --- a/src/css/app.css +++ b/src/css/app.css @@ -1,11 +1,12 @@ @import "tailwindcss/base"; @import "tailwindcss/components"; @import "tailwindcss/utilities"; -@import "./_fonts"; -@import "./_base"; -@import "./_components"; -@import "./_content"; +@import "./_fonts.css"; +@import "./_base.css"; +@import "./_components.css"; +@import "./_content.css"; @import "./_docs.css"; @import "./_windows.css"; -@import "./_highlight"; +@import "./_highlight.css"; @import "./_search.css"; +@import "./_clipboard.css"; diff --git a/src/js/controllers/clipboard_controller.js b/src/js/controllers/clipboard_controller.js new file mode 100644 index 0000000..8328cbc --- /dev/null +++ b/src/js/controllers/clipboard_controller.js @@ -0,0 +1,28 @@ +import checkmark from "../../../static/images/checkmark.svg" +import copyIcon from "../../../static/images/content_copy.svg" +import { Controller } from "stimulus" + +export default class extends Controller { + initialize() { + document + .querySelectorAll("div.clipboard > div.highlight > pre") + .forEach((codeBlock) => { + const button = document.createElement("button") + button.className = "clipboard-button" + button.type = "button" + button.title = "Copy to clipboard" + button.innerHTML = copyIcon + button.addEventListener("click", () => { + navigator.clipboard.writeText(codeBlock.innerText).then( + () => { + button.blur() + button.innerHTML = checkmark + setTimeout(() => (button.innerHTML = copyIcon), 2000) + }, + () => (button.innerHTML = "Error") + ) + }) + codeBlock.parentNode.insertBefore(button, codeBlock) + }) + } +} diff --git a/static/images/checkmark.svg b/static/images/checkmark.svg new file mode 100644 index 0000000..85448bd --- /dev/null +++ b/static/images/checkmark.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/static/images/content_copy.svg b/static/images/content_copy.svg new file mode 100644 index 0000000..06450f7 --- /dev/null +++ b/static/images/content_copy.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/themes/poetry/layouts/docs/single.html b/themes/poetry/layouts/docs/single.html index 81f4bb3..b90b683 100644 --- a/themes/poetry/layouts/docs/single.html +++ b/themes/poetry/layouts/docs/single.html @@ -117,8 +117,6 @@ class="bg-secondary-400 flex-shrink-0 inline-block h-2 w-2 mr-2 rounded-full dark:bg-indigo-300" > {{ end }} - - {{ index (split .Name "|") 0 -}} @@ -134,6 +132,7 @@

{{ index (split .Name "|") 0 -}}

{{ .TableOfContents }} diff --git a/themes/poetry/layouts/shortcodes/clipboard.html b/themes/poetry/layouts/shortcodes/clipboard.html new file mode 100644 index 0000000..ea4bfc5 --- /dev/null +++ b/themes/poetry/layouts/shortcodes/clipboard.html @@ -0,0 +1,3 @@ +
+ {{ printf "%s" .Inner | markdownify }} +
From 1a336cc26b43f53af358b72d8d16de1d14c2469d Mon Sep 17 00:00:00 2001 From: Branch Vincent Date: Thu, 8 Sep 2022 08:20:11 -0400 Subject: [PATCH 2/2] fix: update import, use official image plugin --- package-lock.json | 89 ++++++++++------------ package.json | 2 +- rollup.config.js | 10 +-- src/js/controllers/clipboard_controller.js | 8 +- 4 files changed, 52 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index 213bf0d..5db5772 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "@rollup/plugin-babel": "^5.3.0", "@rollup/plugin-commonjs": "^22.0.0", "@rollup/plugin-eslint": "^8.0.1", + "@rollup/plugin-image": "^2.1.1", "@rollup/plugin-node-resolve": "^13.0.0", "@rollup/plugin-replace": "^4.0.0", "algoliasearch": "^4.9.1", @@ -35,7 +36,6 @@ "prettier-plugin-go-template": "^0.0.13", "rollup": "^2.50.2", "rollup-plugin-postcss": "^4.0.0", - "rollup-plugin-svg-import": "^1.6.0", "rollup-plugin-terser": "^7.0.2", "stimulus-use": "^0.50.0", "tailwindcss": "^3.0.11" @@ -2549,6 +2549,22 @@ "node": ">=8" } }, + "node_modules/@rollup/plugin-image": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-image/-/plugin-image-2.1.1.tgz", + "integrity": "sha512-AgP4U85zuQJdUopLUCM+hTf45RepgXeTb8EJsleExVy99dIoYpt3ZlDYJdKmAc2KLkNntCDg6BPJvgJU3uGF+g==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "mini-svg-data-uri": "^1.2.3" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, "node_modules/@rollup/plugin-node-resolve": { "version": "13.3.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", @@ -7163,6 +7179,15 @@ "dom-walk": "^0.1.0" } }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true, + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -9147,31 +9172,6 @@ "node": ">=8" } }, - "node_modules/rollup-plugin-svg-import": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-svg-import/-/rollup-plugin-svg-import-1.6.0.tgz", - "integrity": "sha512-WYFJ4DMSiC3TTUwTjrTklmXjwWp6GWLIWf7fbmR1pER/7c6vWNjx3WjsQrbOE3+9HmUWW3hWIgH2vrItWfdG1g==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^4.1.1" - }, - "peerDependencies": { - "rollup": ">=1.29.0 <3.0.0" - } - }, - "node_modules/rollup-plugin-svg-import/node_modules/@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", - "dev": true, - "dependencies": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - } - }, "node_modules/rollup-plugin-terser": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", @@ -12399,6 +12399,16 @@ } } }, + "@rollup/plugin-image": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-image/-/plugin-image-2.1.1.tgz", + "integrity": "sha512-AgP4U85zuQJdUopLUCM+hTf45RepgXeTb8EJsleExVy99dIoYpt3ZlDYJdKmAc2KLkNntCDg6BPJvgJU3uGF+g==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "mini-svg-data-uri": "^1.2.3" + } + }, "@rollup/plugin-node-resolve": { "version": "13.3.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", @@ -15826,6 +15836,12 @@ "dom-walk": "^0.1.0" } }, + "mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -17178,27 +17194,6 @@ } } }, - "rollup-plugin-svg-import": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-svg-import/-/rollup-plugin-svg-import-1.6.0.tgz", - "integrity": "sha512-WYFJ4DMSiC3TTUwTjrTklmXjwWp6GWLIWf7fbmR1pER/7c6vWNjx3WjsQrbOE3+9HmUWW3hWIgH2vrItWfdG1g==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^4.1.1" - }, - "dependencies": { - "@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", - "dev": true, - "requires": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - } - } - } - }, "rollup-plugin-terser": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", diff --git a/package.json b/package.json index 01e10b7..507413a 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,9 @@ "@rollup/plugin-babel": "^5.3.0", "@rollup/plugin-commonjs": "^22.0.0", "@rollup/plugin-eslint": "^8.0.1", + "@rollup/plugin-image": "^2.1.1", "@rollup/plugin-node-resolve": "^13.0.0", "@rollup/plugin-replace": "^4.0.0", - "rollup-plugin-svg-import": "^1.6.0", "algoliasearch": "^4.9.1", "atomic-algolia": "^0.3.19", "autoprefixer": "^10.2.5", diff --git a/rollup.config.js b/rollup.config.js index ca4f31f..e3847aa 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -5,7 +5,7 @@ import eslint from "@rollup/plugin-eslint" import { terser } from "rollup-plugin-terser" import postcss from "rollup-plugin-postcss" import replace from "@rollup/plugin-replace" -import svg from "rollup-plugin-svg-import" +import image from "@rollup/plugin-image" import path from "path" @@ -39,8 +39,8 @@ const dev = { configFile: path.resolve(__dirname, "babel.config.json"), babelHelpers: "bundled", }), - svg({ - stringify: true, + image({ + dom: true, }), ], } @@ -76,8 +76,8 @@ const prod = { babelHelpers: "bundled", }), terser(), - svg({ - stringify: true, + image({ + dom: true, }), ], } diff --git a/src/js/controllers/clipboard_controller.js b/src/js/controllers/clipboard_controller.js index 8328cbc..1586971 100644 --- a/src/js/controllers/clipboard_controller.js +++ b/src/js/controllers/clipboard_controller.js @@ -1,6 +1,6 @@ import checkmark from "../../../static/images/checkmark.svg" import copyIcon from "../../../static/images/content_copy.svg" -import { Controller } from "stimulus" +import { Controller } from "@hotwired/stimulus" export default class extends Controller { initialize() { @@ -11,13 +11,13 @@ export default class extends Controller { button.className = "clipboard-button" button.type = "button" button.title = "Copy to clipboard" - button.innerHTML = copyIcon + button.appendChild(copyIcon) button.addEventListener("click", () => { navigator.clipboard.writeText(codeBlock.innerText).then( () => { button.blur() - button.innerHTML = checkmark - setTimeout(() => (button.innerHTML = copyIcon), 2000) + button.replaceChild(checkmark, copyIcon) + setTimeout(() => button.replaceChild(copyIcon, checkmark), 2000) }, () => (button.innerHTML = "Error") )