From 6682e410f3f117efcc6180febd2e662ce00a6d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 25 May 2018 16:57:52 +0200 Subject: [PATCH] WIP --- src/tableui.js | 186 ++++++++++++++++++++++++++++++++++++++++++++++-- theme/table.css | 26 +++++++ 2 files changed, 205 insertions(+), 7 deletions(-) diff --git a/src/tableui.js b/src/tableui.js index 420f82af..417e2d15 100644 --- a/src/tableui.js +++ b/src/tableui.js @@ -8,7 +8,6 @@ */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; import { addListToDropdown, createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import Model from '@ckeditor/ckeditor5-ui/src/model'; import Collection from '@ckeditor/ckeditor5-utils/src/collection'; @@ -19,6 +18,163 @@ import tableRowIcon from './../theme/icons/table-row.svg'; import tableMergeCellIcon from './../theme/icons/table-merge-cell.svg'; import tableSplitCellIcon from './../theme/icons/table-split-cell.svg'; +import View from '@ckeditor/ckeditor5-ui/src/view'; +import FocusTracker from '../../ckeditor5-utils/src/focustracker'; +import FocusCycler from '../../ckeditor5-ui/src/focuscycler'; + +// TODO RENAME & Split +import './../theme/table.css'; + +class TableSizeChooser extends View { + constructor( locale ) { + super( locale ); + + const bind = this.bindTemplate; + + this.set( 'isOn', false ); + + this.setTemplate( { + tag: 'div', + attributes: { + class: [ + 'ck-table-size-choose-box', + bind.if( 'isOn', 'ck-on' ) + ] + }, + on: { + mouseover: bind.to( 'over' ) + } + } ); + } +} + +class TableSizeView extends View { + /** + * @inheritDoc + */ + constructor( locale ) { + super( locale ); + + const bind = this.bindTemplate; + + /** + * Collection of the toolbar items (like buttons). + * + * @readonly + * @member {module:ui/viewcollection~ViewCollection} + */ + this.items = this.createCollection(); + + /** + * Tracks information about DOM focus in the list. + * + * @readonly + * @member {module:utils/focustracker~FocusTracker} + */ + this.focusTracker = new FocusTracker(); + + this.set( 'rows', 0 ); + this.set( 'columns', 0 ); + + /** + * Helps cycling over focusable {@link #items} in the toolbar. + * + * @readonly + * @protected + * @member {module:ui/focuscycler~FocusCycler} + */ + this._focusCycler = new FocusCycler( { + focusables: this.items, + focusTracker: this.focusTracker, + keystrokeHandler: this.keystrokes, + actions: { + // Navigate toolbar items backwards using the arrow[left,up] keys. + focusPrevious: [ 'arrowleft', 'arrowup' ], + + // Navigate toolbar items forwards using the arrow[right,down] keys. + focusNext: [ 'arrowright', 'arrowdown' ] + } + } ); + + this.bind( 'size' ) + .to( this, 'columns', this, 'rows', ( columns, rows ) => `${ rows } x ${ columns }` ); + + this.setTemplate( { + tag: 'div', + attributes: { + class: [ + 'ck', + bind.if( 'isVertical', 'ck-toolbar_vertical' ), + bind.to( 'className' ) + ] + }, + + children: [ + { + tag: 'div', + attributes: { + class: [ 'ck-table-size-choose-box-container' ] + }, + children: this.items + }, + { + tag: 'div', + attributes: { + class: [ 'ck-table-size-label' ] + }, + children: [ + { text: bind.to( 'size' ) } + ] + } + ], + + on: { + click: bind.to( () => { + this.fire( 'execute' ); + } ) + } + } ); + + for ( let i = 0; i < 100; i++ ) { + const view = new TableSizeChooser(); + + view.on( 'over', () => { + const row = parseInt( i / 10 ); + const column = i % 10; + + this.set( 'rows', row + 1 ); + this.set( 'columns', column + 1 ); + } ); + + this.items.add( view ); + } + + this.on( 'change:columns', () => { + this.updateItems(); + } ); + + this.on( 'change:rows', () => { + this.updateItems(); + } ); + } + + updateItems() { + const row = this.rows - 1; + const column = this.columns - 1; + + this.items.map( ( item, index ) => { + const itemRow = parseInt( index / 10 ); + const itemColumn = index % 10; + + if ( itemRow <= row && itemColumn <= column ) { + item.set( 'isOn', true ); + } else { + item.set( 'isOn', false ); + } + } ); + } +} + /** * The table UI plugin. * @@ -33,22 +189,38 @@ export default class TableUI extends Plugin { editor.ui.componentFactory.add( 'insertTable', locale => { const command = editor.commands.get( 'insertTable' ); - const buttonView = new ButtonView( locale ); + const dropdownView = createDropdown( locale ); - buttonView.bind( 'isEnabled' ).to( command ); + dropdownView.bind( 'isEnabled' ).to( command ); - buttonView.set( { + dropdownView.buttonView.set( { icon: tableIcon, label: 'Insert table', tooltip: true } ); - buttonView.on( 'execute', () => { - editor.execute( 'insertTable' ); + const tableSizeView = new TableSizeView( locale ); + + tableSizeView.delegate( 'execute' ).to( dropdownView ); + + dropdownView.buttonView.on( 'open', () => { + // Reset the chooser before showing it to the user. + tableSizeView.rows = 0; + tableSizeView.columns = 0; + } ); + + dropdownView.on( 'execute', () => { + command.execute( { rows: tableSizeView.rows, columns: tableSizeView.columns } ); + + tableSizeView.width = 0; + tableSizeView.height = 0; + editor.editing.view.focus(); } ); - return buttonView; + dropdownView.panelView.children.add( tableSizeView ); + + return dropdownView; } ); editor.ui.componentFactory.add( 'tableColumn', locale => { diff --git a/theme/table.css b/theme/table.css index 419ba7f5..721b6dbf 100644 --- a/theme/table.css +++ b/theme/table.css @@ -24,3 +24,29 @@ background-color: inherit; color: inherit; } + +.ck .ck-table-size-choose-box-container { + display: flex; + flex-direction: row; + flex-wrap: wrap; + width: 160px; + padding: 10px 10px 0 10px; +} + +.ck .ck-table-size-choose-box { + width: 12px; + height: 11px; + margin: 1px; + border: 1px solid #aaa; + + border-radius: 1px; + + &.ck-on { + border-color: #5fa6ff; + background: #c9e9ff; + } +} + +.ck .ck-table-size-label { + text-align: center; +}