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:
committed by
Niels Lyngsø
parent
258dc8d2ac
commit
d51b5e7822
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
})();
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user