Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@vaadin/vaadin-control-state-mixin

Package Overview
Dependencies
Maintainers
18
Versions
63
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vaadin/vaadin-control-state-mixin - npm Package Compare versions

Comparing version 2.2.4 to 20.0.0-alpha1

33

package.json
{
"name": "@vaadin/vaadin-control-state-mixin",
"version": "20.0.0-alpha1",
"description": "vaadin-control-state-mixin",
"main": "vaadin-control-state-mixin.js",
"module": "vaadin-control-state-mixin.js",
"repository": "vaadin/vaadin-control-state-mixin",
"keywords": [

@@ -10,7 +15,2 @@ "Vaadin",

],
"repository": "vaadin/vaadin-control-state-mixin",
"homepage": "https://vaadin.com/elements",
"name": "@vaadin/vaadin-control-state-mixin",
"version": "2.2.4",
"main": "vaadin-control-state-mixin.js",
"author": "Vaadin Ltd",

@@ -21,2 +21,3 @@ "license": "Apache-2.0",

},
"homepage": "https://vaadin.com/elements",
"files": [

@@ -26,21 +27,15 @@ "vaadin-*.d.ts",

],
"resolutions": {
"es-abstract": "1.17.6",
"@types/doctrine": "0.0.3",
"inherits": "2.0.3",
"samsam": "1.1.3",
"supports-color": "3.1.2",
"type-detect": "1.0.0"
},
"dependencies": {
"@polymer/polymer": "^3.0.0"
},
"scripts": {
"generate-typings": "gen-typescript-declarations --outDir . --verify"
},
"devDependencies": {
"@esm-bundle/chai": "^4.1.5",
"@open-wc/testing-helpers": "^1.8.12",
"@polymer/iron-test-helpers": "^3.0.0",
"wct-browser-legacy": "^1.0.1",
"@webcomponents/webcomponentsjs": "^2.0.0"
}
"sinon": "^9.2.4"
},
"publishConfig": {
"access": "public"
},
"gitHead": "93c8e0ec03a178c6d74261261f985bd07f7cc79c"
}

@@ -0,9 +1,9 @@

