8
0
panr 5 лет назад
Родитель
Сommit
434fac2caf

+ 0 - 241
packages/ckeditor5-ui/src/labeledfieldview/labeledfieldview.js

@@ -1,241 +0,0 @@
-/**
- * @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 ui/labeledfieldview/labeledfieldview
- */
-
-import View from '../view';
-import uid from '@ckeditor/ckeditor5-utils/src/uid';
-import LabelView from '../label/labelview';
-import '../../theme/components/labeledfieldview/labeledfieldview.css';
-
-/**
- * The labeled field view class. It can be used to enhance any view with the following features:
- *
- * * a label,
- * * (optional) an error message,
- * * (optional) an info (status) text,
- *
- * all bound logically by proper DOM attributes for UX and accessibility.  It also provides an interface
- * (e.g. observable properties) that allows controlling those additional features.
- *
- * The constructor of this class requires a callback that returns a view to be labeled. The callback
- * is called with unique ids that allow binding of DOM properties:
- *
- *		const labeledInputView = new LabeledFieldView( locale, ( labeledFieldView, viewUid, statusUid ) => {
- *			const inputView = new InputTextView( labeledFieldView.locale );
- *
- *			inputView.set( {
- *				id: viewUid,
- *				ariaDescribedById: statusUid
- *			} );
- *
- *			inputView.bind( 'isReadOnly' ).to( labeledFieldView, 'isEnabled', value => !value );
- *			inputView.bind( 'hasError' ).to( labeledFieldView, 'errorText', value => !!value );
- *
- *			return inputView;
- *		} );
- *
- *		labeledInputView.label = 'User name';
- *		labeledInputView.infoText = 'Full name like for instance, John Doe.';
- *		labeledInputView.render();
- *
- *		document.body.append( labeledInputView.element );
- *
- * See {@link module:ui/labeledfieldview/utils} to discover ready–to–use labeled input helpers for common
- * UI components.
- *
- * @extends module:ui/view~View
- */
-export default class LabeledFieldView extends View {
-	/**
-	 * Creates an instance of the labeled field view class using a provided creator function
-	 * that provides the view to be labeled.
-	 *
-	 * @param {module:utils/locale~Locale} locale The locale instance.
-	 * @param {Function} viewCreator A function that returns a {@link module:ui/view~View}
-	 * that will be labeled. The following arguments are passed to the creator function:
-	 *
-	 * * an instance of the `LabeledFieldView` to allow binding observable properties,
-	 * * an UID string that connects the {@link #labelView label} and the labeled field view in DOM,
-	 * * an UID string that connects the {@link #statusView status} and the labeled field view in DOM.
-	 */
-	constructor( locale, viewCreator ) {
-		super( locale );
-
-		const viewUid = `ck-labeled-view-${ uid() }`;
-		const statusUid = `ck-labeled-view-status-${ uid() }`;
-
-		/**
-		 * The field that gets labeled.
-		 *
-		 * @member {module:ui/view~View} #field
-		 */
-		this.field = viewCreator( this, viewUid, statusUid );
-
-		/**
-		 * The text of the label.
-		 *
-		 * @observable
-		 * @member {String} #label
-		 */
-		this.set( 'label' );
-
-		/**
-		 * Controls whether the component is in read-only mode.
-		 *
-		 * @observable
-		 * @member {Boolean} #isEnabled
-		 */
-		this.set( 'isEnabled', true );
-
-		/**
-		 * The validation error text. When set, it will be displayed
-		 * next to the {@link #field} as a typical validation error message.
-		 * Set it to `null` to hide the message.
-		 *
-		 * **Note:** Setting this property to anything but `null` will automatically
-		 * make the `hasError` of the {@link #field} `true`.
-		 *
-		 * @observable
-		 * @member {String|null} #errorText
-		 */
-		this.set( 'errorText', null );
-
-		/**
-		 * The additional information text displayed next to the {@link #field} which can
-		 * be used to inform the user about its purpose, provide help or hints.
-		 *
-		 * Set it to `null` to hide the message.
-		 *
-		 * **Note:** This text will be displayed in the same place as {@link #errorText} but the
-		 * latter always takes precedence: if the {@link #errorText} is set, it replaces
-		 * {@link #infoText}.
-		 *
-		 * @observable
-		 * @member {String|null} #infoText
-		 */
-		this.set( 'infoText', null );
-
-		/**
-		 * (Optional) The additional CSS class set on the dropdown {@link #element}.
-		 *
-		 * @observable
-		 * @member {String} #class
-		 */
-		this.set( 'class' );
-
-		/**
-		 * The label view instance that describes the entire view.
-		 *
-		 * @member {module:ui/label/labelview~LabelView} #labelView
-		 */
-		this.labelView = this._createLabelView( viewUid );
-
-		/**
-		 * The status view for the {@link #field}. It displays {@link #errorText} and
-		 * {@link #infoText}.
-		 *
-		 * @member {module:ui/view~View} #statusView
-		 */
-		this.statusView = this._createStatusView( statusUid );
-
-		/**
-		 * The combined status text made of {@link #errorText} and {@link #infoText}.
-		 * Note that when present, {@link #errorText} always takes precedence in the
-		 * status.
-		 *
-		 * @see #errorText
-		 * @see #infoText
-		 * @see #statusView
-		 * @private
-		 * @observable
-		 * @member {String|null} #_statusText
-		 */
-		this.bind( '_statusText' ).to(
-			this, 'errorText',
-			this, 'infoText',
-			( errorText, infoText ) => errorText || infoText
-		);
-
-		const bind = this.bindTemplate;
-
-		this.setTemplate( {
-			tag: 'div',
-			attributes: {
-				class: [
-					'ck',
-					'ck-labeled-view',
-					bind.to( 'class' ),
-					bind.if( 'isEnabled', 'ck-disabled', value => !value )
-				]
-			},
-			children: [
-				this.labelView,
-				this.field,
-				this.statusView
-			]
-		} );
-	}
-
-	/**
-	 * Creates label view class instance and bind with view.
-	 *
-	 * @private
-	 * @param {String} id Unique id to set as labelView#for attribute.
-	 * @returns {module:ui/label/labelview~LabelView}
-	 */
-	_createLabelView( id ) {
-		const labelView = new LabelView( this.locale );
-
-		labelView.for = id;
-		labelView.bind( 'text' ).to( this, 'label' );
-
-		return labelView;
-	}
-
-	/**
-	 * Creates the status view instance. It displays {@link #errorText} and {@link #infoText}
-	 * next to the {@link #field}. See {@link #_statusText}.
-	 *
-	 * @private
-	 * @param {String} statusUid Unique id of the status, shared with the {@link #field view's}
-	 * `aria-describedby` attribute.
-	 * @returns {module:ui/view~View}
-	 */
-	_createStatusView( statusUid ) {
-		const statusView = new View( this.locale );
-		const bind = this.bindTemplate;
-
-		statusView.setTemplate( {
-			tag: 'div',
-			attributes: {
-				class: [
-					'ck',
-					'ck-labeled-view__status',
-					bind.if( 'errorText', 'ck-labeled-view__status_error' ),
-					bind.if( '_statusText', 'ck-hidden', value => !value )
-				],
-				id: statusUid,
-				role: bind.if( 'errorText', 'alert' )
-			},
-			children: [
-				{
-					text: bind.to( '_statusText' )
-				}
-			]
-		} );
-
-		return statusView;
-	}
-
-	/**
-	 * Focuses the {@link #field}.
-	 */
-	focus() {
-		this.field.focus();
-	}
-}

