Răsfoiți Sursa

Other: Initial SplitButton implementation.

Maciej Gołaszewski 8 ani în urmă
părinte
comite
9877565919

+ 4 - 1
packages/ckeditor5-ui/src/button/buttonview.js

@@ -178,6 +178,9 @@ export default class ButtonView extends View {
 		 */
 		 */
 		this.labelView = this._createLabelView();
 		this.labelView = this._createLabelView();
 
 
+		// TODO: used for Icon style hack in Highlight UI
+		this.iconView = new IconView();
+
 		/**
 		/**
 		 * Tooltip of the button bound to the template.
 		 * Tooltip of the button bound to the template.
 		 *
 		 *
@@ -252,7 +255,7 @@ export default class ButtonView extends View {
 		super.render();
 		super.render();
 
 
 		if ( this.icon ) {
 		if ( this.icon ) {
-			const iconView = this.iconView = new IconView();
+			const iconView = this.iconView;
 
 
 			iconView.bind( 'content' ).to( this, 'icon' );
 			iconView.bind( 'content' ).to( this, 'icon' );
 
 

+ 111 - 0
packages/ckeditor5-ui/src/button/splitbuttonview.js

@@ -0,0 +1,111 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module ui/button/buttonview
+ */
+
+import View from '../view';
+import ButtonView from './buttonview';
+
+import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
+import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
+
+/**
+ * TODO
+ */
+export default class SplitButtonView extends View {
+	/**
+	 * @inheritDoc
+	 */
+	constructor( locale, startButton ) {
+		super( locale );
+
+		this.children = this.createCollection();
+
+		this.buttonView = startButton || this._createButtonView();
+		this.arrowView = this._createArrowView();
+
+		this.keystrokes = new KeystrokeHandler();
+		this.focusTracker = new FocusTracker();
+
+		this.setTemplate( {
+			tag: 'div',
+
+			attributes: {
+				class: 'ck-splitbutton'
+			},
+
+			children: this.children
+		} );
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	render() {
+		super.render();
+
+		this.children.add( this.buttonView );
+		this.children.add( this.arrowView );
+
+		this.focusTracker.add( this.buttonView.element );
+		this.focusTracker.add( this.arrowView.element );
+
+		this.keystrokes.listenTo( this.element );
+
+		this.keystrokes.set( 'arrowright', ( evt, cb ) => {
+			if ( this.focusTracker.focusedElement === this.buttonView.element ) {
+				cb();
+
+				this.arrowView.focus();
+			}
+		} );
+
+		this.keystrokes.set( 'arrowleft', ( evt, cb ) => {
+			if ( this.focusTracker.focusedElement === this.arrowView.element ) {
+				cb();
+
+				this.buttonView.focus();
+			}
+		} );
+	}
+
+	swapButton( buttonView ) {
+		// remove from FT
+		this.focusTracker.remove( this.buttonView.element );
+
+		this.children.remove( this.buttonView );
+
+		this.buttonView = buttonView;
+
+		this.children.add( this.buttonView, 0 );
+		this.focusTracker.add( this.buttonView.element );
+	}
+
+	focus() {
+		this.buttonView.focus();
+	}
+
+	_createButtonView() {
+		const buttonView = new ButtonView();
+
+		buttonView.bind( 'icon' ).to( this, 'icon' );
+
+		return buttonView;
+	}
+
+	_createArrowView() {
+		const arrowView = new ButtonView();
+		arrowView.icon = 'abc';
+		arrowView.extendTemplate( {
+			attributes: {
+				class: 'ck-splitbutton-arrow'
+			}
+		} );
+
+		return arrowView;
+	}
+}

+ 70 - 0
packages/ckeditor5-ui/src/dropdown/button/createsplitbuttondropdown.js

@@ -0,0 +1,70 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module ui/dropdown/button/createsplitbuttondropdown
+ */
+
+// TODO: import createDropdown from '../createdropdown';
+import SplitButtonView from '../../button/splitbuttonview';
+import DropdownView from '../dropdownview';
+import DropdownPanelView from '../dropdownpanelview';
+
+import ButtonGroupView from '../../buttongroup/buttongroupview';
+import { closeDropdownOnBlur, closeDropdownOnExecute, openDropdownOnArrows } from '../utils';
+
+/**
+ * TODO
+ */
+export default function createSplitButtonDropdown( model, buttonViews, locale, startButton ) {
+	// // Make disabled when all buttons are disabled
+	model.bind( 'isEnabled' ).to(
+		// Bind to #isEnabled of each command...
+		...getBindingTargets( buttonViews, 'isEnabled' ),
+		// ...and set it true if any command #isEnabled is true.
+		( ...areEnabled ) => areEnabled.some( isEnabled => isEnabled )
+	);
+
+	const splitButtonView = new SplitButtonView( locale, startButton );
+
+	splitButtonView.bind( 'label', 'isOn', 'isEnabled', 'withText', 'keystroke', 'tooltip', 'icon' ).to( model );
+
+	const panelView = new DropdownPanelView( locale );
+
+	const dropdownView = new DropdownView( locale, splitButtonView, panelView );
+	// END of TODO
+
+	const buttonGroupView = dropdownView.buttonGroupView = new ButtonGroupView( { isVertical: model.isVertical } );
+
+	buttonGroupView.bind( 'isVertical' ).to( model, 'isVertical' );
+
+	buttonViews.map( view => buttonGroupView.items.add( view ) );
+
+	dropdownView.extendTemplate( {
+		attributes: {
+			class: [
+				'ck-splitbutton-dropdown'
+			]
+		}
+	} );
+
+	dropdownView.buttonView.extendTemplate( {
+		attributes: {
+			class: [ 'ck-button-dropdown' ]
+		}
+	} );
+
+	dropdownView.panelView.children.add( buttonGroupView );
+
+	closeDropdownOnBlur( dropdownView );
+	closeDropdownOnExecute( dropdownView, buttonGroupView.items );
+	openDropdownOnArrows( dropdownView, buttonGroupView );
+
+	return dropdownView;
+}
+
+function getBindingTargets( buttons, attribute ) {
+	return Array.prototype.concat( ...buttons.map( button => [ button, attribute ] ) );
+}

+ 22 - 0
packages/ckeditor5-ui/theme/components/splitbutton.scss

@@ -0,0 +1,22 @@
+// Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+// For licensing, see LICENSE.md or http://ckeditor.com/license
+
+.ck-splitbutton-arrow {
+	//padding-right: 2 * ck-spacing();
+	svg.icon {
+		width: 0;
+		min-width: 0;
+	}
+
+	&::after {
+		content: '';
+		width: 0;
+		height: 0;
+		pointer-events: none;
+		z-index: ck-z();
+
+		position: absolute;
+		top: 50%;
+		transform: translate3d(-50%, -50%, 0);
+	}
+}