From 28bdc7d5908a434179258d3b1fdfcb92338673bb Mon Sep 17 00:00:00 2001 From: mister-ben Date: Mon, 21 Mar 2022 17:21:26 +0100 Subject: [PATCH] feat: easier configuration of buttons and components via options (#7611) --- docs/guides/components.md | 31 ++++++++++++++++++++++++--- src/css/components/_control.scss | 8 ++++++- src/js/clickable-component.js | 14 +++++++++++- src/js/component.js | 9 +++++++- test/unit/clickable-component.test.js | 14 ++++++++++++ test/unit/component.test.js | 15 +++++++++++++ 6 files changed, 85 insertions(+), 6 deletions(-) diff --git a/docs/guides/components.md b/docs/guides/components.md index 2105a55f00..cd4c4cd741 100644 --- a/docs/guides/components.md +++ b/docs/guides/components.md @@ -63,9 +63,10 @@ console.log(button.el()); The above code will output ```html -
-
Button
-
+ ``` Adding the new button to the player @@ -79,6 +80,30 @@ console.log(button.el()); // will have the same html result as the previous example ``` +The text of the button can be set as an option: + +```js +const myButton = player.addChild('button', {controlText: 'abc'}); +``` + +or set later: + +```js +myButton.controlText('def'); +``` + +The control text of a button is normally not visible (but present for screen readers) as the default buttons all display only an icon. The text can be displayed by adding a `vjs-text-visible` class to the button. This or any other class may be set as a setup option, or later by API. + +```js +const myButton = player.addChild('button', {className: 'vjs-text-visible'}); +``` + +or set later: + +```js +myButton.addClass('vjs-text-visible'); +``` + ## Component Children Again, refer to [the component API docs][api] for complete details on methods available for managing component structures. diff --git a/src/css/components/_control.scss b/src/css/components/_control.scss index 7d1fba42f1..4511768140 100644 --- a/src/css/components/_control.scss +++ b/src/css/components/_control.scss @@ -9,8 +9,14 @@ height: 100%; width: 4em; @include flex(none); +} +.video-js .vjs-control.vjs-visible-text { + width: auto; + padding-left: 1em; + padding-right: 1em; } + .vjs-button > .vjs-icon-placeholder:before { font-size: 1.8em; line-height: 1.67; @@ -30,7 +36,7 @@ } // Hide control text visually, but have it available for screenreaders -.video-js .vjs-control-text { +.video-js *:not(.vjs-visible-text) > .vjs-control-text { @include hide-visually; } diff --git a/src/js/clickable-component.js b/src/js/clickable-component.js index f9d5021bad..ba7410cae5 100644 --- a/src/js/clickable-component.js +++ b/src/js/clickable-component.js @@ -22,14 +22,26 @@ class ClickableComponent extends Component { * The `Player` that this class should be attached to. * * @param {Object} [options] - * The key/value store of player options. + * The key/value store of component options. * * @param {function} [options.clickHandler] * The function to call when the button is clicked / activated + * + * @param {string} [options.controlText] + * The text to set on the button + * + * @param {string} [options.className] + * A class or space separated list of classes to add the component + * */ constructor(player, options) { + super(player, options); + if (this.options_.controlText) { + this.controlText(this.options_.controlText); + } + this.handleMouseOver_ = (e) => this.handleMouseOver(e); this.handleMouseOut_ = (e) => this.handleMouseOut(e); this.handleClick_ = (e) => this.handleClick(e); diff --git a/src/js/component.js b/src/js/component.js index 9e9c28b023..728a51c77c 100644 --- a/src/js/component.js +++ b/src/js/component.js @@ -41,13 +41,16 @@ class Component { * The `Player` that this class should be attached to. * * @param {Object} [options] - * The key/value store of player options. + * The key/value store of component options. * * @param {Object[]} [options.children] * An array of children objects to intialize this component with. Children objects have * a name property that will be used if more than one component of the same type needs to be * added. * + * @param {string} [options.className] + * A class or space separated list of classes to add the component + * * @param {Component~ReadyCallback} [ready] * Function that gets called when the `Component` is ready. */ @@ -91,6 +94,10 @@ class Component { this.el_ = this.createEl(); } + if (options.className && this.el_) { + options.className.split(' ').forEach(c => this.addClass(c)); + } + // if evented is anything except false, we want to mixin in evented if (options.evented !== false) { // Make this an evented object and use `el_`, if available, as its event bus diff --git a/test/unit/clickable-component.test.js b/test/unit/clickable-component.test.js index fcb04fcc4f..12f5d67fb5 100644 --- a/test/unit/clickable-component.test.js +++ b/test/unit/clickable-component.test.js @@ -140,3 +140,17 @@ QUnit.test('language change should localize its text', function(assert) { testClickableComponent.dispose(); player.dispose(); }); + +QUnit.test('class and text should be settable from options', function(assert) { + const player = TestHelpers.makePlayer({}); + const testClickableComponent = new ClickableComponent(player, { + className: 'class1', + controlText: 'some text' + }); + + assert.equal(testClickableComponent.controlText(), 'some text', 'text was set'); + assert.ok(testClickableComponent.hasClass('class1'), 'class was set'); + + testClickableComponent.dispose(); + player.dispose(); +}); diff --git a/test/unit/component.test.js b/test/unit/component.test.js index 4865ad29a2..793ea73444 100644 --- a/test/unit/component.test.js +++ b/test/unit/component.test.js @@ -677,6 +677,21 @@ QUnit.test('should add and remove a CSS class', function(assert) { comp.dispose(); }); +QUnit.test('should add CSS class passed in options', function(assert) { + const comp = new Component(this.player, {className: 'class1 class2'}); + + assert.ok(comp.el().className.indexOf('class1') !== -1, 'first of multiple classes added'); + assert.ok(comp.el().className.indexOf('class2') !== -1, 'second of multiple classes added'); + + comp.dispose(); + + const comp2 = new Component(this.player, {className: 'class1'}); + + assert.ok(comp2.el().className.indexOf('class1') !== -1, 'singe class added'); + + comp2.dispose(); +}); + QUnit.test('should show and hide an element', function(assert) { const comp = new Component(this.player, {});