+ 0 - 92
packages/ckeditor5-ui/src/labeledfieldview/utils.js

@@ -1,92 +0,0 @@
-/**
- * @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 ui/labeledfieldview/utils
- */
-
-import InputTextView from '../inputtext/inputtextview';
-import { createDropdown } from '../dropdown/utils';
-
-/**
- * A helper for creating labeled inputs.
- *
- * It creates an instance of a {@link module:ui/inputtext/inputtextview~InputTextView input text} that is
- * logically related to a {@link module:ui/labeledfieldview/labeledfieldview~LabeledFieldView labeled view} in DOM.
- *
- * The helper does the following:
- *
- * * It sets input's `id` and `ariaDescribedById` attributes.
- * * It binds input's `isReadOnly` to the labeled view.
- * * It binds input's `hasError` to the labeled view.
- * * It enables a logic that cleans up the error when user starts typing in the input..
- *
- * Usage:
- *
- *		const labeledInputView = new LabeledFieldView( locale, createLabeledDropdown );
- *		console.log( labeledInputView.view ); // An input instance.
- *
- * @param {module:ui/labeledfieldview/labeledfieldview~LabeledFieldView} labeledFieldView The instance of the labeled view.
- * @param {String} viewUid An UID string that allows DOM logical connection between the
- * {@link module:ui/labeledfieldview/labeledfieldview~LabeledFieldView#labelView labeled view's label} and the input.
- * @param {String} statusUid An UID string that allows DOM logical connection between the
- * {@link module:ui/labeledfieldview/labeledfieldview~LabeledFieldView#statusView labeled view's status} and the input.
- * @returns {module:ui/inputtext/inputtextview~InputTextView} The input text view instance.
- */
-export function createLabeledInputText( labeledFieldView, viewUid, statusUid ) {
-	const inputView = new InputTextView( labeledFieldView.locale );
-
-	inputView.set( {
-		id: viewUid,
-		ariaDescribedById: statusUid
-	} );
-
-	inputView.bind( 'isReadOnly' ).to( labeledFieldView, 'isEnabled', value => !value );
-	inputView.bind( 'hasError' ).to( labeledFieldView, 'errorText', value => !!value );
-
-	inputView.on( 'input', () => {
-		// UX: Make the error text disappear and disable the error indicator as the user
-		// starts fixing the errors.
-		labeledFieldView.errorText = null;
-	} );
-
-	return inputView;
-}
-
-/**
- * A helper for creating labeled dropdowns.
- *
- * It creates an instance of a {@link module:ui/dropdown/dropdownview~DropdownView dropdown} that is
- * logically related to a {@link module:ui/labeledfieldview/labeledfieldview~LabeledFieldView labeled view}.
- *
- * The helper does the following:
- *
- * * It sets dropdown's `id` and `ariaDescribedById` attributes.
- * * It binds input's `isEnabled` to the labeled view.
- *
- * Usage:
- *
- *		const labeledInputView = new LabeledFieldView( locale, createLabeledDropdown );
- *		console.log( labeledInputView.view ); // A dropdown instance.
- *
- * @param {module:ui/labeledfieldview/labeledfieldview~LabeledFieldView} labeledFieldView The instance of the labeled view.
- * @param {String} viewUid An UID string that allows DOM logical connection between the
- * {@link module:ui/labeledfieldview/labeledfieldview~LabeledFieldView#labelView labeled view label} and the dropdown.
- * @param {String} statusUid An UID string that allows DOM logical connection between the
- * {@link module:ui/labeledfieldview/labeledfieldview~LabeledFieldView#statusView labeled view status} and the dropdown.
- * @returns {module:ui/dropdown/dropdownview~DropdownView} The dropdown view instance.
- */
-export function createLabeledDropdown( labeledFieldView, viewUid, statusUid ) {
-	const dropdownView = createDropdown( labeledFieldView.locale );
-
-	dropdownView.set( {
-		id: viewUid,
-		ariaDescribedById: statusUid
-	} );
-
-	dropdownView.bind( 'isEnabled' ).to( labeledFieldView );
-
-	return dropdownView;
-}

