Add code snippet component (#7294)

* Add umbCodeSnippet component

* Add aria-hidden to font icons

* Replace copy button with umb-code-snippet component

* Adjust styling of code snippet

* Adjust language of code snippet

* Update docs for component

* Adjust padding in code header

* Add code snippet content wrapper

* Fix typo

* Rename id value

* Fix typo in docs

* Update color of code blocks

* Use variables for colors

* round border + size for copy button

Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
This commit is contained in:
Bjarne Fyrstenborg
2020-01-08 14:20:43 +01:00
committed by Niels Lyngsø
parent 258dc8d2ac
commit d51b5e7822
8 changed files with 216 additions and 42 deletions

View File

@@ -9,14 +9,13 @@ pre.code {
padding: 0 3px 2px;
#font > #family > .monospace;
font-size: @baseFontSize - 2;
color: @grayDark;
color: @blueExtraDark;
.border-radius(3px);
}
// Inline code
code {
padding: 2px 4px;
color: #d14;
background-color: #f7f7f9;
border: 1px solid #e1e1e8;
white-space: nowrap;

View File

@@ -0,0 +1,119 @@
/**
@ngdoc directive
@name umbraco.directives.directive:umbCodeSnippet
@restrict E
@scope
@description
<h3>Markup example</h3>
<pre>
<div ng-controller="My.Controller as vm">
<umb-code-snippet
language="'csharp'">
{{code}}
</umb-code-snippet>
</div>
</pre>
<h3>Controller example</h3>
<pre>
(function () {
"use strict";
function Controller() {
var vm = this;
}
angular.module("umbraco").controller("My.Controller", Controller);
})();
</pre>
@param {string=} language Language of the code snippet, e.g csharp, html, css.
**/
(function () {
'use strict';
var umbCodeSnippet = {
templateUrl: 'views/components/umb-code-snippet.html',
controller: UmbCodeSnippetController,
controllerAs: 'vm',
transclude: true,
bindings: {
language: '<'
}
};
function UmbCodeSnippetController($timeout) {
const vm = this;
vm.page = {};
vm.$onInit = onInit;
vm.copySuccess = copySuccess;
vm.copyError = copyError;
function onInit() {
vm.guid = String.CreateGuid();
if (vm.language)
{
switch (vm.language.toLowerCase()) {
case "csharp":
case "c#":
vm.language = "C#";
break;
case "html":
vm.language = "HTML";
break;
case "css":
vm.language = "CSS";
break;
case "javascript":
vm.language = "JavaScript";
break;
}
}
}
// copy to clip board success
function copySuccess() {
if (vm.page.copyCodeButtonState !== "success") {
$timeout(function () {
vm.page.copyCodeButtonState = "success";
});
$timeout(function () {
resetClipboardButtonState();
}, 1000);
}
}
// copy to clip board error
function copyError() {
if (vm.page.copyCodeButtonState !== "error") {
$timeout(function () {
vm.page.copyCodeButtonState = "error";
});
$timeout(function () {
resetClipboardButtonState();
}, 1000);
}
}
function resetClipboardButtonState() {
vm.page.copyCodeButtonState = "init";
}
}
angular.module('umbraco.directives').component('umbCodeSnippet', umbCodeSnippet);
})();

View File

@@ -141,6 +141,7 @@
@import "components/umb-empty-state.less";
@import "components/umb-property-editor.less";
@import "components/umb-property-actions.less";
@import "components/umb-code-snippet.less";
@import "components/umb-color-swatches.less";
@import "components/check-circle.less";
@import "components/umb-file-icon.less";

View File

@@ -0,0 +1,43 @@
.umb-code-snippet {
.umb-code-snippet__header {
box-sizing: content-box;
background-color: @gray-10;
display: flex;
flex-direction: row;
font-size: .8rem;
border: 1px solid @gray-8;
border-radius: 3px 3px 0 0;
border-bottom: 0;
margin-top: 16px;
min-height: 30px;
.language {
display: flex;
align-items: center;
justify-content: flex-start;
flex-grow: 1;
padding: 2px 10px;
}
button {
background-color: transparent;
border: none;
border-left: 1px solid @gray-8;
border-radius: 0;
color: #000;
&:hover {
background-color: @grayLighter;
}
}
}
.umb-code-snippet__content {
pre {
border-radius: 0 0 3px 3px;
overflow: auto;
white-space: nowrap;
}
}
}

View File

@@ -185,40 +185,38 @@ iframe, .content-column-body {
// Inline code
// 1: Revert border radius to match look and feel of 7.4+
code{
.border-radius(@baseBorderRadius); // 1
code {
.border-radius(@baseBorderRadius); // 1
}
// Blocks of code
// 1: Wrapping code is unreadable on small devices.
pre {
display: block;
padding: (@baseLineHeight - 1) / 2;
margin: 0 0 @baseLineHeight / 2;
font-family: @sansFontFamily;
//font-size: @baseFontSize - 1; // 14px to 13px
color: @gray-2;
line-height: @baseLineHeight;
white-space: pre-wrap; // 1
overflow-x: auto; // 1
background-color: @gray-10;
border: 1px solid @gray-8;
.border-radius(@baseBorderRadius);
display: block;
padding: (@baseLineHeight - 1) / 2;
margin: 0 0 @baseLineHeight / 2;
font-family: @sansFontFamily;
color: @gray-2;
line-height: @baseLineHeight;
white-space: pre-wrap; // 1
overflow-x: auto; // 1
background-color: @brownGrayLight;
border: 1px solid @gray-8;
.border-radius(@baseBorderRadius);
// Make prettyprint styles more spaced out for readability
&.prettyprint {
margin-bottom: @baseLineHeight;
}
// Make prettyprint styles more spaced out for readability
&.prettyprint {
margin-bottom: @baseLineHeight;
}
// Account for some code outputs that place code tags in pre tags
code {
padding: 0;
white-space: pre; // 1
word-wrap: normal; // 1
background-color: transparent;
border: 0;
}
// Account for some code outputs that place code tags in pre tags
code {
padding: 0;
white-space: pre; // 1
word-wrap: normal; // 1
background-color: transparent;
border: 0;
}
}
/* Styling for content/media sort order dialog */

View File

@@ -31,7 +31,6 @@
vm.datePickerChange = datePickerChange;
vm.submit = submit;
vm.close = close;
vm.copyQuery = copyQuery;
function onInit() {
@@ -121,11 +120,6 @@
query.filters.push({});
}
function copyQuery() {
var copyText = $scope.model.result.queryExpression;
navigator.clipboard.writeText(copyText);
}
function trashFilter(query, filter) {
for (var i = 0; i < query.filters.length; i++) {
if (query.filters[i] == filter) {

View File

@@ -113,11 +113,11 @@
</span>
<a href ng-click="vm.addFilter(vm.query)">
<i class="icon-add"></i>
<i class="icon-add" aria-hidden="true"></i>
</a>
<a href ng-click="vm.trashFilter(vm.query, filter)">
<i class="icon-trash"></i>
<i class="icon-trash" aria-hidden="true"></i>
</a>
</div>
@@ -159,14 +159,11 @@
<ul class="nav unstyled">
<li ng-repeat="item in model.result.sampleResults">
<i class="icon icon-document turquoise-d1"></i> {{item.name}}
<i class="icon icon-document turquoise-d1" aria-hidden="true"></i> {{item.name}}
</li>
</ul>
<pre>{{model.result.queryExpression}}</pre>
<a href ng-click="vm.copyQuery()">
<i class="icon-document"></i> <localize key="template_copyToClipboard">copy to clipboard</localize>
</a>
<umb-code-snippet language="'csharp'">{{model.result.queryExpression}}</umb-code-snippet>
</div>

View File

@@ -0,0 +1,23 @@
<div class="umb-code-snippet">
<div class="umb-code-snippet__header">
<span class="language" ng-if="vm.language">{{vm.language}}</span>
<umb-button umb-clipboard
umb-clipboard-success="vm.copySuccess()"
umb-clipboard-error="vm.copyError()"
umb-clipboard-target="#umbCodeSnippet_{{vm.guid}}"
state="vm.page.copyCodeButtonState"
icon="icon-documents"
type="button"
size="s"
label="Copy"
label-key="general_copy">
</umb-button>
</div>
<div class="umb-code-snippet__content">
<pre id="umbCodeSnippet_{{vm.guid}}">
<code ng-transclude></code>
</pre>
</div>
</div>