UNPKG

shiki-header-with-copy

Version:

Shiki transformer adding a header with language as title and a copy button

84 lines 3.71 kB
import { h, s } from 'hastscript'; export function addHeaderWithCopy(options) { const headerClass = `shiki-header-with-copy ${options?.headerClass ?? ''}`.trim(); const langClass = `lang ${options?.langClass ?? ''}`.trim(); const copyButtonClass = `copy ${options?.copyButtonClass ?? ''}`.trim(); const copyReadyIconClass = `ready ${options?.copyReadyIconClass ?? ''}`.trim(); const copySuccessIconClass = `success ${options?.copySuccessIconClass ?? ''}`.trim(); const preClass = `shiki-pre ${options?.preClass ?? ''}`.trim(); const codeWrapperClass = `code-wrapper ${options?.codeWrapperClass ?? ''}`.trim(); const showButtonText = options?.showButtonText ?? false; return { code(node) { return h('div', { class: codeWrapperClass }, [node]); }, pre(node) { node.properties.class = node.properties.class ? `${node.properties.class} ${preClass}` : preClass; const langEl = h('span', { class: langClass }, this.options.lang); const button = h('button', { class: copyButtonClass, onclick: ` navigator.clipboard.writeText(this.parentElement.parentElement.lastElementChild.innerText); this.firstChild.style.display = 'none'; this.lastChild.style.display = ''; setTimeout(() => { this.firstChild.style.display = ''; this.lastChild.style.display = 'none'; }, 2000) `, }, [ h('span', { class: copyReadyIconClass }, [ s('svg', { xmlns: 'http://www.w3.org/2000/svg', width: '100%', height: '100%', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': '2', 'stroke-linecap': 'round', 'stroke-linejoin': 'round', 'data-svg': 'true', }, [ s('rect', { width: '14', height: '14', x: '8', y: '8', rx: '2', ry: '2', }), s('path', { d: 'M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2', }), ]), showButtonText ? h('span', {}, 'Copy') : null, ]), h('span', { class: copySuccessIconClass, style: 'display: none' }, [ s('svg', { xmlns: 'http://www.w3.org/2000/svg', width: '100%', height: '100%', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': '2', 'stroke-linecap': 'round', 'stroke-linejoin': 'round', 'data-svg': 'true', }, [ s('path', { d: 'M20 6 9 17l-5-5', }), ]), showButtonText ? h('span', {}, 'Copied') : null, ]), ]); const headerEl = h('div', { class: headerClass }, [langEl, button]); if (headerEl) { node.children.unshift(headerEl); } }, }; } //# sourceMappingURL=index.js.map