+ 0 - 166
packages/ckeditor5-ui/tests/labeledfieldview/labeledfieldview.js

@@ -1,166 +0,0 @@
-/**
- * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
-
-import View from '../../src/view';
-import LabeledFieldView from '../../src/labeledfieldview/labeledfieldview';
-import LabelView from '../../src/label/labelview';
-
-describe( 'LabeledFieldView', () => {
-	const locale = {};
-
-	let labeledFieldView, view;
-
-	beforeEach( () => {
-		labeledFieldView = new LabeledFieldView( locale, ( labeledFieldView, viewUid, statusUid ) => {
-			view = new View( locale );
-			view.setTemplate( { tag: 'div' } );
-			view.focus = () => {};
-			view.viewUid = viewUid;
-			view.statusUid = statusUid;
-
-			return view;
-		} );
-
-		labeledFieldView.render();
-	} );
-
-	afterEach( () => {
-		labeledFieldView.destroy();
-	} );
-
-	describe( 'constructor()', () => {
-		it( 'should set labeledFieldView#locale', () => {
-			expect( labeledFieldView.locale ).to.deep.equal( locale );
-		} );
-
-		it( 'should set labeledFieldView#field', () => {
-			expect( labeledFieldView.field ).to.equal( view );
-		} );
-
-		it( 'should set labeledFieldView#label', () => {
-			expect( labeledFieldView.label ).to.be.undefined;
-		} );
-
-		it( 'should set labeledFieldView#isEnabled', () => {
-			expect( labeledFieldView.isEnabled ).to.be.true;
-		} );
-
-		it( 'should set labeledFieldView#errorText', () => {
-			expect( labeledFieldView.errorText ).to.be.null;
-		} );
-
-		it( 'should set labeledFieldView#infoText', () => {
-			expect( labeledFieldView.infoText ).to.be.null;
-		} );
-
-		it( 'should set labeledFieldView#class', () => {
-			expect( labeledFieldView.class ).to.be.undefined;
-		} );
-
-		it( 'should create labeledFieldView#labelView', () => {
-			expect( labeledFieldView.labelView ).to.instanceOf( LabelView );
-		} );
-
-		it( 'should create labeledFieldView#statusView', () => {
-			expect( labeledFieldView.statusView ).to.instanceOf( View );
-
-			expect( labeledFieldView.statusView.element.tagName ).to.equal( 'DIV' );
-			expect( labeledFieldView.statusView.element.classList.contains( 'ck' ) ).to.be.true;
-			expect( labeledFieldView.statusView.element.classList.contains( 'ck-labeled-view__status' ) ).to.be.true;
-		} );
-
-		it( 'should allow pairing #view and #labelView by unique id', () => {
-			expect( labeledFieldView.labelView.for ).to.equal( view.viewUid );
-		} );
-
-		it( 'should allow pairing #view and #statusView by unique id', () => {
-			expect( view.statusUid ).to.equal( labeledFieldView.statusView.element.id );
-		} );
-	} );
-
-	describe( 'template', () => {
-		it( 'should have the CSS class', () => {
-			expect( labeledFieldView.element.classList.contains( 'ck' ) ).to.be.true;
-			expect( labeledFieldView.element.classList.contains( 'ck-labeled-view' ) ).to.be.true;
-		} );
-
-		it( 'should have #labeledFieldView', () => {
-			expect( labeledFieldView.template.children[ 0 ] ).to.equal( labeledFieldView.labelView );
-		} );
-
-		it( 'should have #view', () => {
-			expect( labeledFieldView.template.children[ 1 ] ).to.equal( view );
-		} );
-
-		it( 'should have the #statusView container', () => {
-			expect( labeledFieldView.template.children[ 2 ] ).to.equal( labeledFieldView.statusView );
-		} );
-
-		describe( 'DOM bindings', () => {
-			describe( 'class', () => {
-				it( 'should react on labeledFieldView#class', () => {
-					labeledFieldView.class = 'foo';
-					expect( labeledFieldView.element.classList.contains( 'foo' ) ).to.be.true;
-
-					labeledFieldView.class = 'bar';
-					expect( labeledFieldView.element.classList.contains( 'foo' ) ).to.be.false;
-					expect( labeledFieldView.element.classList.contains( 'bar' ) ).to.be.true;
-				} );
-			} );
-
-			describe( 'status container', () => {
-				it( 'should react on labeledFieldView#errorText', () => {
-					const statusElement = labeledFieldView.statusView.element;
-
-					labeledFieldView.errorText = '';
-					expect( statusElement.classList.contains( 'ck-hidden' ) ).to.be.true;
-					expect( statusElement.classList.contains( 'ck-labeled-view__status_error' ) ).to.be.false;
-					expect( statusElement.hasAttribute( 'role' ) ).to.be.false;
-					expect( statusElement.innerHTML ).to.equal( '' );
-
-					labeledFieldView.errorText = 'foo';
-					expect( statusElement.classList.contains( 'ck-hidden' ) ).to.be.false;
-					expect( statusElement.classList.contains( 'ck-labeled-view__status_error' ) ).to.be.true;
-					expect( statusElement.getAttribute( 'role' ) ).to.equal( 'alert' );
-					expect( statusElement.innerHTML ).to.equal( 'foo' );
-				} );
-
-				it( 'should react on labeledFieldView#infoText', () => {
-					const statusElement = labeledFieldView.statusView.element;
-
-					labeledFieldView.infoText = '';
-					expect( statusElement.classList.contains( 'ck-hidden' ) ).to.be.true;
-					expect( statusElement.classList.contains( 'ck-labeled-view__status_error' ) ).to.be.false;
-					expect( statusElement.hasAttribute( 'role' ) ).to.be.false;
-					expect( statusElement.innerHTML ).to.equal( '' );
-
-					labeledFieldView.infoText = 'foo';
-					expect( statusElement.classList.contains( 'ck-hidden' ) ).to.be.false;
-					expect( statusElement.classList.contains( 'ck-labeled-view__status_error' ) ).to.be.false;
-					expect( statusElement.hasAttribute( 'role' ) ).to.be.false;
-					expect( statusElement.innerHTML ).to.equal( 'foo' );
-				} );
-			} );
-		} );
-	} );
-
-	describe( 'binding', () => {
-		it( 'should bind labeledFieldView#label to labeledFieldView.labelView#label', () => {
-			labeledFieldView.label = 'Foo bar';
-
-			expect( labeledFieldView.labelView.text ).to.equal( 'Foo bar' );
-		} );
-	} );
-
-	describe( 'focus()', () => {
-		it( 'should focus the #view in DOM', () => {
-			const spy = sinon.spy( view, 'focus' );
-
-			labeledFieldView.focus();
-
-			sinon.assert.calledOnce( spy );
-		} );
-	} );
-} );

+ 0 - 108
packages/ckeditor5-ui/tests/labeledfieldview/utils.js

@@ -1,108 +0,0 @@
-/**
- * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
-
-import {
-	createLabeledInputText,
-	createLabeledDropdown
-} from '../../src/labeledfieldview/utils';
-
-import LabeledFieldView from '../../src/labeledfieldview/labeledfieldview';
-import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
-import InputTextView from '../../src/inputtext/inputtextview';
-import DropdownView from '../../src/dropdown/dropdownview';
-
-describe( 'LabeledFieldView utils', () => {
-	let locale;
-
-	testUtils.createSinonSandbox();
-
-	beforeEach( () => {
-		locale = { t: val => val };
-	} );
-
-	describe( 'createLabeledInputText()', () => {
-		let labeledFieldView;
-
-		beforeEach( () => {
-			labeledFieldView = new LabeledFieldView( locale, createLabeledInputText );
-		} );
-
-		afterEach( () => {
-			labeledFieldView.destroy();
-		} );
-
-		it( 'should create an InputTextView instance', () => {
-			expect( labeledFieldView.field ).to.be.instanceOf( InputTextView );
-		} );
-
-		it( 'should pass the Locale to the input', () => {
-			expect( labeledFieldView.field.locale ).to.equal( locale );
-		} );
-
-		it( 'should set input #id and #ariaDescribedById', () => {
-			labeledFieldView.render();
-
-			expect( labeledFieldView.field.id ).to.equal( labeledFieldView.labelView.for );
-			expect( labeledFieldView.field.ariaDescribedById ).to.equal( labeledFieldView.statusView.element.id );
-		} );
-
-		it( 'should bind input\'s #isReadOnly to LabeledFieldView#isEnabled', () => {
-			labeledFieldView.isEnabled = true;
-			expect( labeledFieldView.field.isReadOnly ).to.be.false;
-
-			labeledFieldView.isEnabled = false;
-			expect( labeledFieldView.field.isReadOnly ).to.be.true;
-		} );
-
-		it( 'should bind input\'s #hasError to LabeledFieldView#errorText', () => {
-			labeledFieldView.errorText = 'some error';
-			expect( labeledFieldView.field.hasError ).to.be.true;
-
-			labeledFieldView.errorText = null;
-			expect( labeledFieldView.field.hasError ).to.be.false;
-		} );
-
-		it( 'should clean LabeledFieldView#errorText upon input\'s DOM "update" event', () => {
-			labeledFieldView.errorText = 'some error';
-			labeledFieldView.field.fire( 'input' );
-			expect( labeledFieldView.errorText ).to.be.null;
-		} );
-	} );
-
-	describe( 'createLabeledDropdown', () => {
-		let labeledFieldView;
-
-		beforeEach( () => {
-			labeledFieldView = new LabeledFieldView( locale, createLabeledDropdown );
-		} );
-
-		afterEach( () => {
-			labeledFieldView.destroy();
-		} );
-
-		it( 'should create a DropdownView', () => {
-			expect( labeledFieldView.field ).to.be.instanceOf( DropdownView );
-		} );
-
-		it( 'should pass the Locale to the dropdown', () => {
-			expect( labeledFieldView.field.locale ).to.equal( locale );
-		} );
-
-		it( 'should set dropdown\'s #id and #ariaDescribedById', () => {
-			labeledFieldView.render();
-
-			expect( labeledFieldView.field.id ).to.equal( labeledFieldView.labelView.for );
-			expect( labeledFieldView.field.ariaDescribedById ).to.equal( labeledFieldView.statusView.element.id );
-		} );
-
-		it( 'should bind dropdown\'s #isEnabled to the labeled view', () => {
-			labeledFieldView.isEnabled = true;
-			expect( labeledFieldView.field.isEnabled ).to.be.true;
-
-			labeledFieldView.isEnabled = false;
-			expect( labeledFieldView.field.isEnabled ).to.be.false;
-		} );
-	} );
-} );

+ 0 - 10
packages/ckeditor5-ui/theme/components/labeledfieldview/labeledfieldview.css

@@ -1,10 +0,0 @@
-/*
- * 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.
- */