# vaadin-control-state-mixin
A mixin which adds `focused` and `focus-ring` states to an element.
[![npm version](https://badgen.net/npm/v/@vaadin/vaadin-control-state-mixin)](https://www.npmjs.com/package/@vaadin/vaadin-control-state-mixin)
[![Bower version](https://badgen.net/github/release/vaadin/vaadin-control-state-mixin)](https://github.com/vaadin/vaadin-control-state-mixin/releases)
[![Build Status](https://travis-ci.org/vaadin/vaadin-control-state-mixin.svg?branch=master)](https://travis-ci.org/vaadin/vaadin-control-state-mixin)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/vaadin/web-components?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![Discord](https://img.shields.io/discord/732335336448852018?label=discord)](https://discord.gg/PHmkCKC)
# vaadin-control-state-mixin
A mixin which adds `focused` and `focus-ring` states to an element.
## Running tests in browser

@@ -13,23 +13,17 @@

1. Make sure you have [npm](https://www.npmjs.com/) and [Bower](https://bower.io) installed.
1. Make sure you have [npm](https://www.npmjs.com/).
1. When in the `vaadin-control-state-mixin` directory, run `npm install` and then `bower install` to install dependencies.
1. When in the `vaadin-control-state-mixin` directory, run `npm install` to install dependencies.
1. Make sure you have [polymer-cli](https://www.npmjs.com/package/polymer-cli) installed globally: `npm i -g polymer-cli`.
1. Run `npm test` to start the tests in Chrome.
1. Run `npm start`.
1. Navigate to http://127.0.0.1:3000/components/vaadin-control-state-mixin/test/index.html
## Debugging tests in browser
1. Run `npm run debug`, then choose manual mode (M) and open the link in browser.
## Running tests from the command line
1. Install [web-component-tester](https://www.npmjs.com/package/web-component-tester): `npm install -g web-component-tester`
1. When in the `vaadin-control-state-mixin` directory, run `wct` or `npm test`
## Following the coding style
We are using [ESLint](http://eslint.org/) for linting JavaScript code. You can check if your code is following our standards by running `npm run lint`, which will automatically lint all `.js` files as well as JavaScript snippets inside `.html` files.
We are using [ESLint](http://eslint.org/) for linting JavaScript code. You can check if your code is following our standards by running `npm run lint`, which will automatically lint all `.js` files.

@@ -36,0 +30,0 @@

/**
* DO NOT EDIT
*
* This file was automatically generated by
* https://github.com/Polymer/tools/tree/master/packages/gen-typescript-declarations
*
* To modify these typings, edit the source file(s):
* vaadin-control-state-mixin.js
*/
// tslint:disable:variable-name Describing an API that's defined elsewhere.
// tslint:disable:no-any describes the API as best we are able today
export {ControlStateMixin};
/**
* Polymer.IronControlState is not a proper 2.0 class, also, its tabindex

@@ -25,9 +8,6 @@ * implementation fails in the shadow dom, so we have this for vaadin elements.

interface ControlStateMixinConstructor {
new(...args: any[]): ControlStateMixin;
new (...args: any[]): ControlStateMixin;
}
export {ControlStateMixinConstructor};
interface ControlStateMixin {
/**

@@ -37,3 +17,3 @@ * Any element extending this mixin is required to implement this getter.

*/
readonly focusElement: Element|null|undefined;
readonly focusElement: Element | null | undefined;

@@ -43,3 +23,3 @@ /**

*/
autofocus: boolean|null|undefined;
autofocus: boolean | null | undefined;

@@ -49,8 +29,11 @@ /**

*/
disabled: boolean|null|undefined;
ready(): void;
disconnectedCallback(): void;
disabled: boolean | null | undefined;
_setFocused(focused: boolean): void;
_focus(): void;
click(): void;
}
export { ControlStateMixinConstructor, ControlStateMixin };
/**
@license
Copyright (c) 2017 Vaadin Ltd.
This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
* @license
* Copyright (c) 2021 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
// We consider the keyboard to be active if the window has received a keydown

@@ -17,3 +18,3 @@ // event since the last mousedown event.

},
{capture: true}
{ capture: true }
);

@@ -26,3 +27,3 @@

},
{capture: true}
{ capture: true }
);

@@ -36,28 +37,22 @@

*/
const TabIndexMixin = superClass => class VaadinTabIndexMixin extends superClass {
static get properties() {
var properties = {
/**
* Internal property needed to listen to `tabindex` attribute changes.
*
* For changing the tabindex of this component use the native `tabIndex` property.
* @private
*/
tabindex: {
type: Number,
value: 0,
reflectToAttribute: true,
observer: '_tabindexChanged'
}
};
if (window.ShadyDOM) {
// ShadyDOM browsers need the `tabIndex` in order to notify when the user changes it programmatically.
properties['tabIndex'] = properties.tabindex;
const TabIndexMixin = (superClass) =>
class VaadinTabIndexMixin extends superClass {
static get properties() {
return {
/**
* Internal property needed to listen to `tabindex` attribute changes.
*
* For changing the tabindex of this component use the native `tabIndex` property.
* @private
*/
tabindex: {
type: Number,
value: 0,
reflectToAttribute: true,
observer: '_tabindexChanged'
}
};
}
};
return properties;
}
};
/**

@@ -68,77 +63,63 @@ * Polymer.IronControlState is not a proper 2.0 class, also, its tabindex

*/
export const ControlStateMixin = superClass => class VaadinControlStateMixin extends TabIndexMixin(superClass) {
static get properties() {
return {
/**
* Specify that this control should have input focus when the page loads.
*/
autofocus: {
type: Boolean
},
export const ControlStateMixin = (superClass) =>
class VaadinControlStateMixin extends TabIndexMixin(superClass) {
static get properties() {
return {
/**
* Specify that this control should have input focus when the page loads.
*/
autofocus: {
type: Boolean
},
/**
* Stores the previous value of tabindex attribute of the disabled element
* @private
*/
_previousTabIndex: {
type: Number
},
/**
* Stores the previous value of tabindex attribute of the disabled element
* @private
*/
_previousTabIndex: {
type: Number
},
/**
* If true, the user cannot interact with this element.
*/
disabled: {
type: Boolean,
observer: '_disabledChanged',
reflectToAttribute: true
},
/**
* If true, the user cannot interact with this element.
*/
disabled: {
type: Boolean,
observer: '_disabledChanged',
reflectToAttribute: true
},
/**
* @private
*/
_isShiftTabbing: {
type: Boolean
}
};
}
/**
* @private
*/
_isShiftTabbing: {
type: Boolean
}
};
}
/**
* @protected
*/
ready() {
this.addEventListener('focusin', e => {
if (e.composedPath()[0] === this) {
// Only focus if the focus is received from somewhere outside
if (!this.contains(e.relatedTarget)) {
this._focus();
/**
* @protected
*/
ready() {
this.addEventListener('focusin', (e) => {
if (e.composedPath()[0] === this) {
// Only focus if the focus is received from somewhere outside
if (!this.contains(e.relatedTarget)) {
this._focus();
}
} else if (e.composedPath().indexOf(this.focusElement) !== -1 && !this.disabled) {
this._setFocused(true);
}
} else if (e.composedPath().indexOf(this.focusElement) !== -1 && !this.disabled) {
this._setFocused(true);
}
});
this.addEventListener('focusout', e => this._setFocused(false));
});
this.addEventListener('focusout', () => this._setFocused(false));
// In super.ready() other 'focusin' and 'focusout' listeners might be
// added, so we call it after our own ones to ensure they execute first.
// Issue to watch out: when incorrect, <vaadin-combo-box> refocuses the
// input field on iOS after “Done” is pressed.
super.ready();
// In super.ready() other 'focusin' and 'focusout' listeners might be
// added, so we call it after our own ones to ensure they execute first.
// Issue to watch out: when incorrect, <vaadin-combo-box> refocuses the
// input field on iOS after “Done” is pressed.
super.ready();
// This fixes the bug in Firefox 61 (https://bugzilla.mozilla.org/show_bug.cgi?id=1472887)
// where focusout event does not go out of shady DOM because composed property in the event is not true
const ensureEventComposed = e => {
if (!e.composed) {
e.target.dispatchEvent(new CustomEvent(e.type, {
bubbles: true,
composed: true,
cancelable: false
}));
}
};
this.shadowRoot.addEventListener('focusin', ensureEventComposed);
this.shadowRoot.addEventListener('focusout', ensureEventComposed);
this.addEventListener('keydown', e => {
if (!e.defaultPrevented && e.keyCode === 9) {
if (e.shiftKey) {
this.addEventListener('keydown', (e) => {
if (!e.defaultPrevented && e.keyCode === 9 && e.shiftKey) {
// Flag is checked in _focus event handler.

@@ -149,167 +130,141 @@ this._isShiftTabbing = true;

// Event handling in IE is asynchronous and the flag is removed asynchronously as well
setTimeout(() => this._isShiftTabbing = false, 0);
} else {
// Workaround for FF63-65 bug that causes the focus to get lost when
// blurring a slotted component with focusable shadow root content
// https://bugzilla.mozilla.org/show_bug.cgi?id=1528686
// TODO: Remove when safe
const firefox = window.navigator.userAgent.match(/Firefox\/(\d\d\.\d)/);
if (firefox
&& parseFloat(firefox[1]) >= 63
&& parseFloat(firefox[1]) < 66
&& this.parentNode
&& this.nextSibling) {
const fakeTarget = document.createElement('input');
fakeTarget.style.position = 'absolute';
fakeTarget.style.opacity = '0';
fakeTarget.tabIndex = this.tabIndex;
this.parentNode.insertBefore(fakeTarget, this.nextSibling);
fakeTarget.focus();
fakeTarget.addEventListener('focusout', () => this.parentNode.removeChild(fakeTarget));
}
setTimeout(() => (this._isShiftTabbing = false), 0);
}
});
if (this.autofocus && !this.disabled) {
window.requestAnimationFrame(() => {
this._focus();
this._setFocused(true);
this.setAttribute('focus-ring', '');
});
}
});
if (this.autofocus && !this.disabled) {
window.requestAnimationFrame(() => {
this._focus();
this._setFocused(true);
this.setAttribute('focus-ring', '');
});
}
}
/**
* @protected
*/
disconnectedCallback() {
super.disconnectedCallback();
/**
* @protected
*/
disconnectedCallback() {
super.disconnectedCallback();
// in non-Chrome browsers, blur does not fire on the element when it is disconnected.
// reproducible in `<vaadin-date-picker>` when closing on `Cancel` or `Today` click.
if (this.hasAttribute('focused')) {
this._setFocused(false);
// in non-Chrome browsers, blur does not fire on the element when it is disconnected.
// reproducible in `<vaadin-date-picker>` when closing on `Cancel` or `Today` click.
if (this.hasAttribute('focused')) {
this._setFocused(false);
}
}
}
/**
* @param {boolean} focused
* @protected
*/
_setFocused(focused) {
if (focused) {
this.setAttribute('focused', '');
} else {
this.removeAttribute('focused');
}
/**
* @param {boolean} focused
* @protected
*/
_setFocused(focused) {
if (focused) {
this.setAttribute('focused', '');
} else {
this.removeAttribute('focused');
}
// focus-ring is true when the element was focused from the keyboard.
// Focus Ring [A11ycasts]: https://youtu.be/ilj2P5-5CjI
if (focused && keyboardActive) {
this.setAttribute('focus-ring', '');
} else {
this.removeAttribute('focus-ring');
// focus-ring is true when the element was focused from the keyboard.
// Focus Ring [A11ycasts]: https://youtu.be/ilj2P5-5CjI
if (focused && keyboardActive) {
this.setAttribute('focus-ring', '');
} else {
this.removeAttribute('focus-ring');
}
}
}
/**
* Any element extending this mixin is required to implement this getter.
* It returns the actual focusable element in the component.
* @return {Element | null | undefined}
*/
get focusElement() {
window.console.warn(`Please implement the 'focusElement' property in <${this.localName}>`);
return this;
}
/**
* @protected
*/
_focus() {
if (!this.focusElement || this._isShiftTabbing) {
return;
/**
* Any element extending this mixin is required to implement this getter.
* It returns the actual focusable element in the component.
* @return {Element | null | undefined}
*/
get focusElement() {
window.console.warn(`Please implement the 'focusElement' property in <${this.localName}>`);
return this;
}
this.focusElement.focus();
this._setFocused(true);
}
/**
* @protected
*/
_focus() {
if (!this.focusElement || this._isShiftTabbing) {
return;
}
/**
* Moving the focus from the host element causes firing of the blur event what leads to problems in IE.
* @private
*/
focus() {
if (!this.focusElement || this.disabled) {
return;
this.focusElement.focus();
this._setFocused(true);
}
this.focusElement.focus();
this._setFocused(true);
}
/**
* Moving the focus from the host element causes firing of the blur event what leads to problems in IE.
* @private
*/
focus() {
if (!this.focusElement || this.disabled) {
return;
}
/**
* Native bluring in the host element does nothing because it does not have the focus.
* In chrome it works, but not in FF.
* @private
*/
blur() {
if (!this.focusElement) {
return;
this.focusElement.focus();
this._setFocused(true);
}
this.focusElement.blur();
this._setFocused(false);
}
/**
* @param {boolean} disabled
* @private
*/
_disabledChanged(disabled) {
this.focusElement.disabled = disabled;
if (disabled) {
this.blur();
this._previousTabIndex = this.tabindex;
this.tabindex = -1;
this.setAttribute('aria-disabled', 'true');
} else {
if (typeof this._previousTabIndex !== 'undefined') {
this.tabindex = this._previousTabIndex;
/**
* Native bluring in the host element does nothing because it does not have the focus.
* In chrome it works, but not in FF.
* @private
*/
blur() {
if (!this.focusElement) {
return;
}
this.removeAttribute('aria-disabled');
this.focusElement.blur();
this._setFocused(false);
}
}
/**
* @param {number | null | undefined} tabindex
* @private
*/
_tabindexChanged(tabindex) {
if (tabindex !== undefined) {
this.focusElement.tabIndex = tabindex;
}
if (this.disabled && this.tabindex) {
// If tabindex attribute was changed while checkbox was disabled
if (this.tabindex !== -1) {
/**
* @param {boolean} disabled
* @private
*/
_disabledChanged(disabled) {
this.focusElement.disabled = disabled;
if (disabled) {
this.blur();
this._previousTabIndex = this.tabindex;
this.tabindex = -1;
this.setAttribute('aria-disabled', 'true');
} else {
if (typeof this._previousTabIndex !== 'undefined') {
this.tabindex = this._previousTabIndex;
}
this.removeAttribute('aria-disabled');
}
this.tabindex = tabindex = undefined;
}
if (window.ShadyDOM) {
this.setProperties({tabIndex: tabindex, tabindex: tabindex});
/**
* @param {number | null | undefined} tabindex
* @private
*/
_tabindexChanged(tabindex) {
if (tabindex !== undefined) {
this.focusElement.tabIndex = tabindex;
}
if (this.disabled && this.tabindex) {
// If tabindex attribute was changed while checkbox was disabled
if (this.tabindex !== -1) {
this._previousTabIndex = this.tabindex;
}
this.tabindex = tabindex = undefined;
}
}
}
/**
* @protected
*/
click() {
if (!this.disabled) {
super.click();
/**
* @protected
*/
click() {
if (!this.disabled) {
super.click();
}
}
}
};
};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc