Add color picker component (#8812)
This commit is contained in:
committed by
GitHub
parent
4ecbb7abe6
commit
5911243908
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
@ngdoc directive
|
||||
@name umbraco.directives.directive:umbColorPicker
|
||||
@restrict E
|
||||
@scope
|
||||
|
||||
@description
|
||||
<strong>Added in Umbraco v. 8.8:</strong> Use this directive to render a color picker.
|
||||
|
||||
<h3>Markup example</h3>
|
||||
<pre>
|
||||
<div ng-controller="My.ColorController as vm">
|
||||
|
||||
<umb-color-picker
|
||||
options="vm.options"
|
||||
on-show="vm.show(color)"
|
||||
on-hide="vm.hide(color)"
|
||||
on-change="vm.change(color)">
|
||||
</umb-color-picker>
|
||||
|
||||
</div>
|
||||
</pre>
|
||||
|
||||
<h3>Controller example</h3>
|
||||
<pre>
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function Controller() {
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.options = {
|
||||
type: "color",
|
||||
color: defaultColor,
|
||||
showAlpha: false,
|
||||
showPalette: true,
|
||||
showPaletteOnly: false,
|
||||
preferredFormat: "hex",
|
||||
};
|
||||
|
||||
vm.show = show;
|
||||
vm.hide = hide;
|
||||
vm.change = change;
|
||||
|
||||
function show(color) {
|
||||
color.toHexString().trimStart("#");
|
||||
}
|
||||
|
||||
function hide(color) {
|
||||
color.toHexString().trimStart("#");
|
||||
}
|
||||
|
||||
function change(color) {
|
||||
color.toHexString().trimStart("#");
|
||||
}
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("My.ColorController", Controller);
|
||||
|
||||
})();
|
||||
</pre>
|
||||
|
||||
@param {string} ngModel (<code>binding</code>): Value for the color picker.
|
||||
@param {object} options (<code>binding</code>): Config object for the color picker.
|
||||
@param {function} onBeforeShow (<code>expression</code>): Callback function before color picker is shown.
|
||||
@param {function} onChange (<code>expression</code>): Callback function when the color is changed.
|
||||
@param {function} onShow (<code>expression</code>): Callback function when color picker is shown.
|
||||
@param {function} onHide (<code>expression</code>): Callback function when color picker is hidden.
|
||||
@param {function} onMove (<code>expression</code>): Callback function when the color is moved in color picker.
|
||||
|
||||
**/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function ColorPickerController($scope, $element, $timeout, assetsService, localizationService) {
|
||||
|
||||
const ctrl = this;
|
||||
|
||||
let colorPickerInstance = null;
|
||||
let labels = {};
|
||||
|
||||
ctrl.$onInit = function() {
|
||||
|
||||
// load the separate css for the editor to avoid it blocking our js loading
|
||||
assetsService.loadCss("lib/spectrum/spectrum.css", $scope);
|
||||
|
||||
// load the js file for the color picker
|
||||
assetsService.load([
|
||||
//"lib/spectrum/tinycolor.js",
|
||||
"lib/spectrum/spectrum.js"
|
||||
], $scope).then(function () {
|
||||
|
||||
// init color picker
|
||||
grabElementAndRun();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function grabElementAndRun() {
|
||||
|
||||
var labelKeys = [
|
||||
"general_cancel",
|
||||
"general_choose",
|
||||
"general_clear"
|
||||
];
|
||||
|
||||
localizationService.localizeMany(labelKeys).then(values => {
|
||||
labels.cancel = values[0];
|
||||
labels.choose = values[1];
|
||||
labels.clear = values[2];
|
||||
});
|
||||
|
||||
$timeout(function () {
|
||||
const element = $element.find('.umb-color-picker > input')[0];
|
||||
setColorPicker(element, labels);
|
||||
}, 0, true);
|
||||
|
||||
}
|
||||
|
||||
function setColorPicker(element, labels) {
|
||||
|
||||
// Spectrum options: https://seballot.github.io/spectrum/#options
|
||||
|
||||
const defaultOptions = {
|
||||
type: "color",
|
||||
color: null,
|
||||
showAlpha: false,
|
||||
showInitial: false,
|
||||
showInput: true,
|
||||
cancelText: labels.cancel,
|
||||
clearText: labels.clear,
|
||||
chooseText: labels.choose,
|
||||
preferredFormat: "hex",
|
||||
clickoutFiresChange: true
|
||||
};
|
||||
|
||||
// If has ngModel set the color
|
||||
if (ctrl.ngModel) {
|
||||
defaultOptions.color = ctrl.ngModel;
|
||||
}
|
||||
|
||||
//const options = ctrl.options ? ctrl.options : defaultOptions;
|
||||
const options = Utilities.extend(defaultOptions, ctrl.options);
|
||||
|
||||
var elem = angular.element(element);
|
||||
|
||||
// Create new color pickr instance
|
||||
const colorPicker = elem.spectrum(options);
|
||||
|
||||
colorPickerInstance = colorPicker;
|
||||
|
||||
if (colorPickerInstance) {
|
||||
// destroy the color picker instance when the dom element is removed
|
||||
elem.on('$destroy', function () {
|
||||
colorPickerInstance.spectrum('destroy');
|
||||
});
|
||||
}
|
||||
|
||||
setUpCallbacks();
|
||||
|
||||
// Refresh the scope
|
||||
$scope.$applyAsync();
|
||||
}
|
||||
|
||||
// Spectrum events: https://seballot.github.io/spectrum/#events
|
||||
|
||||
function setUpCallbacks() {
|
||||
|
||||
if (colorPickerInstance) {
|
||||
|
||||
// bind hook for beforeShow
|
||||
if (ctrl.onBeforeShow) {
|
||||
colorPickerInstance.on('beforeShow.spectrum', (e, tinycolor) => {
|
||||
$timeout(function () {
|
||||
ctrl.onBeforeShow({ color: tinycolor });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// bind hook for show
|
||||
if (ctrl.onShow) {
|
||||
colorPickerInstance.on('show.spectrum', (e, tinycolor) => {
|
||||
$timeout(function () {
|
||||
ctrl.onShow({ color: tinycolor });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// bind hook for hide
|
||||
if (ctrl.onHide) {
|
||||
colorPickerInstance.on('hide.spectrum', (e, tinycolor) => {
|
||||
$timeout(function () {
|
||||
ctrl.onHide({ color: tinycolor });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// bind hook for change
|
||||
if (ctrl.onChange) {
|
||||
colorPickerInstance.on('change.spectrum', (e, tinycolor) => {
|
||||
$timeout(function () {
|
||||
ctrl.onChange({ color: tinycolor });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// bind hook for move
|
||||
if (ctrl.onMove) {
|
||||
colorPickerInstance.on('move.spectrum', (e, tinycolor) => {
|
||||
$timeout(function () {
|
||||
ctrl.onMove({ color: tinycolor });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
angular
|
||||
.module('umbraco.directives')
|
||||
.component('umbColorPicker', {
|
||||
template: '<div class="umb-color-picker"><input type="hidden" /></div>',
|
||||
controller: ColorPickerController,
|
||||
bindings: {
|
||||
ngModel: '<',
|
||||
options: '<',
|
||||
onBeforeShow: '&',
|
||||
onShow: '&',
|
||||
onHide: '&',
|
||||
onChange: '&',
|
||||
onMove: '&'
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -46,7 +46,7 @@ For extra details about options and events take a look here: https://refreshless
|
||||
</pre>
|
||||
|
||||
@param {object} ngModel (<code>binding</code>): Value for the slider.
|
||||
@param {object} options (<code>binding</code>): Config object for the date picker.
|
||||
@param {object} options (<code>binding</code>): Config object for the slider.
|
||||
@param {callback} onSetup (<code>callback</code>): onSetup gets triggered when the slider is initialized
|
||||
@param {callback} onUpdate (<code>callback</code>): onUpdate fires every time the slider values are changed.
|
||||
@param {callback} onSlide (<code>callback</code>): onSlide gets triggered when the handle is being dragged.
|
||||
|
||||
@@ -98,9 +98,9 @@
|
||||
})();
|
||||
</pre>
|
||||
|
||||
@param {string} icon (<code>binding</code>): The node icon.
|
||||
@param {string} name (<code>binding</code>): The node name.
|
||||
@param {string} published (<code>binding</code>): The node published state.
|
||||
@param {array} items (<code>binding</code>): The items for the table.
|
||||
@param {array} itemProperties (<code>binding</code>): The properties for the items to use in table.
|
||||
@param {boolean} allowSelectAll (<code>binding</code>): Specify whether to allow select all.
|
||||
@param {function} onSelect (<code>expression</code>): Callback function when the row is selected.
|
||||
@param {function} onClick (<code>expression</code>): Callback function when the "Name" column link is clicked.
|
||||
@param {function} onSelectAll (<code>expression</code>): Callback function when selecting all items.
|
||||
|
||||
@@ -143,6 +143,7 @@
|
||||
@import "components/umb-property-editor.less";
|
||||
@import "components/umb-property-actions.less";
|
||||
@import "components/umb-code-snippet.less";
|
||||
@import "components/umb-color-picker.less";
|
||||
@import "components/umb-color-swatches.less";
|
||||
@import "components/check-circle.less";
|
||||
@import "components/umb-file-icon.less";
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
.umb-color-picker {
|
||||
|
||||
.sp-replacer {
|
||||
display: inline-flex;
|
||||
margin-right: 18px;
|
||||
height: 32px;
|
||||
|
||||
&.sp-light {
|
||||
background-color: @white;
|
||||
}
|
||||
|
||||
.sp-preview {
|
||||
margin: 5px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.sp-dd {
|
||||
line-height: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,21 +160,6 @@
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.sp-replacer {
|
||||
display: inline-flex;
|
||||
margin-right: 18px;
|
||||
height: auto;
|
||||
|
||||
.sp-preview {
|
||||
margin: 5px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.sp-dd {
|
||||
line-height: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
border: 1px solid @white;
|
||||
padding: 6px 10px;
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
<div class="umb-property-editor umb-prevalues-multivalues" ng-controller="Umbraco.PrevalueEditors.MultiColorPickerController">
|
||||
<div class="umb-property-editor umb-prevalues-multivalues" ng-controller="Umbraco.PrevalueEditors.MultiColorPickerController as vm">
|
||||
<div class="control-group umb-prevalues-multivalues__add color-picker-preval">
|
||||
<div class="umb-prevalues-multivalues__left">
|
||||
<input name="newColor" type="hidden" />
|
||||
<label for="newColor" val-highlight="{{hasError}}">#{{newColor}}</label>
|
||||
<input name="newLabel" type="text" ng-model="newLabel" focus-when="{{focusOnNew}}" class="umb-property-editor color-label" placeholder="Label" ng-show="labelEnabled" />
|
||||
|
||||
<umb-color-picker
|
||||
ng-model="newColor"
|
||||
options="options"
|
||||
on-hide="vm.hide(color)"
|
||||
on-show="vm.show(color)"
|
||||
on-change="vm.change(color)">
|
||||
</umb-color-picker>
|
||||
|
||||
<label val-highlight="{{hasError}}">#{{newColor}}</label>
|
||||
<input type="text" name="newLabel" ng-model="newLabel" focus-when="{{focusOnNew}}" class="umb-property-editor color-label" localize="placeholder" placeholder="@general_label" ng-show="vm.labelEnabled" />
|
||||
</div>
|
||||
<div class="umb-prevalues-multivalues__right">
|
||||
<button class="btn btn-info add" ng-click="add($event)"><localize key="general_add">Add</localize></button>
|
||||
<button type="button" class="btn btn-info add" ng-click="vm.add($event)"><localize key="general_add">Add</localize></button>
|
||||
</div>
|
||||
</div>
|
||||
<div ui-sortable="sortableOptions" ng-model="model.value">
|
||||
@@ -21,7 +29,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="umb-prevalues-multivalues__right">
|
||||
<button type="button" class="umb-node-preview__action umb-node-preview__action--red" ng-click="remove(item, $event)"><localize key="general_remove">Remove</localize></button>
|
||||
<button type="button" class="umb-node-preview__action umb-node-preview__action--red" ng-click="vm.remove(item, $event)"><localize key="general_remove">Remove</localize></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
angular.module("umbraco").controller("Umbraco.PrevalueEditors.MultiColorPickerController",
|
||||
function ($scope, $timeout, assetsService, angularHelper, $element, localizationService, eventsService) {
|
||||
function ($scope, angularHelper, $element, eventsService) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.add = add;
|
||||
vm.remove = remove;
|
||||
|
||||
vm.show = show;
|
||||
vm.hide = hide;
|
||||
vm.change = change;
|
||||
|
||||
vm.labelEnabled = false;
|
||||
|
||||
//NOTE: We need to make each color an object, not just a string because you cannot 2-way bind to a primitive.
|
||||
var defaultColor = "000000";
|
||||
var defaultLabel = null;
|
||||
@@ -9,52 +21,33 @@
|
||||
$scope.hasError = false;
|
||||
$scope.focusOnNew = false;
|
||||
|
||||
$scope.labels = {};
|
||||
$scope.options = {
|
||||
type: "color",
|
||||
color: defaultColor,
|
||||
allowEmpty: false,
|
||||
showAlpha: false
|
||||
};
|
||||
|
||||
var labelKeys = [
|
||||
"general_cancel",
|
||||
"general_choose"
|
||||
];
|
||||
function hide(color) {
|
||||
// show the add button
|
||||
$element.find(".btn.add").show();
|
||||
}
|
||||
|
||||
$scope.labelEnabled = false;
|
||||
eventsService.on("toggleValue", function (e, args) {
|
||||
$scope.labelEnabled = args.value;
|
||||
});
|
||||
|
||||
localizationService.localizeMany(labelKeys).then(function (values) {
|
||||
$scope.labels.cancel = values[0];
|
||||
$scope.labels.choose = values[1];
|
||||
});
|
||||
function show(color) {
|
||||
// hide the add button
|
||||
$element.find(".btn.add").hide();
|
||||
}
|
||||
|
||||
assetsService.load([
|
||||
//"lib/spectrum/tinycolor.js",
|
||||
"lib/spectrum/spectrum.js"
|
||||
], $scope).then(function () {
|
||||
var elem = $element.find("input[name='newColor']");
|
||||
elem.spectrum({
|
||||
type: "color",
|
||||
color: defaultColor,
|
||||
showAlpha: false,
|
||||
showInitial: false,
|
||||
showInput: true,
|
||||
chooseText: $scope.labels.choose,
|
||||
cancelText: $scope.labels.cancel,
|
||||
preferredFormat: "hex",
|
||||
clickoutFiresChange: true,
|
||||
hide: function (color) {
|
||||
//show the add butotn
|
||||
$element.find(".btn.add").show();
|
||||
},
|
||||
change: function (color) {
|
||||
angularHelper.safeApply($scope, function () {
|
||||
$scope.newColor = color.toHexString().trimStart("#"); // #ff0000
|
||||
});
|
||||
},
|
||||
show: function() {
|
||||
//hide the add butotn
|
||||
$element.find(".btn.add").hide();
|
||||
function change(color) {
|
||||
angularHelper.safeApply($scope, function () {
|
||||
if (color) {
|
||||
$scope.newColor = color.toHexString().trimStart("#");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
eventsService.on("toggleValue", function (e, args) {
|
||||
vm.labelEnabled = args.value;
|
||||
});
|
||||
|
||||
if (!Utilities.isArray($scope.model.value)) {
|
||||
@@ -96,7 +89,7 @@
|
||||
return label !== null && typeof label !== "undefined" && label !== "" && label.length && label.length > 0;
|
||||
}
|
||||
|
||||
$scope.remove = function (item, evt) {
|
||||
function remove(item, evt) {
|
||||
|
||||
evt.preventDefault();
|
||||
|
||||
@@ -105,9 +98,9 @@
|
||||
});
|
||||
|
||||
angularHelper.getCurrentForm($scope).$setDirty();
|
||||
};
|
||||
}
|
||||
|
||||
$scope.add = function (evt) {
|
||||
function add(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
if ($scope.newColor) {
|
||||
@@ -127,11 +120,10 @@
|
||||
return;
|
||||
}
|
||||
|
||||
//there was an error, do the highlight (will be set back by the directive)
|
||||
// there was an error, do the highlight (will be set back by the directive)
|
||||
$scope.hasError = true;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
$scope.sortableOptions = {
|
||||
axis: 'y',
|
||||
@@ -145,6 +137,4 @@
|
||||
}
|
||||
};
|
||||
|
||||
//load the separate css for the editor to avoid it blocking our js loading
|
||||
assetsService.loadCss("lib/spectrum/spectrum.css", $scope);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user