mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-07-26 00:29:45 +02:00
Add ability to copy header link (#256)
* Add ability to copy header link * Update copy button styles * Update splash border radius * Remove cursor pointer from header * Fix for different header sizes * Update animation * Update src/frontend/styles/components/page.pcss Co-authored-by: Peter Savchenko <specc.dev@gmail.com> Co-authored-by: Peter Savchenko <specc.dev@gmail.com>
This commit is contained in:
parent
51fb6655e2
commit
3e5b6a8ba0
6 changed files with 196 additions and 21 deletions
|
@ -1,3 +1,5 @@
|
|||
import copyToClipboard from '../utils/copyToClipboard';
|
||||
|
||||
/**
|
||||
* @class Page
|
||||
* @classdesc Class for page module
|
||||
|
@ -11,12 +13,33 @@ export default class Page {
|
|||
this.tableOfContent = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* CSS classes used in the codes
|
||||
*
|
||||
* @returns {Record<string, string>}
|
||||
*/
|
||||
static get CSS() {
|
||||
return {
|
||||
page: 'page',
|
||||
copyLinkBtn: 'block-header__copy-link',
|
||||
header: 'block-header--anchor',
|
||||
headerLinkCopied: 'block-header--link-copied',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by ModuleDispatcher to initialize module from DOM
|
||||
*/
|
||||
init() {
|
||||
this.codeStyler = this.createCodeStyling();
|
||||
this.tableOfContent = this.createTableOfContent();
|
||||
|
||||
/**
|
||||
* Add click event listener to capture copy link button clicks
|
||||
*/
|
||||
const page = document.querySelector(`.${Page.CSS.page}`);
|
||||
|
||||
page.addEventListener('click', this.copyAnchorLinkIfNeeded);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,4 +79,29 @@ export default class Page {
|
|||
console.error(error); // @todo send to Hawk
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if 'copy link' button was clicked and copies the link to clipboard
|
||||
*
|
||||
* @param e - click event
|
||||
*/
|
||||
copyAnchorLinkIfNeeded = async (e) => {
|
||||
const copyLinkButtonClicked = e.target.closest(`.${Page.CSS.copyLinkBtn}`);
|
||||
|
||||
if (!copyLinkButtonClicked) {
|
||||
return;
|
||||
}
|
||||
|
||||
const header = e.target.closest(`.${Page.CSS.header}`);
|
||||
const link = header.querySelector('a').href;
|
||||
|
||||
await copyToClipboard(link);
|
||||
header.classList.add(Page.CSS.headerLinkCopied);
|
||||
|
||||
header.addEventListener('mouseleave', () => {
|
||||
setTimeout(() => {
|
||||
header.classList.remove(Page.CSS.headerLinkCopied);
|
||||
}, 500);
|
||||
}, { once: true });
|
||||
}
|
||||
}
|
||||
|
|
39
src/frontend/js/utils/copyToClipboard.js
Normal file
39
src/frontend/js/utils/copyToClipboard.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
const ERROR_MESSAGE = 'Unable to copy to clipboard';
|
||||
|
||||
/**
|
||||
* Copies specified text to clipboard
|
||||
*
|
||||
* @param {string} text - text to be copied to clipboard
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export default function (text) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(text)
|
||||
.then(() => resolve())
|
||||
.catch(() => reject(new Error(ERROR_MESSAGE)));
|
||||
} else {
|
||||
const tmpElement = document.createElement('input');
|
||||
|
||||
Object.assign(tmpElement.style, {
|
||||
position: 'fixed',
|
||||
top: '0',
|
||||
left: '0',
|
||||
opacity: '0',
|
||||
});
|
||||
|
||||
tmpElement.value = text;
|
||||
document.body.appendChild(tmpElement);
|
||||
tmpElement.select();
|
||||
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
resolve();
|
||||
} catch (e) {
|
||||
reject(new Error(ERROR_MESSAGE));
|
||||
} finally {
|
||||
document.body.removeChild(tmpElement);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue