diff --git a/packages/docs/src/app/components/component-viewer/component-viewer.component.ts b/packages/docs/src/app/components/component-viewer/component-viewer.component.ts index 059a0948b..d475bb194 100644 --- a/packages/docs/src/app/components/component-viewer/component-viewer.component.ts +++ b/packages/docs/src/app/components/component-viewer/component-viewer.component.ts @@ -97,12 +97,42 @@ export class ComponentOverviewComponent implements OnDestroy { scrollToSelectedContentSection() { this.documentLost = false; this.showView(); + this.createCopyIcons(); if (this.anchorsComponent) { this.anchorsComponent.setScrollPosition(); } } + createCopyIcons() { + const codeBlocks: NodeListOf = document.querySelectorAll('.docs-markdown__pre .docs-markdown__code'); + + codeBlocks.forEach((codeBlock) => { + const copyIcon = document.createElement('i'); + copyIcon.className = 'mc mc-copy_16 docs-markdown__code-icon'; + copyIcon.addEventListener('click', this.copyCode); + codeBlock.prepend(copyIcon); + }); + } + + copyCode(event: Event) { + const codeCopyAnimationTime = 200; + const code = ( event.target).parentNode; + + const range = document.createRange(); + range.selectNodeContents(code); + const sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + document.execCommand('copy'); + sel.removeAllRanges(); + + ( event.target).classList.add('docs-markdown__code-icon_active'); + setTimeout(() => { + ( event.target).classList.remove('docs-markdown__code-icon_active'); + }, codeCopyAnimationTime); + } + showDocumentLostAlert() { this.documentLost = true; this.showView(); diff --git a/packages/docs/src/styles/_markdown.scss b/packages/docs/src/styles/_markdown.scss index 3c4a05f96..5bfdf3e46 100644 --- a/packages/docs/src/styles/_markdown.scss +++ b/packages/docs/src/styles/_markdown.scss @@ -67,6 +67,36 @@ padding-right: 16px; } } + + &__code { + white-space: pre-line; + } + + &__pre>&__code { + display: block; + position: relative; + overflow-x: auto; + padding: 12px; + } + + &__code-icon { + display: flex; + position: absolute; + top: 0; + right: 0; + z-index: 10; + padding: 6px 6px; + -webkit-transition: -webkit-transform 0.1s; + -moz-transition: -moz-transform 0.1s; + transition: transform 0.1s; + } + + &__code-icon_active { + -webkit-transform: scale(0.93); + -moz-transform: scale(0.93); + -ms-transform: scale(0.93); + transform: scale(0.93); + } } .docs-header-link { @@ -98,6 +128,12 @@ color: $text; } + .docs-markdown__pre .docs-markdown__code { + //colors from solarized and Darcula color schemes + background: if($is-dark, #2b2b2b, #fdf6e3); + color: if($is-dark, #bababa, #657b83); + } + .docs-markdown { color: $fg-default; @@ -139,6 +175,10 @@ &__th { color: $th-color; } + + &__code-icon { + color: $color; + } }