Explorar el Código

Add ColorInputView

panr hace 5 años
padre
commit
2b2a47cc84

+ 261 - 0
packages/ckeditor5-ui/src/colorinputview/colorinputview.js

@@ -0,0 +1,261 @@
+import View from '@ckeditor/ckeditor5-ui/src/view';
+import LabelView from '../label/labelview';
+import InputTextView from '@ckeditor/ckeditor5-ui/src/inputtext/inputtextview';
+import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+import DropdownButtonView from '@ckeditor/ckeditor5-ui/src/dropdown/button/dropdownbuttonview';
+import DropdownView from '@ckeditor/ckeditor5-ui/src/dropdown/dropdownview';
+import DropdownPanelView from '@ckeditor/ckeditor5-ui/src/dropdown/dropdownpanelview';
+import ColorGrid from '@ckeditor/ckeditor5-ui/src/colorgrid/colorgridview';
+import '../../theme/components/colorinputview/colorinputview.css';
+
+export default class ColorInputView extends View {
+	// options?
+	constructor( locale ) {
+		super( locale );
+
+		this.set( 'label' );
+
+		this.set( 'value' );
+
+		this.set( 'id' );
+
+		this.set( 'placeholder' );
+
+		this.set( 'isEnabled', false );
+
+		this.set( 'errorText', null );
+
+		this.set( 'ariaDescribedById' );
+
+		this.dropdownButton = null;
+
+		this.dropdownPanel = null;
+
+		this.colorPicker = this._createTextInputWithDropdown( locale );
+
+		this.label = this._createLabelView( this.id );
+
+		const bind = this.bindTemplate;
+
+		this.on( 'setColor:setValueFromPicker', ( evtData, data ) => {
+			this.value = data.value;
+			this._toggleColorPicker();
+		} );
+
+		this.setTemplate( {
+			tag: 'div',
+			attributes: {
+				class: [
+					'ck',
+					'ck-input',
+					'ck-input-color-picker',
+					'ck-labeled-view',
+					bind.if( 'hasError', 'ck-error' )
+				],
+				id: bind.to( 'id' ),
+				placeholder: bind.to( 'placeholder' ),
+				readonly: bind.to( 'isEnabled', isEnabled => !isEnabled ),
+				'aria-invalid': bind.if( 'hasError', true ),
+				'aria-describedby': bind.to( 'ariaDescribedById' )
+			},
+			children: [
+				this.label,
+				this.colorPicker
+			],
+		} );
+	}
+
+	_createTextInputWithDropdown( locale ) {
+		const textInput = this._createInputTextView( locale );
+		const dropdown = this._createDropdownView( locale );
+		const colorInputPicker = new View();
+
+		colorInputPicker.setTemplate( {
+			tag: 'div',
+			attributes: {
+				class: [ 'ck', 'ck-dropdown__color-picker' ]
+			},
+			children: [
+				textInput,
+				dropdown,
+			]
+		} );
+
+		return colorInputPicker;
+	}
+
+	_createDropdownView( locale ) {
+		const bind = this.bindTemplate;
+		const colorGrid = this._createColorGrid();
+		const dropdownPanel = new DropdownPanelView( locale );
+		const dropdownButton = new DropdownButtonView( locale );
+		const colorPreview = new View();
+		const removeColorButton = this._createRemoveColorButton( locale );
+
+		colorPreview.setTemplate( {
+			tag: 'span',
+			attributes: {
+				class: [ 'ck', 'ck-dropdown__color-picker-preview' ],
+				style: {
+					backgroundColor: bind.to( 'value' )
+				}
+			}
+		} );
+
+		dropdownButton.extendTemplate( {
+			attributes: {
+				class: 'ck-dropdown__color-picker-button'
+			},
+		} );
+		dropdownButton.withArrow = false;
+		dropdownButton.children.add( colorPreview );
+		dropdownButton.bind( 'isEnabled' ).to( this );
+
+		const dropdown = new DropdownView( locale, dropdownButton, dropdownPanel );
+
+		dropdown.panelView.children.add( removeColorButton );
+		dropdown.panelView.children.add( colorGrid );
+		dropdown.bind( 'isEnabled' ).to( this );
+
+		this.dropdownButton = dropdownButton;
+		this.dropdownPanel = dropdownPanel;
+
+		return dropdown;
+	}
+
+	_createInputTextView( locale ) {
+		const input = new InputTextView( locale );
+
+		input.bind( 'value' ).to( this );
+		input.bind( 'isReadOnly' ).to( this, 'isEnabled', value => !value );
+		input.bind( 'placeholder' ).to( this );
+		input.bind( 'hasError' ).to( this, 'errorText', value => !!value );
+
+		input.on( 'input', ( evt, input ) => {
+			// UX: Make the error text disappear and disable the error indicator as the user
+			// starts fixing the errors.
+			this.errorText = null;
+
+			this.fire( 'setColor:setInputValue', {
+				value: input.target.value
+			} );
+		} );
+
+		return input;
+	}
+
+	_createRemoveColorButton( locale ) {
+		const bind = this.bindTemplate;
+		const removeColor = new ButtonView( locale );
+		const buttonLabel = new View();
+
+		removeColor.extendTemplate( {
+			attributes: {
+				class: [ 'ck', 'ck-dropdown__color-picker-remove-color' ]
+			},
+		} );
+
+		buttonLabel.setTemplate( {
+			tag: 'span',
+			children: [
+				'Remove color'
+			],
+			on: {
+				click: bind.to( () => {
+					this.value = '';
+					this._toggleColorPicker();
+				} )
+			}
+		} );
+
+		removeColor.children.add( buttonLabel );
+
+		return removeColor;
+	}
+
+	_createLabelView( id ) {
+		const label = new LabelView();
+		label.for = id;
+		label.bind( 'text' ).to( this, 'label' );
+
+		return label;
+	}
+
+	_createColorGrid( locale ) {
+		const options = {
+			colorDefinitions: [
+				{
+					color: 'hsl(0, 0%, 0%)',
+					label: 'Black'
+				},
+				{
+					color: 'hsl(0, 0%, 30%)',
+					label: 'Dim grey'
+				},
+				{
+					color: 'hsl(0, 0%, 60%)',
+					label: 'Grey'
+				},
+				{
+					color: 'hsl(0, 0%, 90%)',
+					label: 'Light grey'
+				},
+				{
+					color: 'hsl(0, 0%, 100%)',
+					label: 'White',
+					hasBorder: true
+				},
+				{
+					color: 'hsl(0, 75%, 60%)',
+					label: 'Red'
+				},
+				{
+					color: 'hsl(30, 75%, 60%)',
+					label: 'Orange'
+				},
+				{
+					color: 'hsl(60, 75%, 60%)',
+					label: 'Yellow'
+				},
+				{
+					color: 'hsl(90, 75%, 60%)',
+					label: 'Light green'
+				},
+				{
+					color: 'hsl(120, 75%, 60%)',
+					label: 'Green'
+				},
+				{
+					color: 'hsl(150, 75%, 60%)',
+					label: 'Aquamarine'
+				},
+				{
+					color: 'hsl(180, 75%, 60%)',
+					label: 'Turquoise'
+				},
+				{
+					color: 'hsl(210, 75%, 60%)',
+					label: 'Light blue'
+				},
+				{
+					color: 'hsl(240, 75%, 60%)',
+					label: 'Blue'
+				},
+				{
+					color: 'hsl(270, 75%, 60%)',
+					label: 'Purple'
+				}
+			],
+			columns: 5
+		};
+		const colorGrid = new ColorGrid( locale, options );
+		colorGrid.delegate( 'execute' ).to( this, 'setColor:setValueFromPicker' );
+		colorGrid.bind( 'selectedColor' ).to( this, 'value' );
+
+		return colorGrid;
+	}
+
+	_toggleColorPicker() {
+		this.dropdownButton.fire( 'open' );
+	}
+}

+ 17 - 0
packages/ckeditor5-ui/theme/components/colorinputview/colorinputview.css

@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/*
+ * Note: This file should contain the wireframe styles only. But since there are no such styles,
+ * it acts as a message to the builder telling that it should look for the corresponding styles
+ * **in the theme** when compiling the editor.
+ */
+
+.ck.ck-dropdown__input-color-preview {
+	position: absolute;
+	right: 5px;
+  width: 20px;
+	height: 20px;
+}