New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

material-input

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

material-input - npm Package Compare versions

Comparing version 0.0.2 to 0.0.3

docs/include.js/.npmignore

231

dist/material-input.js
'use strict';
// define attributes that are not supposed to be transferred

@@ -11,2 +12,4 @@ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var attributesExceptions = ['name', 'label', 'tabindex', 'placeholder', 'autofocus', 'autocomplete', 'autovalidate'];
var MaterialInput = function (_HTMLElement) {

@@ -24,14 +27,26 @@ _inherits(MaterialInput, _HTMLElement);

value: function createdCallback() {
this.createShadowRoot().innerHTML = '\n <style>\n :host{\n color: rgb(54,79,199);\n display: block;\n position: relative;\n }\n .material-input__container{\n width: inherit;\n display: block;\n position: relative;\n margin: .5em 0;\n }\n .material-input__input{\n box-sizing: border-box;\n position: relative;\n background-color: transparent;\n font-size: 1em;\n color: black;\n padding: 1em 1em 1em 10px;\n display: block;\n width: 100%;\n border: none;\n border-bottom: .1rem solid rgb(206,212,218);\n }\n .material-input__input:focus{\n outline: none;\n color: black;\n }\n /* placeholder and placeholder fade on focus */\n .material-input__input::-webkit-input-placeholder {\n color: rgb(134,142,150);\n opacity: 1;\n }\n .material-input__input:focus::-webkit-input-placeholder {\n opacity: .5;\n transition: opacity .35s ease;\n }\n .material-input__input::-moz-placeholder {\n color: rgb(134,142,150);\n opacity: 1;\n }\n .material-input__input:focus::-moz-placeholder {\n opacity: .5;\n transition: opacity .35s ease;\n }\n .material-input__input:-ms-input-placeholder {\n color: rgb(134,142,150);\n opacity: 1;\n }\n .material-input__input:-ms-input-placeholder {\n opacity: .5;\n transition: opacity .35s ease;\n }\n /* Labels */\n .material-input__label{\n color: rgb(134,142,150);\n font-size: inherit;\n pointer-events: none;\n position: absolute;\n left: 10px;\n bottom: 1em;\n transition: 0.2s ease all;\n }\n .material-input__container.is-empty .material-input__input[placeholder] ~ .material-input__label{\n color: black;\n }\n /* active state */\n .material-input__input:focus ~ .material-input__label,\n .material-input__container:not(.is-empty) .material-input__label,\n .material-input__container.label-always-floats .material-input__label{\n bottom: 3em;\n font-size: .75em;\n }\n .material-input__input:focus ~ .material-input__label,\n .material-input__container.is-empty .material-input__input[placeholder]:focus ~ .material-input__label{\n color: inherit;\n }\n .material-input__bar{\n position:relative;\n display:block;\n width:100%;\n }\n .material-input__bar::before, .material-input__bar::after {\n content:\'\';\n height:2px;\n width:0;\n bottom:0;\n position:absolute;\n background: currentColor;\n transition:0.2s ease all;\n }\n .material-input__bar::before {\n left:50%;\n }\n .material-input__bar::after {\n right:50%;\n }\n .material-input__input:focus ~ .material-input__bar:before, .material-input__input:focus ~ .material-input__bar:after{\n width:50%;\n }\n </style>\n <div class="material-input__container">\n <input class="material-input__input" tabindex="-1" />\n <label class="material-input__label"></label>\n <div class="material-input__bar"></div>\n <div class="material-input__message"></div>\n </div>\n ';
// initialize attributes
var value = '';
// set value of material-input
Object.defineProperty(this, "value", {
configurable: true,
enumerable: true,
get: function get() {
return value;
},
set: function set(newValue) {
value = !newValue ? '' : newValue;
this._value(value);
}
});
this.createShadowRoot().innerHTML = '\n <style>\n :host{\n display: block;\n position: relative;\n background: transparent;\n margin: .5em 0;\n }\n .material-input__container{\n width: inherit;\n display: block;\n position: relative;\n }\n .material-input__input{\n box-sizing: border-box;\n position: relative;\n background-color: transparent;\n font-size: 1em;\n color: var(--material-input-text-color, black);\n padding: 1em 1em 1em 10px;\n display: block;\n width: 100%;\n border: none;\n border-bottom: var(--material-input-line-height, 1px) solid var(--material-input-border-color, rgb(206,212,218));\n box-shadow: none;\n }\n .material-input__container.invalid .material-input__input{\n border-bottom-color: var(--material-input-invalid-color, rgb(224,49,49));\n }\n .material-input__container.valid .material-input__input{\n border-bottom-color: var(--material-input-valid-color, rgb(47,158,68));\n }\n .material-input__input:focus{\n outline: none;\n }\n /* placeholder and placeholder fade on focus */\n .material-input__input::-webkit-input-placeholder {\n color: var(--material-input-placeholder-color, rgb(134,142,150));\n opacity: 1;\n }\n .material-input__input:focus::-webkit-input-placeholder {\n opacity: .5;\n transition: opacity .35s ease;\n }\n .material-input__input::-moz-placeholder {\n color: var(--material-input-placeholder-color, rgb(134,142,150));\n opacity: 1;\n }\n .material-input__input:focus::-moz-placeholder {\n opacity: .5;\n transition: opacity .35s ease;\n }\n .material-input__input:-ms-input-placeholder {\n color: var(--material-input-placeholder-color, rgb(134,142,150));\n opacity: 1;\n }\n .material-input__input:-ms-input-placeholder {\n opacity: .5;\n transition: opacity .35s ease;\n }\n /* Labels */\n .material-input__label{\n color: rgb(134,142,150);\n font-size: inherit;\n pointer-events: none;\n position: absolute;\n left: 10px;\n bottom: 1em;\n transition: 0.2s ease all;\n }\n .material-input__container.no-animation .material-input__label,\n .material-input__container.label-always-floats .material-input__label{\n transition: 0s ease all;\n }\n .material-input__container.is-empty .material-input__input[placeholder] ~ .material-input__label{\n color: var(--material-input-text-color, black);\n }\n /* active state */\n .material-input__input:focus ~ .material-input__label,\n .material-input__container:not(.is-empty) .material-input__label,\n .material-input__container.label-always-floats .material-input__label{\n bottom: 3em;\n font-size: .75em;\n }\n .material-input__input:focus ~ .material-input__label,\n .material-input__container.is-empty .material-input__input[placeholder]:focus ~ .material-input__label{\n color: var(--material-input-highlight-color, rgb(54,79,199));\n }\n /* errror state */\n .material-input__container.invalid.label-always-floats .material-input__label,\n .material-input__container.invalid .material-input__input:focus ~ .material-input__label,\n .material-input__container.is-empty.invalid .material-input__input[placeholder]:focus ~ .material-input__label,\n .material-input__container.is-empty.invalid .material-input__input[placeholder] ~ .material-input__label{\n color: var(--material-input-invalid-color, rgb(224,49,49));\n }\n /* valid state */\n .material-input__container.valid.label-always-floats .material-input__label,\n .material-input__container.valid .material-input__input:focus ~ .material-input__label,\n .material-input__container.is-empty.valid .material-input__input[placeholder]:focus ~ .material-input__label,\n .material-input__container.is-empty.valid .material-input__input[placeholder] ~ .material-input__label{\n color: var(--material-input-valid-color, rgb(47,158,68));\n }\n /* bar */\n .material-input__bar{\n position:relative;\n display:block;\n width:100%;\n }\n .material-input__bar::before, .material-input__bar::after {\n content:\'\';\n height: var(--material-input-highlight-line-height, 2px);\n width:0;\n bottom:0;\n position:absolute;\n background: var(--material-input-highlight-color, rgb(54,79,199));\n transition:0.2s ease all;\n }\n .material-input__container.invalid .material-input__bar::before,\n .material-input__container.invalid .material-input__bar::after{\n background: var(--material-input-invalid-color, rgb(224,49,49));\n }\n .material-input__container.valid .material-input__bar::before,\n .material-input__container.valid .material-input__bar::after{\n background: var(--material-input-valid-color, rgb(47,158,68));\n }\n .material-input__bar::before {\n left:50%;\n }\n .material-input__bar::after {\n right:50%;\n }\n .material-input__input:focus ~ .material-input__bar:before, .material-input__input:focus ~ .material-input__bar:after{\n width:50%;\n }\n </style>\n <div class="material-input__container no-animation' + (this.value == '' ? ' is-empty' : '') + '">\n <input class="material-input__input" tabindex="-1" />\n <label class="material-input__label"></label>\n <div class="material-input__bar"></div>\n <div class="material-input__message"></div>\n </div>\n ';
// set tab index to make element focussable
this.setAttribute('tabindex', 0);
this.type = this.getAttribute('type') || 'text';
this.value = this.getAttribute('value') || null;
this.name = this.getAttribute('name') || 'material-input';
this.label = this.getAttribute('label') || null;
this.placeholder = this.getAttribute('placeholder') || null;
this.invalid = this.hasAttribute('invalid') || false;
this.valid = this.hasAttribute('valid') || false;
// add input field for form submisson
this.insertAdjacentHTML('afterend', '<input tabindex="-1" type="hidden" name="' + this.name + '"/>');
// shim shadowDOM styling
if (WebComponents !== undefined && WebComponents.flags.shadow === true) {
WebComponents.ShadowCSS.shimStyling(this.shadowRoot, 'material-input');
}
// add hidden input
this.insertAdjacentHTML('afterend', '<input tabindex="-1" style="pointer-events: none; margin:0; border: 0; height: 0; opacity: 0; position: absolute; top: ' + (this.offsetTop + this.offsetHeight) + 'px; left: ' + this.offsetLeft + 'px;" name="' + this.getAttribute('name') + '"/>');
this.$hiddenInput = document.querySelector('input[name=' + this.getAttribute('name') + ']');
// elements

@@ -42,14 +57,28 @@ this.$container = this.shadowRoot.querySelector('.material-input__container');

this.$message = this.$container.querySelector('.material-input__message');
this.$hiddenInput = document.querySelector('input[name=' + this.name + ']');
// add events
this.$hiddenInput.addEventListener('invalid', function () {
this._setValid(false);
}.bind(this));
this.$input.setAttribute('type', this.type);
this.$input.addEventListener('keydown', function () {
this.$input.addEventListener('blur', function () {
this._value(this.$input.value);
// check if is valid
if (this.$input.value !== '' && (this.$input.validity.valid === true || this.$input.validity.valid === false)) {
this._setValid(this.$input.validity.valid);
}
}.bind(this));
this.$input.addEventListener('blur', function () {
this.$input.addEventListener('keydown', function () {
this._value(this.$input.value);
}.bind(this));
if (this.hasAttribute('autovalidate') && String(this.getAttribute('autovalidate')) !== 'false') {
this.$input.addEventListener('keydown', function () {
// check if is valid
if (this.$input.value !== '' && this.$input.validity.valid === true) {
this._setValid(true);
}
}.bind(this));
}
this.addEventListener('focus', function () {

@@ -59,23 +88,140 @@ this.$input.focus();

if (this.value) {
this.$input.value = this.value;
this._transferAttributes();
this._setValue(this.getAttribute('value'));
this._setLabel(this.getAttribute('label'));
this._setPlaceholder(this.getAttribute('placeholder'));
this._setValid();
// remove no-animation loading class
setTimeout(function () {
this.$container.classList.remove('no-animation');
}.bind(this), 100);
}
/**
* when an attribute is changed
*/
}, {
key: 'attributeChangedCallback',
value: function attributeChangedCallback(attrName, oldVal, newVal) {
// define callbacks
var callbacks = {
'valid': this._setValid,
'value': this._setValue,
'label': this._setLabel,
'placeholder': this._setPlaceholder
};
// call callback if it exists
if (callbacks.hasOwnProperty(attrName)) {
callbacks[attrName].call(this, newVal, oldVal);
} else {
// if other attributes are updated, transfer updates to hidden input field
this._transferAttribute(attrName, newVal, attributesExceptions);
}
}
/**
* set the custom validity of the input
*/
this._value(this.value);
this._label(this.label);
this._placeholder(this.placeholder);
}, {
key: 'setCustomValidity',
value: function setCustomValidity(msg) {
this.$input.setCustomValidity(msg);
this.$hiddenInput.setCustomValidity(msg);
}
/**
* set value
*/
if (this.required) {
this.$hiddenInput.setAttribute('required', '');
}, {
key: '_setValue',
value: function _setValue(newValue) {
this.value = newValue;
}
/**
* set field to valid or invalid
*/
}, {
key: '_setValid',
value: function _setValid() {
var validity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
// valid is not set
if (!this.hasAttribute('valid')) {
this.valid = undefined;
this.$container.classList.remove('valid');
this.$container.classList.remove('invalid');
}
// valid is true
if (this.getAttribute('valid') === 'true' || this.getAttribute('valid') === true || validity === true || validity === 'true') {
this.valid = true;
this.$container.classList.add('valid');
this.$container.classList.remove('invalid');
}
// valid is false
if (this.getAttribute('valid') === 'false' || this.getAttribute('valid') === false || validity === false || validity === 'false') {
this.valid = false;
this.$container.classList.add('invalid');
this.$container.classList.remove('valid');
}
}
/**
* transfer attributes to input
*/
}, {
key: '_transferAttributes',
value: function _transferAttributes() {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = Object.keys(this.attributes)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var key = _step.value;
if (this.attributes.hasOwnProperty(key)) {
this._transferAttribute(this.attributes[key].name, this.attributes[key].value, attributesExceptions);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
/**
* transfer attribute to input
*/
}, {
key: '_transferAttribute',
value: function _transferAttribute(attrName, val, attributesExceptions) {
if (attributesExceptions.indexOf(attrName) === -1) {
this.$hiddenInput.setAttribute(attrName, val);
this.$input.setAttribute(attrName, val);
}
}
/**
* update value and toggle is-empty class
*/
}, {
key: '_value',
value: function _value(value) {
// set value of material-input
this.value = !value ? '' : value;
value: function _value(val) {
// set value of hidden input for form submission
this.$hiddenInput.value = this.value;
this.$hiddenInput.value = val;
this.$input.value = val;
// set state depending on value
this._toggle(this.$container, 'is-empty', this.value === '');
this._toggle(this.$container, 'is-empty', val === '');
}

@@ -87,17 +233,24 @@ /**

}, {
key: '_label',
value: function _label(label) {
this.$label.innerHTML = label;
this._toggle(this.$container, 'label-always-floats', this.placeholder !== null);
key: '_setLabel',
value: function _setLabel(label) {
if (label !== undefined && label !== null) {
return this.$label.innerHTML = label;
}
this.$label.innerHTML = '';
}
/**
* set placeholder and add label-always-floats class
*/
}, {
key: '_placeholder',
value: function _placeholder(placeholder) {
if (placeholder !== null) {
this.$input.placeholder = placeholder;
} else {
this.$input.removeAttribute('placeholder');
key: '_setPlaceholder',
value: function _setPlaceholder(placeholder) {
if (placeholder !== null && placeholder !== undefined) {
this.$input.setAttribute('placeholder', placeholder);
this.$container.classList.add('label-always-floats');
return;
}
this.$input.removeAttribute('placeholder');
this.$container.classList.remove('label-always-floats');
}
/**

@@ -104,0 +257,0 @@ * since classList.toggle with a second param is not supported in IE11 and below

8

package.json
{
"name": "material-input",
"version": "0.0.2",
"version": "0.0.3",
"description": "An easy drop-in material-input solution as a custom element",

@@ -10,3 +10,3 @@ "main": "src/material-input.js",

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "./node_modules/web-component-tester/bin/wct"
},

@@ -34,5 +34,7 @@ "repository": {

"gulp-babel": "^6.1.2",
"gulp-sourcemaps": "^1.6.0"
"gulp-sourcemaps": "^1.6.0",
"include.js": "^0.1.2",
"web-component-tester": "^4.3.5"
},
"dependencies": {}
}

@@ -12,5 +12,5 @@ # Material-input

Not released yet. Feel free to test it an contribute.
```bash
npm install --save material-input
```
# npm install --save material-input
```

@@ -26,4 +26,5 @@ You need the [webcomponents-lite polyfill](https://github.com/webcomponents/webcomponentsjs).

## Usage
Just drop the `<material-input>` element into you html and add your text.
Just drop the `<material-input>` element into you html `<form>` element and you are ready to go. A visually hidden `<input>` field will be created which syncs its values with the `<material-input>` to allow for normal forms to pick up the value.
```html

@@ -47,8 +48,52 @@ <material-input name="username"></material-input>

### Value
Like a normal input field, you can set the value using the attribute `value` in html or via javascript by either setting the attribute or by directly setting the `value` property.
```html
<!-- html -->
<material-input name="animal" value="cat"></material-input>
```
```javascript
// javascript
document.querySelector('material-input.animal').value = 'cat';
document.querySelector('material-input.animal').setAttribute('value','cat');
```
### Validation
Validation works just like with any default `<input>` element. Add a `required` or set the `type` to `email` and you will get the browsers validation notifications. Additionally the `material-input` will have a `valid` or `invalid` style.
Additionally it is possible to explicitly set a field to be `invalid` by using the default `setCustomValidity` method on the `material-input`. You can read more about the [setCustomValidity feature on MDN](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Controlling_the_text_of_constraints_violation).
```javascript
document.querySelector('material-input.customValidatedItem').setCustomValidity('This is not valid.');
```
#### Autovalidate
When adding the `autovalidate` attribute to the `material-input`, the field will be validated on every `keydown` event. However, this means a field with no validation rules will always be valid and receive the `valid` immediately.
## Custom styling
Until browser support mixins, there is only basic styling. You can change the size of the text of all one one `material-input` which will increase its general size.
Apart from basic styling on the `material-input` like `margins` or the `font-size` you can use the following `css properties` to for custom styling.
Additionally you can set the font color for `material-input` which will change the color of the line below and label when active.
### Limitation
As of now only Chrome supports the `:host` element properly, even with the default polyfill. If you want to change the margin on the `material-input` you will need to wrap it in another element.
```css
/* select your specific input or all */
material-input.some-class{
/* the text color of the input */
--material-input-text-color: black;
/* the text color of the placeholder or the floating label on an empty field */
--material-input-placeholder-color: grey;
/* the color of the border and label when the field is focused */
--material-input-highlight-color: indigo;
/* the color of the border and label when the field is in an invalid state */
--material-input-invalid-color: red;
/* the color of the border and label when the field is in a valid state */
--material-input-valid-color: green;
/* the default color of the bottom border */
--material-input-border-color: orange;
/* the height of the bottom border when the field is not focused */
--material-input-line-height: 1px;
/* the height of the bottom border when the field is focused */
--material-input-highlight-line-height: 3px;
}
```
'use strict';
// define attributes that are not supposed to be transferred
// const attributesExceptions = [
// 'name',
// 'label',
// 'tabindex',
// 'placeholder',
// 'autofocus',
// 'autocomplete',
// 'autovalidate'
// ];
class MaterialInput extends HTMLElement {

@@ -10,8 +19,23 @@

createdCallback() {
var value = '';
// set value of material-input
Object.defineProperty( this, "value", {
configurable: true,
enumerable: true,
get: function(){
return value;
},
set: function(newValue){
value = !newValue ? '' : newValue;
this._value(value);
}
});
this.createShadowRoot().innerHTML = `
<style>
:host{
color: rgb(54,79,199);
display: block;
position: relative;
background: transparent;
margin: .5em 0;
}

@@ -22,3 +46,2 @@ .material-input__container{

position: relative;
margin: .5em 0;
}

@@ -30,3 +53,3 @@ .material-input__input{

font-size: 1em;
color: black;
color: var(--material-input-text-color, black);
padding: 1em 1em 1em 10px;

@@ -36,11 +59,17 @@ display: block;

border: none;
border-bottom: .1rem solid rgb(206,212,218);
border-bottom: var(--material-input-line-height, 1px) solid var(--material-input-border-color, rgb(206,212,218));
box-shadow: none;
}
.material-input__container.invalid .material-input__input{
border-bottom-color: var(--material-input-invalid-color, rgb(224,49,49));
}
.material-input__container.valid .material-input__input{
border-bottom-color: var(--material-input-valid-color, rgb(47,158,68));
}
.material-input__input:focus{
outline: none;
color: black;
}
/* placeholder and placeholder fade on focus */
.material-input__input::-webkit-input-placeholder {
color: rgb(134,142,150);
color: var(--material-input-placeholder-color, rgb(134,142,150));
opacity: 1;

@@ -53,3 +82,3 @@ }

.material-input__input::-moz-placeholder {
color: rgb(134,142,150);
color: var(--material-input-placeholder-color, rgb(134,142,150));
opacity: 1;

@@ -62,3 +91,3 @@ }

.material-input__input:-ms-input-placeholder {
color: rgb(134,142,150);
color: var(--material-input-placeholder-color, rgb(134,142,150));
opacity: 1;

@@ -80,4 +109,8 @@ }

}
.material-input__container.no-animation .material-input__label,
.material-input__container.label-always-floats .material-input__label{
transition: 0s ease all;
}
.material-input__container.is-empty .material-input__input[placeholder] ~ .material-input__label{
color: black;
color: var(--material-input-text-color, black);
}

@@ -93,4 +126,19 @@ /* active state */

.material-input__container.is-empty .material-input__input[placeholder]:focus ~ .material-input__label{
color: inherit;
color: var(--material-input-highlight-color, rgb(54,79,199));
}
/* errror state */
.material-input__container.invalid.label-always-floats .material-input__label,
.material-input__container.invalid .material-input__input:focus ~ .material-input__label,
.material-input__container.is-empty.invalid .material-input__input[placeholder]:focus ~ .material-input__label,
.material-input__container.is-empty.invalid .material-input__input[placeholder] ~ .material-input__label{
color: var(--material-input-invalid-color, rgb(224,49,49));
}
/* valid state */
.material-input__container.valid.label-always-floats .material-input__label,
.material-input__container.valid .material-input__input:focus ~ .material-input__label,
.material-input__container.is-empty.valid .material-input__input[placeholder]:focus ~ .material-input__label,
.material-input__container.is-empty.valid .material-input__input[placeholder] ~ .material-input__label{
color: var(--material-input-valid-color, rgb(47,158,68));
}
/* bar */
.material-input__bar{

@@ -103,9 +151,17 @@ position:relative;

content:'';
height:2px;
height: var(--material-input-highlight-line-height, 2px);
width:0;
bottom:0;
position:absolute;
background: currentColor;
background: var(--material-input-highlight-color, rgb(54,79,199));
transition:0.2s ease all;
}
.material-input__container.invalid .material-input__bar::before,
.material-input__container.invalid .material-input__bar::after{
background: var(--material-input-invalid-color, rgb(224,49,49));
}
.material-input__container.valid .material-input__bar::before,
.material-input__container.valid .material-input__bar::after{
background: var(--material-input-valid-color, rgb(47,158,68));
}
.material-input__bar::before {

@@ -121,3 +177,3 @@ left:50%;

</style>
<div class="material-input__container">
<div class="material-input__container no-animation${this.value == '' ? ' is-empty' : ''}">
<input class="material-input__input" tabindex="-1" />

@@ -129,13 +185,20 @@ <label class="material-input__label"></label>

`;
// initialize attributes
this.attributesExceptions = [
'name',
'label',
'tabindex',
'placeholder',
'autofocus',
'autocomplete',
'autovalidate'
];
// set tab index to make element focussable
this.setAttribute('tabindex',0);
this.type = this.getAttribute('type') || 'text';
this.value = this.getAttribute('value') || null;
this.name = this.getAttribute('name') || 'material-input';
this.label = this.getAttribute('label') || null;
this.placeholder = this.getAttribute('placeholder') || null;
this.invalid = this.hasAttribute('invalid') || false;
this.valid = this.hasAttribute('valid') || false;
// add input field for form submisson
this.insertAdjacentHTML('afterend','<input tabindex="-1" type="hidden" name="'+this.name+'"/>');
// shim shadowDOM styling
if(WebComponents !== undefined && WebComponents.flags.shadow === true){
WebComponents.ShadowCSS.shimStyling( this.shadowRoot, 'material-input' )
}
// add hidden input
this.insertAdjacentHTML('afterend','<input tabindex="-1" style="pointer-events: none; margin:0; border: 0; height: 0; opacity: 0; position: absolute; top: '+(this.offsetTop + this.offsetHeight)+'px; left: '+this.offsetLeft+'px;" name="'+this.getAttribute('name')+'"/>');
this.$hiddenInput = document.querySelector('input[name='+this.getAttribute('name')+']');
// elements

@@ -146,38 +209,134 @@ this.$container = this.shadowRoot.querySelector('.material-input__container');

this.$message = this.$container.querySelector('.material-input__message');
this.$hiddenInput = document.querySelector('input[name='+this.name+']');
this.$input.setAttribute('type', this.type);
// add events
this._addEvents();
// transfer attribtues to input & hiddenInput
this._transferAttributes();
// set value, label, etc.
this._setValue(this.getAttribute('value'));
this._setLabel(this.getAttribute('label'));
this._setPlaceholder(this.getAttribute('placeholder'));
this._setValid();
// remove no-animation loading class
setTimeout(function(){
this.$container.classList.remove('no-animation');
}.bind(this),100);
}
/**
* when an attribute is changed
*/
attributeChangedCallback(attrName, oldVal, newVal) {
// define callbacks
var callbacks = {
'valid': this._setValid,
'value': this._setValue,
'label': this._setLabel,
'placeholder': this._setPlaceholder
};
// call callback if it exists
if(callbacks.hasOwnProperty(attrName)) {
callbacks[attrName].call(this, newVal, oldVal);
}
else{
// if other attributes are updated, transfer updates to hidden input field
this._transferAttribute(attrName, newVal, this.attributesExceptions);
}
}
/**
* set the custom validity of the input
*/
setCustomValidity(msg){
this.$input.setCustomValidity(msg);
this.$hiddenInput.setCustomValidity(msg)
}
/**
* add events for all items
*/
_addEvents(){
// on focuse pass to input
this.addEventListener('focus', function(){
this.$input.focus();
});
// set validation status when hiddenInput is invalid
this.$hiddenInput.addEventListener('invalid', function(){
this._setValid(false);
}.bind(this));
// pass on value when user enters content
this.$input.addEventListener('keydown', function(){
this._value(this.$input.value);
}.bind(this));
// pass in value and validate when user exits input field
this.$input.addEventListener('blur', function(){
this._value(this.$input.value);
// check if is valid
if(this.$input.value !== '' && (this.$input.validity.valid === true || this.$input.validity.valid === false)){
this._setValid(this.$input.validity.valid);
}
}.bind(this));
this.addEventListener('focus', function(){
this.$input.focus();
});
if(this.value){
this.$input.value = this.value;
// if autovalidate is set to true, validate on key event
if(this.hasAttribute('autovalidate') && String(this.getAttribute('autovalidate')) !== 'false'){
this.$input.addEventListener('keydown', function(){
// check if is valid
if(this.$input.value !== '' && (this.$input.validity.valid === true)){
this._setValid(true);
}
}.bind(this));
}
this._value(this.value);
this._label(this.label);
this._placeholder(this.placeholder);
if(this.required){
this.$hiddenInput.setAttribute('required','');
}
/**
* set value
*/
_setValue(newValue){
this.value = newValue;
}
/**
* set field to valid or invalid
*/
_setValid(validity = undefined){
// valid is not set
if(!this.hasAttribute('valid') ){
this.valid = undefined;
this.$container.classList.remove('valid');
this.$container.classList.remove('invalid');
}
// valid is true
if(this.getAttribute('valid') === 'true' || this.getAttribute('valid') === true || validity === true || validity === 'true'){
this.valid = true;
this.$container.classList.add('valid');
this.$container.classList.remove('invalid');
}
// valid is false
if(this.getAttribute('valid') === 'false' || this.getAttribute('valid') === false || validity === false || validity === 'false') {
this.valid = false;
this.$container.classList.add('invalid');
this.$container.classList.remove('valid');
}
}
_value(value){
// set value of material-input
this.value = !value ? '' : value;
/**
* transfer attributes to input
*/
_transferAttributes(){
for(var key of Object.keys(this.attributes)){
if (this.attributes.hasOwnProperty(key)) {
this._transferAttribute(this.attributes[key].name, this.attributes[key].value, this.attributesExceptions);
}
}
}
/**
* transfer attribute to input
*/
_transferAttribute(attrName, val, attributesExceptions){
if(attributesExceptions.indexOf(attrName) === -1){
this.$hiddenInput.setAttribute(attrName,val);
this.$input.setAttribute(attrName,val);
}
}
/**
* update value and toggle is-empty class
*/
_value(val){
// set value of hidden input for form submission
this.$hiddenInput.value = this.value;
this.$hiddenInput.value = val;
this.$input.value = val;
// set state depending on value
this._toggle(this.$container, 'is-empty', this.value === '');
this._toggle(this.$container, 'is-empty', val === '');
}

@@ -187,16 +346,20 @@ /**

*/
_label(label){
this.$label.innerHTML = label;
this._toggle(this.$container, 'label-always-floats',this.placeholder !== null);
_setLabel(label){
if(label !== undefined && label !== null){
return this.$label.innerHTML = label;
}
this.$label.innerHTML = '';
}
_placeholder(placeholder){
if(placeholder !== null){
this.$input.placeholder = placeholder;
/**
* set placeholder and add label-always-floats class
*/
_setPlaceholder(placeholder){
if(placeholder !== null && placeholder !== undefined){
this.$input.setAttribute('placeholder', placeholder);
this.$container.classList.add('label-always-floats');
return;
}
else{
this.$input.removeAttribute('placeholder');
}
this.$input.removeAttribute('placeholder');
this.$container.classList.remove('label-always-floats');
}
/**

@@ -203,0 +366,0 @@ * since classList.toggle with a second param is not supported in IE11 and below

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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