material-toggle
Advanced tools
Comparing version 0.0.6 to 1.0.0
{ | ||
"name": "material-input", | ||
"description": "An easy drop-in material-input solution as a custom element", | ||
"main": "src/material-input.js", | ||
"main": "dist/material-toggle.js", | ||
"authors": [ | ||
@@ -22,9 +22,3 @@ "Lukas Oppermann" | ||
"tests" | ||
], | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"web-component-tester": "Polymer/web-component-tester#^4.3.5", | ||
"webcomponentsjs": "^0.7.22", | ||
"polymer": "Polymer/polymer#^1.2.0" | ||
} | ||
] | ||
} |
@@ -1,91 +0,264 @@ | ||
'use strict'; | ||
/** | ||
* transfer attributes to input | ||
*/ | ||
const _transferAttributes = function (ce, element, allowed) { | ||
allowed.forEach(function (attrName) { | ||
if (ce.hasAttribute(attrName)) { | ||
element.setAttribute(attrName, ce.getAttribute(attrName) || '') | ||
ce.removeAttribute(attrName) | ||
} | ||
}) | ||
} | ||
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; }; }(); | ||
/** | ||
* get parent form | ||
*/ | ||
const _getParentForm = function (current) { | ||
current = current.parentElement | ||
// return form | ||
if (current.constructor === HTMLFormElement) return current // eslint-disable-line no-undef | ||
// return false on body | ||
if (current.constructor === HTMLBodyElement) return false // eslint-disable-line no-undef | ||
// dig one level deeper | ||
return _getParentForm(current) | ||
} | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
const makeTemplate = function (strings, ...substs) { | ||
var html = '' | ||
for (let i = 0; i < substs.length; i++) { | ||
html += strings[i] | ||
html += substs[i] | ||
} | ||
html += strings[strings.length - 1] | ||
var template = document.createElement('template') | ||
template.innerHTML = html | ||
return template | ||
} | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
var template = makeTemplate`<style> | ||
:host{ | ||
display: inline-block; | ||
position: relative; | ||
--material-checkbox-highlight-color: var(--accent-color, rgba(54,79,199,0.5)); | ||
} | ||
:host ::slotted(input){ | ||
pointer-events: none; | ||
position: absolute; | ||
left: -100%; | ||
} | ||
:host ::slotted(label){ | ||
display: block; | ||
position: relative; | ||
background: transparent; | ||
padding-left: 54px; | ||
} | ||
.material-toggle__switch{ | ||
position: absolute; | ||
display: block; | ||
top: 50%; | ||
transform: translateY(-50%); | ||
left: 0; | ||
height: 16px; | ||
width: 44px; | ||
background: white; | ||
background-image: linear-gradient(var(--material-checkbox-bg-color, rgb(206,212,218)), var(--material-checkbox-bg-color, rgb(206,212,218))); | ||
border-radius: 100px; | ||
transition: all 0.3s ease; | ||
pointer-events: none; | ||
} | ||
.material-toggle__knob { | ||
position: absolute; | ||
left: -5px; | ||
top: -5px; | ||
display: block; | ||
width: 26px; | ||
height: 26px; | ||
border-radius: 100px; | ||
background: var(--material-checkbox-knob-color, rgb(255,255,255)); | ||
box-shadow: var(--material-checkbox-shadow, 0 .2em .5em rgba(0,0,0,.15)); | ||
content: ''; | ||
transition: all 0.3s ease; | ||
} | ||
:host([checked]) .material-toggle__switch{ | ||
background-image: | ||
linear-gradient(rgba(255,255,255,0.75), rgba(255,255,255,0.75)), | ||
linear-gradient(var(--material-checkbox-highlight-color), var(--material-checkbox-highlight-color)); | ||
} | ||
:host([checked]) .material-toggle__knob { | ||
left: 20px; | ||
background: var(--material-checkbox-highlight-color); | ||
} | ||
:host([disabled]) .material-toggle__switch{ | ||
background: var(--material-checkbox-disabled-bg-color, rgb(241,243,245)); | ||
pointer-events: none; | ||
} | ||
:host([disabled]) .material-toggle__knob{ | ||
background: var(--material-checkbox-disabled-knob-color, rgb(206,212,218)); | ||
box-shadow: var(--material-checkbox-disabled-shadow, 0 .2em .5em rgba(0,0,0,.1)); | ||
} | ||
:host(:focus){ | ||
outline: none; | ||
} | ||
:host(:focus) .material-toggle__knob:not(.unfocused){ | ||
box-shadow: var(--material-checkbox-shadow, 0 .2em .5em rgba(0,0,0,.15)), 0 0 0 .7em rgba(0,0,0,.15); | ||
} | ||
:host([checked]:focus) .material-toggle__knob:not(.unfocused){ | ||
box-shadow: var(--material-checkbox-shadow, 0 .2em .5em rgba(0,0,0,.15)), 0 0 0 .7em var(--material-checkbox-semi-highlight-color, rgba(54,79,199,.25)); | ||
} | ||
</style> | ||
<slot></slot> | ||
<div class="material-toggle__switch"> | ||
<div class="material-toggle__knob" draggable="true"></div> | ||
</div> | ||
` | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
ShadyCSS.prepareTemplate(template, 'material-toggle') // eslint-disable-line no-undef | ||
/** | ||
* A simple (boolean) material toggle based on a checkbox, which works in a normal html form | ||
*/ | ||
class MaterialToggle extends HTMLElement { // eslint-disable-line no-undef | ||
var MaterialToggle = function (_HTMLInputElement) { | ||
_inherits(MaterialToggle, _HTMLInputElement); | ||
constructor () { | ||
super() | ||
// Attach a shadow root to the element. | ||
let shadowRoot = this.attachShadow({mode: 'open'}) | ||
ShadyCSS.applyStyle(this) // eslint-disable-line no-undef | ||
shadowRoot.appendChild(document.importNode(template.content, true)) | ||
} | ||
function MaterialToggle() { | ||
_classCallCheck(this, MaterialToggle); | ||
connectedCallback () { | ||
// get elements | ||
this.$knob = this.shadowRoot.querySelector('.material-toggle__knob') | ||
this.$label = document.createElement('label') | ||
this.$label.innerHTML = ` | ||
<input type="checkbox" tabindex="-1" style="position: absolute; opacity: 0; pointer-events: none;"/> | ||
<div class="material-toggle__label">${this.innerHTML}</div> | ||
` | ||
// remove potential label from slot as it is added above | ||
this.innerHTML = '' | ||
this.appendChild(this.$label) | ||
this.$checkbox = this.querySelector('input') | ||
return _possibleConstructorReturn(this, (MaterialToggle.__proto__ || Object.getPrototypeOf(MaterialToggle)).call(this)); // always call super() first in the ctor. This also calls the extended class' ctor. | ||
_transferAttributes(this, this.$checkbox, [ | ||
'name', | ||
'required', | ||
'autofocus' | ||
]) | ||
// reset values | ||
this.disabled = this.disabled | ||
this.checked = this.checked | ||
// add events | ||
this._addEvents() | ||
} | ||
_addEvents () { | ||
// add event | ||
this.$checkbox.addEventListener('change', function (e) { | ||
this.checked = e.target.checked | ||
}.bind(this)) | ||
// move focus to main element if checkbox is focused | ||
this.$checkbox.addEventListener('focus', function () { | ||
this.focus() | ||
}.bind(this)) | ||
// toggle checkbox in space | ||
this.addEventListener('keydown', function (e) { | ||
// space | ||
if (e.keyCode === 32) { | ||
this.checked = !this.$checkbox.checked | ||
} | ||
}.bind(this)) | ||
// submit form on return | ||
this.addEventListener('keydown', function (e) { | ||
var $form = _getParentForm(e.target) | ||
// return | ||
if (e.keyCode === 13) { | ||
if ($form.checkValidity()) { | ||
$form.submit() | ||
} else if ($form.querySelector('[type="submit"]') !== null) { | ||
// needed to trigger validation | ||
$form.querySelector('[type="submit"]').click() | ||
} | ||
return | ||
} | ||
}) | ||
// remove focus on click | ||
this.$label.addEventListener('mousedown', function () { | ||
this.$knob.classList.add('unfocused') | ||
}.bind(this)) | ||
// add focus on mouse event | ||
this.$label.addEventListener('keydown', function () { | ||
this.$knob.classList.remove('unfocused') | ||
}.bind(this)) | ||
} | ||
static get observedAttributes () { | ||
return [ | ||
/** @type {boolean} When given the element is totally inactive */ | ||
'disabled', | ||
/** @type {boolean} When given the element is set to active */ | ||
'checked', | ||
/** @type {true|false} When given, sets the validity state */ | ||
'validity' | ||
] | ||
} | ||
attributeChangedCallback (attrName, oldVal, newVal) { | ||
if (this.disabled) { | ||
this.setAttribute('tabindex', '-1') | ||
this.setAttribute('aria-disabled', 'true') | ||
} else { | ||
this.setAttribute('tabindex', '0') | ||
this.setAttribute('aria-disabled', 'false') | ||
} | ||
} | ||
_createClass(MaterialToggle, [{ | ||
key: 'createdCallback', | ||
value: function createdCallback() { | ||
var checkbox = document.createElement('input'); | ||
checkbox.type = 'checkbox'; | ||
this.appendChild(checkbox); | ||
get disabled () { | ||
return this.hasAttribute('disabled') | ||
} | ||
this.createShadowRoot().innerHTML = '\n <style>\n :host{\n }\n ::content input{\n position: relative;\n display: inline-block;\n border: 0;\n margin: 10px 35px 10px 3px;\n }\n ::content input:before {\n content: "";\n position: absolute;\n display: block;\n left: -3px;\n top: -3px;\n height: 16px;\n width: 44px;\n background: white;\n background-image: linear-gradient(var(--material-checkbox-bg-color, rgb(206,212,218)), var(--material-checkbox-bg-color, rgb(206,212,218)));\n border-radius: 100px;\n transition: all 0.3s ease;\n }\n ::content input:after {\n left: 20px;\n position: absolute;\n left: -5px;\n top: -8px;\n display: block;\n width: 26px;\n height: 26px;\n border-radius: 100px;\n background: var(--material-checkbox-knob-color, rgb(255,255,255));\n box-shadow: var(--material-checkbox-shadow, 0 .2rem .5rem rgba(0,0,0,.15));\n content: \'\';\n transition: all 0.3s ease;\n }\n ::content input:active:after {\n transform: scale(1.15, 0.85);\n }\n ::content input:checked:before {\n background-image: linear-gradient(var(--material-checkbox-highlight-color, rgba(54,79,199,0.5)), var(--material-checkbox-highlight-color, rgba(54,79,199,0.5)));\n }\n ::content input:checked:after {\n left: 20px;\n background: var(--material-checkbox-highlight-color, rgb(54,79,199));\n }\n ::content input:disabled:before{\n background: var(--material-checkbox-disabled-bg-color, rgb(241,243,245));\n pointer-events: none;\n }\n ::content input:disabled:after {\n background: var(--material-checkbox-disabled-knob-color, rgb(206,212,218));\n box-shadow: var(--material-checkbox-disabled-shadow, 0 .2rem .5rem rgba(0,0,0,.1));\n }\n </style>\n <content></content>\n '; | ||
this.$input = this.querySelector('input'); | ||
// shim shadowDOM styling | ||
if (WebComponents !== undefined && WebComponents.flags.shadow === true) { | ||
WebComponents.ShadowCSS.shimStyling(this.shadowRoot, 'material-toggle'); | ||
} | ||
this.attributesExceptions = []; | ||
this._transferAttributes(); | ||
} | ||
set disabled (val) { | ||
// Reflect the value of `disabled` as an attribute. | ||
if (val) { | ||
this.setAttribute('disabled', '') | ||
this.$checkbox.setAttribute('disabled', '') | ||
} else { | ||
this.removeAttribute('disabled') | ||
this.$checkbox.removeAttribute('disabled') | ||
} | ||
} | ||
/** | ||
* transfer attributes to input | ||
*/ | ||
get checked () { | ||
return this.hasAttribute('checked') | ||
} | ||
}, { | ||
key: '_transferAttributes', | ||
value: function _transferAttributes() { | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
set checked (val) { | ||
if (val) { | ||
this.setAttribute('checked', '') | ||
if (this.$checkbox !== undefined) { | ||
this.$checkbox.setAttribute('checked', '') | ||
} | ||
} else { | ||
this.removeAttribute('checked') | ||
if (this.$checkbox !== undefined) { | ||
this.$checkbox.removeAttribute('checked') | ||
} | ||
} | ||
} | ||
try { | ||
for (var _iterator = Object.keys(this.attributes)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var key = _step.value; | ||
set validity (val) { | ||
// Reflect the value of `validity` as an attribute. | ||
if (val === true || val === false) { | ||
this.setAttribute('validity', val) | ||
} else { | ||
this.removeAttribute('validity') | ||
} | ||
} | ||
if (this.attributes.hasOwnProperty(key)) { | ||
this._transferAttribute(this.attributes[key].name, this.attributes[key].value, this.attributesExceptions); | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
} | ||
/** | ||
* transfer attribute to input | ||
*/ | ||
get validity () { | ||
return this.getAttribute('validity') | ||
} | ||
} | ||
}, { | ||
key: '_transferAttribute', | ||
value: function _transferAttribute(attrName, val, attributesExceptions) { | ||
if (attributesExceptions.indexOf(attrName) === -1) { | ||
this.$input.setAttribute(attrName, val); | ||
if (attrName === 'id') { | ||
this.removeAttribute('id'); | ||
} | ||
} | ||
} | ||
}]); | ||
customElements.define('material-toggle', MaterialToggle) // eslint-disable-line no-undef | ||
return MaterialToggle; | ||
}(HTMLInputElement); | ||
document.registerElement('material-toggle', MaterialToggle); | ||
//# sourceMappingURL=material-toggle.js.map |
@@ -1,16 +0,12 @@ | ||
'use strict'; | ||
'use strict' | ||
/* ---------- */ | ||
/* setup */ | ||
const gulp = require('gulp'); | ||
const sourcemaps = require('gulp-sourcemaps'); | ||
const babel = require('gulp-babel'); | ||
gulp.task('default', () => { | ||
return gulp.src('src/*.js') | ||
.pipe(sourcemaps.init()) | ||
.pipe(babel({ | ||
presets: ['latest'] | ||
})) | ||
.pipe(sourcemaps.write('.')) | ||
.pipe(gulp.dest('dist')); | ||
}); | ||
var gulp = require('gulp') | ||
var sourcemaps = require('gulp-sourcemaps') | ||
// | ||
gulp.task('default', function () { | ||
return gulp.src('src/material-toggle.js') | ||
.pipe(sourcemaps.init()) | ||
.pipe(sourcemaps.write('.')) | ||
.pipe(gulp.dest('dist')) | ||
}) |
{ | ||
"name": "material-toggle", | ||
"version": "0.0.6", | ||
"version": "1.0.0", | ||
"description": "Material Design toggle web component. No framework, vanilla js", | ||
"main": "dist/material-toggle.js", | ||
"scripts": { | ||
"test": "./node_modules/.bin/wct --skip-selenium-install", | ||
"test": "./node_modules/.bin/wct && standard 'src/*.js' | snazzy", | ||
"travis": "./node_modules/.bin/wct ", | ||
@@ -28,15 +28,16 @@ "cover": "./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha test/*.js --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" | ||
"devDependencies": { | ||
"babel-preset-latest": "^6.16.0", | ||
"bower": "^1.7.9", | ||
"@webcomponents/custom-elements": "^1.0.0-alpha.3", | ||
"@webcomponents/shadycss": "github:webcomponents/shadycss", | ||
"@webcomponents/shadydom": "github:webcomponents/shadydom", | ||
"coveralls": "^2.11.14", | ||
"gulp": "^3.9.1", | ||
"gulp-babel": "^6.1.2", | ||
"gulp-sourcemaps": "^1.6.0", | ||
"istanbul": "^0.4.5", | ||
"mocha-istanbul": "^0.3.0", | ||
"web-component-tester": "^4.3.5", | ||
"web-component-tester-istanbul": "^0.10.0", | ||
"webcomponents.js": "^0.7" | ||
"snazzy": "^6.0.0", | ||
"standard": "^8.6.0", | ||
"web-component-tester": "^5.0.0", | ||
"web-component-tester-istanbul": "^0.3.0" | ||
}, | ||
"dependencies": {} | ||
} |
# Material-toggle | ||
An easy drop-in material design vanilla custom toggle element. HTML form ready, no framework dependencies, small footprint. | ||
[![Spec Custom Elements V1](https://img.shields.io/badge/spec-custom%20elements%20v1-F52757.svg?style=flat-square)](https://www.w3.org/TR/custom-elements/) | ||
[![Build Status](https://img.shields.io/travis/nuclei/material-toggle/master.svg?style=flat-square)](https://travis-ci.org/nuclei/material-toggle) [![npm](https://img.shields.io/npm/v/material-toggle.svg?style=flat-square)](https://www.npmjs.com/package/material-toggle) [![npm](https://img.shields.io/npm/dt/material-toggle.svg?style=flat-square)](https://www.npmjs.com/package/material-toggle) [![npm](https://img.shields.io/npm/l/material-toggle.svg?style=flat-square)](https://github.com/nuclei/material-toggle/blob/master/LICENSE) | ||
@@ -5,0 +6,0 @@ |
@@ -1,104 +0,262 @@ | ||
'use strict'; | ||
/** | ||
* transfer attributes to input | ||
*/ | ||
const _transferAttributes = function (ce, element, allowed) { | ||
allowed.forEach(function (attrName) { | ||
if (ce.hasAttribute(attrName)) { | ||
element.setAttribute(attrName, ce.getAttribute(attrName) || '') | ||
ce.removeAttribute(attrName) | ||
} | ||
}) | ||
} | ||
class MaterialToggle extends HTMLInputElement { | ||
/** | ||
* get parent form | ||
*/ | ||
const _getParentForm = function (current) { | ||
current = current.parentElement | ||
// return form | ||
if (current.constructor === HTMLFormElement) return current // eslint-disable-line no-undef | ||
// return false on body | ||
if (current.constructor === HTMLBodyElement) return false // eslint-disable-line no-undef | ||
// dig one level deeper | ||
return _getParentForm(current) | ||
} | ||
constructor() { | ||
super(); // always call super() first in the ctor. This also calls the extended class' ctor. | ||
const makeTemplate = function (strings, ...substs) { | ||
var html = '' | ||
for (let i = 0; i < substs.length; i++) { | ||
html += strings[i] | ||
html += substs[i] | ||
} | ||
html += strings[strings.length - 1] | ||
var template = document.createElement('template') | ||
template.innerHTML = html | ||
return template | ||
} | ||
var template = makeTemplate`<style> | ||
:host{ | ||
display: inline-block; | ||
position: relative; | ||
--material-checkbox-highlight-color: var(--accent-color, rgba(54,79,199,0.5)); | ||
} | ||
:host ::slotted(input){ | ||
pointer-events: none; | ||
position: absolute; | ||
left: -100%; | ||
} | ||
:host ::slotted(label){ | ||
display: block; | ||
position: relative; | ||
background: transparent; | ||
padding-left: 54px; | ||
} | ||
.material-toggle__switch{ | ||
position: absolute; | ||
display: block; | ||
top: 50%; | ||
transform: translateY(-50%); | ||
left: 0; | ||
height: 16px; | ||
width: 44px; | ||
background: white; | ||
background-image: linear-gradient(var(--material-checkbox-bg-color, rgb(206,212,218)), var(--material-checkbox-bg-color, rgb(206,212,218))); | ||
border-radius: 100px; | ||
transition: all 0.3s ease; | ||
pointer-events: none; | ||
} | ||
.material-toggle__knob { | ||
position: absolute; | ||
left: -5px; | ||
top: -5px; | ||
display: block; | ||
width: 26px; | ||
height: 26px; | ||
border-radius: 100px; | ||
background: var(--material-checkbox-knob-color, rgb(255,255,255)); | ||
box-shadow: var(--material-checkbox-shadow, 0 .2em .5em rgba(0,0,0,.15)); | ||
content: ''; | ||
transition: all 0.3s ease; | ||
} | ||
:host([checked]) .material-toggle__switch{ | ||
background-image: | ||
linear-gradient(rgba(255,255,255,0.75), rgba(255,255,255,0.75)), | ||
linear-gradient(var(--material-checkbox-highlight-color), var(--material-checkbox-highlight-color)); | ||
} | ||
:host([checked]) .material-toggle__knob { | ||
left: 20px; | ||
background: var(--material-checkbox-highlight-color); | ||
} | ||
:host([disabled]) .material-toggle__switch{ | ||
background: var(--material-checkbox-disabled-bg-color, rgb(241,243,245)); | ||
pointer-events: none; | ||
} | ||
:host([disabled]) .material-toggle__knob{ | ||
background: var(--material-checkbox-disabled-knob-color, rgb(206,212,218)); | ||
box-shadow: var(--material-checkbox-disabled-shadow, 0 .2em .5em rgba(0,0,0,.1)); | ||
} | ||
:host(:focus){ | ||
outline: none; | ||
} | ||
:host(:focus) .material-toggle__knob:not(.unfocused){ | ||
box-shadow: var(--material-checkbox-shadow, 0 .2em .5em rgba(0,0,0,.15)), 0 0 0 .7em rgba(0,0,0,.15); | ||
} | ||
:host([checked]:focus) .material-toggle__knob:not(.unfocused){ | ||
box-shadow: var(--material-checkbox-shadow, 0 .2em .5em rgba(0,0,0,.15)), 0 0 0 .7em var(--material-checkbox-semi-highlight-color, rgba(54,79,199,.25)); | ||
} | ||
</style> | ||
<slot></slot> | ||
<div class="material-toggle__switch"> | ||
<div class="material-toggle__knob" draggable="true"></div> | ||
</div> | ||
` | ||
createdCallback() { | ||
var checkbox = document.createElement('input'); | ||
checkbox.type = 'checkbox'; | ||
this.appendChild(checkbox); | ||
ShadyCSS.prepareTemplate(template, 'material-toggle') // eslint-disable-line no-undef | ||
/** | ||
* A simple (boolean) material toggle based on a checkbox, which works in a normal html form | ||
*/ | ||
class MaterialToggle extends HTMLElement { // eslint-disable-line no-undef | ||
this.createShadowRoot().innerHTML = ` | ||
<style> | ||
:host{ | ||
} | ||
::content input{ | ||
position: relative; | ||
display: inline-block; | ||
border: 0; | ||
margin: 10px 35px 10px 3px; | ||
} | ||
::content input:before { | ||
content: ""; | ||
position: absolute; | ||
display: block; | ||
left: -3px; | ||
top: -3px; | ||
height: 16px; | ||
width: 44px; | ||
background: white; | ||
background-image: linear-gradient(var(--material-checkbox-bg-color, rgb(206,212,218)), var(--material-checkbox-bg-color, rgb(206,212,218))); | ||
border-radius: 100px; | ||
transition: all 0.3s ease; | ||
} | ||
::content input:after { | ||
left: 20px; | ||
position: absolute; | ||
left: -5px; | ||
top: -8px; | ||
display: block; | ||
width: 26px; | ||
height: 26px; | ||
border-radius: 100px; | ||
background: var(--material-checkbox-knob-color, rgb(255,255,255)); | ||
box-shadow: var(--material-checkbox-shadow, 0 .2rem .5rem rgba(0,0,0,.15)); | ||
content: ''; | ||
transition: all 0.3s ease; | ||
} | ||
::content input:active:after { | ||
transform: scale(1.15, 0.85); | ||
} | ||
::content input:checked:before { | ||
background-image: linear-gradient(var(--material-checkbox-highlight-color, rgba(54,79,199,0.5)), var(--material-checkbox-highlight-color, rgba(54,79,199,0.5))); | ||
} | ||
::content input:checked:after { | ||
left: 20px; | ||
background: var(--material-checkbox-highlight-color, rgb(54,79,199)); | ||
} | ||
::content input:disabled:before{ | ||
background: var(--material-checkbox-disabled-bg-color, rgb(241,243,245)); | ||
pointer-events: none; | ||
} | ||
::content input:disabled:after { | ||
background: var(--material-checkbox-disabled-knob-color, rgb(206,212,218)); | ||
box-shadow: var(--material-checkbox-disabled-shadow, 0 .2rem .5rem rgba(0,0,0,.1)); | ||
} | ||
</style> | ||
<content></content> | ||
`; | ||
this.$input = this.querySelector('input'); | ||
// shim shadowDOM styling | ||
if(WebComponents !== undefined && WebComponents.flags.shadow === true){ | ||
WebComponents.ShadowCSS.shimStyling( this.shadowRoot, 'material-toggle' ) | ||
constructor () { | ||
super() | ||
// Attach a shadow root to the element. | ||
let shadowRoot = this.attachShadow({mode: 'open'}) | ||
ShadyCSS.applyStyle(this) // eslint-disable-line no-undef | ||
shadowRoot.appendChild(document.importNode(template.content, true)) | ||
} | ||
connectedCallback () { | ||
// get elements | ||
this.$knob = this.shadowRoot.querySelector('.material-toggle__knob') | ||
this.$label = document.createElement('label') | ||
this.$label.innerHTML = ` | ||
<input type="checkbox" tabindex="-1" style="position: absolute; opacity: 0; pointer-events: none;"/> | ||
<div class="material-toggle__label">${this.innerHTML}</div> | ||
` | ||
// remove potential label from slot as it is added above | ||
this.innerHTML = '' | ||
this.appendChild(this.$label) | ||
this.$checkbox = this.querySelector('input') | ||
_transferAttributes(this, this.$checkbox, [ | ||
'name', | ||
'required', | ||
'autofocus' | ||
]) | ||
// reset values | ||
this.disabled = this.disabled | ||
this.checked = this.checked | ||
// add events | ||
this._addEvents() | ||
} | ||
_addEvents () { | ||
// add event | ||
this.$checkbox.addEventListener('change', function (e) { | ||
this.checked = e.target.checked | ||
}.bind(this)) | ||
// move focus to main element if checkbox is focused | ||
this.$checkbox.addEventListener('focus', function () { | ||
this.focus() | ||
}.bind(this)) | ||
// toggle checkbox in space | ||
this.addEventListener('keydown', function (e) { | ||
// space | ||
if (e.keyCode === 32) { | ||
this.checked = !this.$checkbox.checked | ||
} | ||
}.bind(this)) | ||
// submit form on return | ||
this.addEventListener('keydown', function (e) { | ||
var $form = _getParentForm(e.target) | ||
// return | ||
if (e.keyCode === 13) { | ||
if ($form.checkValidity()) { | ||
$form.submit() | ||
} else if ($form.querySelector('[type="submit"]') !== null) { | ||
// needed to trigger validation | ||
$form.querySelector('[type="submit"]').click() | ||
} | ||
this.attributesExceptions = []; | ||
this._transferAttributes(); | ||
return | ||
} | ||
}) | ||
// remove focus on click | ||
this.$label.addEventListener('mousedown', function () { | ||
this.$knob.classList.add('unfocused') | ||
}.bind(this)) | ||
// add focus on mouse event | ||
this.$label.addEventListener('keydown', function () { | ||
this.$knob.classList.remove('unfocused') | ||
}.bind(this)) | ||
} | ||
static get observedAttributes () { | ||
return [ | ||
/** @type {boolean} When given the element is totally inactive */ | ||
'disabled', | ||
/** @type {boolean} When given the element is set to active */ | ||
'checked', | ||
/** @type {true|false} When given, sets the validity state */ | ||
'validity' | ||
] | ||
} | ||
attributeChangedCallback (attrName, oldVal, newVal) { | ||
if (this.disabled) { | ||
this.setAttribute('tabindex', '-1') | ||
this.setAttribute('aria-disabled', 'true') | ||
} else { | ||
this.setAttribute('tabindex', '0') | ||
this.setAttribute('aria-disabled', 'false') | ||
} | ||
} | ||
/** | ||
* 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); | ||
} | ||
} | ||
get disabled () { | ||
return this.hasAttribute('disabled') | ||
} | ||
set disabled (val) { | ||
// Reflect the value of `disabled` as an attribute. | ||
if (val) { | ||
this.setAttribute('disabled', '') | ||
this.$checkbox.setAttribute('disabled', '') | ||
} else { | ||
this.removeAttribute('disabled') | ||
this.$checkbox.removeAttribute('disabled') | ||
} | ||
/** | ||
* transfer attribute to input | ||
*/ | ||
_transferAttribute(attrName, val, attributesExceptions){ | ||
if(attributesExceptions.indexOf(attrName) === -1){ | ||
this.$input.setAttribute(attrName,val); | ||
if(attrName === 'id'){ | ||
this.removeAttribute('id'); | ||
} | ||
} | ||
} | ||
get checked () { | ||
return this.hasAttribute('checked') | ||
} | ||
set checked (val) { | ||
if (val) { | ||
this.setAttribute('checked', '') | ||
if (this.$checkbox !== undefined) { | ||
this.$checkbox.setAttribute('checked', '') | ||
} | ||
} else { | ||
this.removeAttribute('checked') | ||
if (this.$checkbox !== undefined) { | ||
this.$checkbox.removeAttribute('checked') | ||
} | ||
} | ||
} | ||
set validity (val) { | ||
// Reflect the value of `validity` as an attribute. | ||
if (val === true || val === false) { | ||
this.setAttribute('validity', val) | ||
} else { | ||
this.removeAttribute('validity') | ||
} | ||
} | ||
get validity () { | ||
return this.getAttribute('validity') | ||
} | ||
} | ||
document.registerElement('material-toggle', MaterialToggle); | ||
customElements.define('material-toggle', MaterialToggle) // eslint-disable-line no-undef |
@@ -5,3 +5,3 @@ module.exports = { | ||
"local": { | ||
"browsers": ["chrome"] | ||
"browsers": ["chrome", "firefox"] | ||
} | ||
@@ -8,0 +8,0 @@ // istanbul: { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
0
0
44
115468
12
19
1081
1