diff --git a/lang/contexts.json b/lang/contexts.json index 8639a098..a2081b11 100644 --- a/lang/contexts.json +++ b/lang/contexts.json @@ -22,7 +22,7 @@ "Cell properties": "The label describing the form allowing to specify the properties of a selected table cell.", "Border": "The label describing a group of border–related form fields (border style, color, etc.).", "Style": "The label for the dropdown that allows configuring the border style of a table or a table cell.", - "Width": "The label for the input that allows configuring the border width of a table or a table cell.", + "Width": "The label for the input that allows configuring the width of a table or a table cell or the width of a border.", "Height": "The label for the input that allows configuring the height of a table or a table cell.", "Color": "The label for the input that allows configuring the border color of a table or a table cell.", "Background": "The label for the input that allows configuring the background color of a table or a table cell.", @@ -52,6 +52,7 @@ "Align table to the left": "The label used by assistive technologies describing a button that aligns the table to the left.", "Center table": "The label used by assistive technologies describing a button that centers the table.", "Align table to the right": "The label used by assistive technologies describing a button that aligns the table to the right.", + "Remove color": "The label used by a button next to the color palette in the color picker that removes the color (resets it to an empty value).", "The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\".": "The localized error string that can be displayed next to color (background, border) fields that have an invalid value", "The value is invalid. Try \"10px\" or \"2em\" or simply \"2\".": "The localized error string that can be displayed next to length (padding, border width) fields that have an invalid value." } diff --git a/src/table.js b/src/table.js index e33d3706..709629b0 100644 --- a/src/table.js +++ b/src/table.js @@ -63,3 +63,31 @@ export default class Table extends Plugin { * * @member {module:table/table~TableConfig} module:core/editor/editorconfig~EditorConfig#table */ + +/** + * An array of colors definitions (either strings or objects). + * + * const colors = [ + * { + * color: 'hsl(0, 0%, 60%)', + * label: 'Grey' + * }, + * 'hsl(0, 0%, 80%)', + * { + * color: 'hsl(0, 0%, 90%)', + * label: 'Light grey' + * }, + * { + * color: 'hsl(0, 0%, 100%)', + * label: 'White', + * hasBorder: true + * }, + * '#FF0000' + * ] + * + * Usually used as a configuration parameter, for instance in + * {@link module:table/table~TableConfig#tableProperties `config.table.tableProperties`} + * or {@link module:table/table~TableConfig#tableCellProperties `config.table.tableCellProperties`}. + * + * @typedef {Array.} module:table/table~TableColorConfig + */ diff --git a/src/tablecellproperties.js b/src/tablecellproperties.js index 692beb7e..323fadfb 100644 --- a/src/tablecellproperties.js +++ b/src/tablecellproperties.js @@ -35,3 +35,43 @@ export default class TableCellProperties extends Plugin { return [ TableCellPropertiesEditing, TableCellPropertiesUI ]; } } + +/** + * A configuration of the table cell properties user interface (balloon). It allows to define: + * + * * the color palette for the cell border color style field (`tableCellProperties.borderColors`), + * * the color palette for the cell background style field (`tableCellProperties.backgroundColors`). + * + * const tableConfig = { + * tableCellProperties: { + * borderColors: [ + * { + * color: 'hsl(0, 0%, 90%)', + * label: 'Light grey' + * }, + * // ... + * ], + * backgroundColors: [ + * { + * color: 'hsl(120, 75%, 60%)', + * label: 'Green' + * }, + * // ... + * ] + * } + * }; + * + * **Note**: The configurations do not impact the data being loaded into the editor, + * i.e. they do not limit or filter the colors in the data. They are used only in the user interface + * allowing users to pick colors in a more convenient way. + * + * The default color palettes for the cell background and the cell border are the same + * ({@link module:table/ui/utils~defaultColors check out their content}). + * + * Both color palette configurations must follow the + * {@link module:table/table~TableColorConfig table color configuration format}. + * + * Read more about configuring the table feature in {@link module:table/table~TableConfig}. + * + * @member {Object} module:table/table~TableConfig#tableCellProperties + */ diff --git a/src/tablecellproperties/tablecellpropertiesui.js b/src/tablecellproperties/tablecellpropertiesui.js index e354a997..a6c16bcc 100644 --- a/src/tablecellproperties/tablecellpropertiesui.js +++ b/src/tablecellproperties/tablecellpropertiesui.js @@ -19,10 +19,15 @@ import { getBalloonCellPositionData, getLocalizedColorErrorText, getLocalizedLengthErrorText, + defaultColors, lengthFieldValidator, lineWidthFieldValidator, repositionContextualBalloon } from '../ui/utils'; +import { + getLocalizedColorOptions, + normalizeColorOptions +} from '@ckeditor/ckeditor5-ui/src/colorgrid/utils'; import { debounce } from 'lodash-es'; const ERROR_TEXT_TIMEOUT = 500; @@ -51,6 +56,18 @@ export default class TableCellPropertiesUI extends Plugin { return 'TableCellPropertiesUI'; } + /** + * @inheritDoc + */ + constructor( editor ) { + super( editor ); + + editor.config.define( 'table.tableCellProperties', { + borderColors: defaultColors, + backgroundColors: defaultColors + } ); + } + /** * @inheritDoc */ @@ -118,7 +135,15 @@ export default class TableCellPropertiesUI extends Plugin { _createPropertiesView() { const editor = this.editor; const viewDocument = editor.editing.view.document; - const view = new TableCellPropertiesView( editor.locale ); + const config = editor.config.get( 'table.tableCellProperties' ); + const borderColorsConfig = normalizeColorOptions( config.borderColors ); + const localizedBorderColors = getLocalizedColorOptions( editor.locale, borderColorsConfig ); + const backgroundColorsConfig = normalizeColorOptions( config.backgroundColors ); + const localizedBackgroundColors = getLocalizedColorOptions( editor.locale, backgroundColorsConfig ); + const view = new TableCellPropertiesView( editor.locale, { + borderColors: localizedBorderColors, + backgroundColors: localizedBackgroundColors + } ); const t = editor.t; // Render the view so its #element is available for the clickOutsideHandler. diff --git a/src/tablecellproperties/ui/tablecellpropertiesview.js b/src/tablecellproperties/ui/tablecellpropertiesview.js index ac8bc4fe..08970a96 100644 --- a/src/tablecellproperties/ui/tablecellpropertiesview.js +++ b/src/tablecellproperties/ui/tablecellpropertiesview.js @@ -21,7 +21,12 @@ import LabelView from '@ckeditor/ckeditor5-ui/src/label/labelview'; import { addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; -import { fillToolbar, getBorderStyleDefinitions, getBorderStyleLabels } from '../../ui/utils'; +import { + fillToolbar, + getBorderStyleDefinitions, + getBorderStyleLabels, + getLabeledColorInputCreator, +} from '../../ui/utils'; import FormRowView from '../../ui/formrowview'; import FormHeaderView from '../../ui/formheaderview'; @@ -57,9 +62,16 @@ const ALIGNMENT_ICONS = { */ export default class TableCellPropertiesView extends View { /** - * @inheritDoc + * @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance. + * @param {Object} options Additional configuration of the view. + * @param {module:table/table~TableColorConfig} options.borderColors A configuration of the border + * color palette used by the + * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#borderColorInput}. + * @param {module:table/table~TableColorConfig} options.backgroundColors A configuration of the background + * color palette used by the + * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#backgroundInput}. */ - constructor( locale ) { + constructor( locale, options ) { super( locale ); this.set( { @@ -145,6 +157,13 @@ export default class TableCellPropertiesView extends View { verticalAlignment: '' } ); + /** + * Options passed to the view. See {@link #constructor} to learn more. + * + * @member {Object} + */ + this.options = options; + const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields(); const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields(); const { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields(); @@ -193,7 +212,7 @@ export default class TableCellPropertiesView extends View { * An input that allows specifying the color of the table cell border. * * @readonly - * @member {module:ui/inputtext/inputtextview~InputTextView} + * @member {module:table/ui/colorinputview~ColorInputView} */ this.borderColorInput = borderColorInput; @@ -201,7 +220,7 @@ export default class TableCellPropertiesView extends View { * An input that allows specifying the table cell background color. * * @readonly - * @member {module:ui/inputtext/inputtextview~InputTextView} + * @member {module:table/ui/colorinputview~ColorInputView} */ this.backgroundInput = this._createBackgroundField(); @@ -329,7 +348,7 @@ export default class TableCellPropertiesView extends View { operatorLabel, heightInput ], - class: 'ck-table-cell-properties-form__dimensions-row' + class: 'ck-table-form__dimensions-row' } ), // Padding row. new FormRowView( locale, { @@ -431,6 +450,10 @@ export default class TableCellPropertiesView extends View { * @returns {Object.} */ _createBorderFields() { + const colorInputCreator = getLabeledColorInputCreator( { + colorConfig: this.options.borderColors, + columns: 5 + } ); const locale = this.locale; const t = this.t; @@ -481,13 +504,18 @@ export default class TableCellPropertiesView extends View { // -- Color --------------------------------------------------- - const borderColorInput = new LabeledView( locale, createLabeledInputText ); - borderColorInput.label = t( 'Color' ); + const borderColorInput = new LabeledView( locale, colorInputCreator ); + + borderColorInput.set( { + label: t( 'Color' ), + class: 'ck-table-form__border-color', + } ); + borderColorInput.view.bind( 'value' ).to( this, 'borderColor' ); borderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet ); borderColorInput.view.on( 'input', () => { - this.borderColor = borderColorInput.view.element.value; + this.borderColor = borderColorInput.view.value; } ); // Reset the border color and width fields when style is "none". @@ -518,8 +546,12 @@ export default class TableCellPropertiesView extends View { _createBackgroundField() { const locale = this.locale; const t = this.t; + const colorInputCreator = getLabeledColorInputCreator( { + colorConfig: this.options.backgroundColors, + columns: 5 + } ); - const backgroundInput = new LabeledView( locale, createLabeledInputText ); + const backgroundInput = new LabeledView( locale, colorInputCreator ); backgroundInput.set( { label: t( 'Background' ), @@ -528,7 +560,7 @@ export default class TableCellPropertiesView extends View { backgroundInput.view.bind( 'value' ).to( this, 'backgroundColor' ); backgroundInput.view.on( 'input', () => { - this.backgroundColor = backgroundInput.view.element.value; + this.backgroundColor = backgroundInput.view.value; } ); return backgroundInput; @@ -558,7 +590,7 @@ export default class TableCellPropertiesView extends View { widthInput.set( { label: t( 'Width' ), - class: 'ck-table-cell-properties-form__width', + class: 'ck-table-form__dimensions-row__width', } ); widthInput.view.bind( 'value' ).to( this, 'width' ); @@ -587,7 +619,7 @@ export default class TableCellPropertiesView extends View { heightInput.set( { label: t( 'Height' ), - class: 'ck-table-cell-properties-form__height', + class: 'ck-table-form__dimensions-row__height', } ); heightInput.view.bind( 'value' ).to( this, 'height' ); diff --git a/src/tableproperties.js b/src/tableproperties.js index bda740e5..ce4d1970 100644 --- a/src/tableproperties.js +++ b/src/tableproperties.js @@ -36,3 +36,43 @@ export default class TableProperties extends Plugin { return [ TablePropertiesEditing, TablePropertiesUI ]; } } + +/** + * A configuration of the table properties user interface (balloon). It allows to define: + * + * * the color palette for the table border color style field (`tableProperties.borderColors`), + * * the color palette for the table background style field (`tableProperties.backgroundColors`). + * + * const tableConfig = { + * tableProperties: { + * borderColors: [ + * { + * color: 'hsl(0, 0%, 90%)', + * label: 'Light grey' + * }, + * // ... + * ], + * backgroundColors: [ + * { + * color: 'hsl(120, 75%, 60%)', + * label: 'Green' + * }, + * // ... + * ] + * } + * }; + * + * **Note**: The configurations do not impact the data being loaded into the editor, + * i.e. they do not limit or filter the colors in the data. They are used only in the user interface + * allowing users to pick colors in a more convenient way. + * + * The default color palettes for the table background and the table border are the same + * ({@link module:table/ui/utils~defaultColors check out their content}). + * + * Both color palette configurations must follow the + * {@link module:table/table~TableColorConfig table color configuration format}. + * + * Read more about configuring the table feature in {@link module:table/table~TableConfig}. + * + * @member {Object} module:table/table~TableConfig#tableProperties + */ diff --git a/src/tableproperties/tablepropertiesui.js b/src/tableproperties/tablepropertiesui.js index 999eec0a..5660a4dd 100644 --- a/src/tableproperties/tablepropertiesui.js +++ b/src/tableproperties/tablepropertiesui.js @@ -21,8 +21,13 @@ import { getLocalizedLengthErrorText, lengthFieldValidator, lineWidthFieldValidator, - repositionContextualBalloon + repositionContextualBalloon, + defaultColors, } from '../ui/utils'; +import { + getLocalizedColorOptions, + normalizeColorOptions +} from '@ckeditor/ckeditor5-ui/src/colorgrid/utils'; import { debounce } from 'lodash-es'; const ERROR_TEXT_TIMEOUT = 500; @@ -51,6 +56,18 @@ export default class TablePropertiesUI extends Plugin { return 'TablePropertiesUI'; } + /** + * @inheritDoc + */ + constructor( editor ) { + super( editor ); + + editor.config.define( 'table.tableProperties', { + borderColors: defaultColors, + backgroundColors: defaultColors + } ); + } + /** * @inheritDoc */ @@ -118,7 +135,15 @@ export default class TablePropertiesUI extends Plugin { _createPropertiesView() { const editor = this.editor; const viewDocument = editor.editing.view.document; - const view = new TablePropertiesView( editor.locale ); + const config = editor.config.get( 'table.tableProperties' ); + const borderColorsConfig = normalizeColorOptions( config.borderColors ); + const localizedBorderColors = getLocalizedColorOptions( editor.locale, borderColorsConfig ); + const backgroundColorsConfig = normalizeColorOptions( config.backgroundColors ); + const localizedBackgroundColors = getLocalizedColorOptions( editor.locale, backgroundColorsConfig ); + const view = new TablePropertiesView( editor.locale, { + borderColors: localizedBorderColors, + backgroundColors: localizedBackgroundColors + } ); const t = editor.t; // Render the view so its #element is available for the clickOutsideHandler. diff --git a/src/tableproperties/ui/tablepropertiesview.js b/src/tableproperties/ui/tablepropertiesview.js index bde7050f..4c0d031a 100644 --- a/src/tableproperties/ui/tablepropertiesview.js +++ b/src/tableproperties/ui/tablepropertiesview.js @@ -21,7 +21,12 @@ import LabelView from '@ckeditor/ckeditor5-ui/src/label/labelview'; import { addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; -import { fillToolbar, getBorderStyleDefinitions, getBorderStyleLabels } from '../../ui/utils'; +import { + fillToolbar, + getBorderStyleDefinitions, + getBorderStyleLabels, + getLabeledColorInputCreator +} from '../../ui/utils'; import FormRowView from '../../ui/formrowview'; import FormHeaderView from '../../ui/formheaderview'; @@ -49,9 +54,16 @@ const ALIGNMENT_ICONS = { */ export default class TablePropertiesView extends View { /** - * @inheritDoc + * @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance. + * @param {Object} options Additional configuration of the view. + * @param {module:table/table~TableColorConfig} options.borderColors A configuration of the border + * color palette used by the + * {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView#borderColorInput}. + * @param {module:table/table~TableColorConfig} options.backgroundColors A configuration of the background + * color palette used by the + * {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView#backgroundInput}. */ - constructor( locale ) { + constructor( locale, options ) { super( locale ); this.set( { @@ -119,6 +131,14 @@ export default class TablePropertiesView extends View { alignment: '' } ); + /** + * Options passed to the view. See {@link #constructor} to learn more. + * + * @protected + * @member {Object} + */ + this.options = options; + const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields(); const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields(); const { alignmentToolbar, alignmentLabel } = this._createAlignmentFields(); @@ -167,7 +187,7 @@ export default class TablePropertiesView extends View { * An input that allows specifying the color of the table border. * * @readonly - * @member {module:ui/inputtext/inputtextview~InputTextView} + * @member {module:table/ui/colorinputview~ColorInputView} */ this.borderColorInput = borderColorInput; @@ -175,7 +195,7 @@ export default class TablePropertiesView extends View { * An input that allows specifying the table background color. * * @readonly - * @member {module:ui/inputtext/inputtextview~InputTextView} + * @member {module:table/ui/colorinputview~ColorInputView} */ this.backgroundInput = this._createBackgroundField(); @@ -286,7 +306,7 @@ export default class TablePropertiesView extends View { operatorLabel, heightInput ], - class: 'ck-table-properties-form__dimensions-row' + class: 'ck-table-form__dimensions-row' } ), // Alignment row. new FormRowView( locale, { @@ -377,6 +397,10 @@ export default class TablePropertiesView extends View { * @returns {Object.} */ _createBorderFields() { + const colorInputCreator = getLabeledColorInputCreator( { + colorConfig: this.options.borderColors, + columns: 5 + } ); const locale = this.locale; const t = this.t; @@ -427,13 +451,18 @@ export default class TablePropertiesView extends View { // -- Color --------------------------------------------------- - const borderColorInput = new LabeledView( locale, createLabeledInputText ); - borderColorInput.label = t( 'Color' ); + const borderColorInput = new LabeledView( locale, colorInputCreator ); + + borderColorInput.set( { + label: t( 'Color' ), + class: 'ck-table-form__border-color', + } ); + borderColorInput.view.bind( 'value' ).to( this, 'borderColor' ); borderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet ); borderColorInput.view.on( 'input', () => { - this.borderColor = borderColorInput.view.element.value; + this.borderColor = borderColorInput.view.value; } ); // Reset the border color and width fields when style is "none". @@ -462,10 +491,14 @@ export default class TablePropertiesView extends View { * @returns {module:ui/labeledview/labeledview~LabeledView} */ _createBackgroundField() { + const backgroundInputCreator = getLabeledColorInputCreator( { + colorConfig: this.options.backgroundColors, + columns: 5 + } ); const locale = this.locale; const t = this.t; - const backgroundInput = new LabeledView( locale, createLabeledInputText ); + const backgroundInput = new LabeledView( locale, backgroundInputCreator ); backgroundInput.set( { label: t( 'Background' ), @@ -474,7 +507,7 @@ export default class TablePropertiesView extends View { backgroundInput.view.bind( 'value' ).to( this, 'backgroundColor' ); backgroundInput.view.on( 'input', () => { - this.backgroundColor = backgroundInput.view.element.value; + this.backgroundColor = backgroundInput.view.value; } ); return backgroundInput; @@ -504,7 +537,7 @@ export default class TablePropertiesView extends View { widthInput.set( { label: t( 'Width' ), - class: 'ck-table-properties-form__width', + class: 'ck-table-form__dimensions-row__width', } ); widthInput.view.bind( 'value' ).to( this, 'width' ); @@ -533,7 +566,7 @@ export default class TablePropertiesView extends View { heightInput.set( { label: t( 'Height' ), - class: 'ck-table-properties-form__height', + class: 'ck-table-form__dimensions-row__height', } ); heightInput.view.bind( 'value' ).to( this, 'height' ); diff --git a/src/ui/colorinputview.js b/src/ui/colorinputview.js new file mode 100644 index 00000000..f5b80267 --- /dev/null +++ b/src/ui/colorinputview.js @@ -0,0 +1,252 @@ +/** + * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/** + * @module table/ui/colorinputview + */ + +import View from '@ckeditor/ckeditor5-ui/src/view'; +import InputTextView from '@ckeditor/ckeditor5-ui/src/inputtext/inputtextview'; +import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; +import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; +import ColorGrid from '@ckeditor/ckeditor5-ui/src/colorgrid/colorgridview'; +import removeButtonIcon from '@ckeditor/ckeditor5-core/theme/icons/eraser.svg'; +import '../../theme/colorinput.css'; + +/** + * The color input view class. It allows the user to type in a color (hex, rgb, etc.) + * or choose it from the configurable color palette with a preview. + * + * @private + * @extends module:ui/view~View + */ +export default class ColorInputView extends View { + /** + * Creates an instance of the color input view. + * + * @param {module:utils/locale~Locale} locale The locale instance. + * @param {Object} options The input options. + * @param {module:ui/colorgrid/colorgrid~ColorDefinition} options.colorDefinitions The colors to be displayed + * in the palette inside the input's dropdown. + * @param {Number} options.columns The number of columns in which the colors will be displayed. + */ + constructor( locale, options ) { + super( locale ); + + const bind = this.bindTemplate; + + /** + * The value of the input. + * + * @observable + * @member {String} #value + * @default '' + */ + this.set( 'value', '' ); + + /** + * The `id` attribute of the input (i.e. to pair with a `