Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
13
gaia/shared/elements/gaia_switch/examples/example.js
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
var result = document.getElementById('result');
|
||||
|
||||
var elements = document.querySelectorAll('gaia-switch');
|
||||
|
||||
[].forEach.call(elements, function(switchEl, index) {
|
||||
switchEl.addEventListener('click', function(e) {
|
||||
result.textContent = 'Switch event for: ' + (index + 1) + ' value: ' +
|
||||
e.target.checked;
|
||||
});
|
||||
|
||||
});
|
||||
52
gaia/shared/elements/gaia_switch/examples/index.html
Executable file
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>GaiaSwitch Demo</title>
|
||||
<meta name="description" content="Demo app for gaia-switch" />
|
||||
<style type="text/css">
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10px;
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
}
|
||||
section {
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
<script src="../../../js/component_utils.js"></script>
|
||||
<script>window.GaiaSwitchBaseurl = '../';</script>
|
||||
<script src="../script.js"></script>
|
||||
<script defer src="example.js"></script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.getElementById('dir').checked = false;
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body role="application">
|
||||
<p dir="ltr">
|
||||
<label>
|
||||
<input id="dir" type="checkbox"
|
||||
onchange="document.documentElement.dir = this.checked ? 'rtl' : 'ltr'">
|
||||
RTL mode
|
||||
</label>
|
||||
</p>
|
||||
<section>
|
||||
<gaia-switch>
|
||||
<label>With a label</label>
|
||||
</gaia-switch>
|
||||
</section>
|
||||
<section>
|
||||
<gaia-switch>
|
||||
<label>With a different label</label>
|
||||
<details dir="auto">Sometimes a gaia switch can have an explanation. Sometimes a gaia switch can have an explanation. Sometimes a gaia switch can have an explanation. </details>
|
||||
</gaia-switch>
|
||||
</section>
|
||||
<div id="result"></div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
gaia/shared/elements/gaia_switch/images/background.png
Executable file
|
After Width: | Height: | Size: 755 B |
BIN
gaia/shared/elements/gaia_switch/images/background@1.5x.png
Executable file
|
After Width: | Height: | Size: 1 KiB |
BIN
gaia/shared/elements/gaia_switch/images/background_off.png
Executable file
|
After Width: | Height: | Size: 475 B |
BIN
gaia/shared/elements/gaia_switch/images/background_off@1.5x.png
Executable file
|
After Width: | Height: | Size: 616 B |
BIN
gaia/shared/elements/gaia_switch/images/background_off@2.25x.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
gaia/shared/elements/gaia_switch/images/background_on@2.25x.png
Executable file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
gaia/shared/elements/gaia_switch/images/background_rtl.png
Executable file
|
After Width: | Height: | Size: 748 B |
BIN
gaia/shared/elements/gaia_switch/images/background_rtl@1.5x.png
Executable file
|
After Width: | Height: | Size: 1 KiB |
151
gaia/shared/elements/gaia_switch/script.js
Executable file
|
|
@ -0,0 +1,151 @@
|
|||
'use strict';
|
||||
/* global ComponentUtils */
|
||||
|
||||
window.GaiaSwitch = (function(win) {
|
||||
// Extend from the HTMLElement prototype
|
||||
var proto = Object.create(HTMLElement.prototype);
|
||||
|
||||
// Allow baseurl to be overridden (used for demo page)
|
||||
var baseurl = window.GaiaSwitchBaseurl ||
|
||||
'/shared/elements/gaia_switch/';
|
||||
|
||||
proto.createdCallback = function() {
|
||||
var shadow = this.createShadowRoot();
|
||||
this._template = template.content.cloneNode(true);
|
||||
this._input = this._template.querySelector('input[type="checkbox"]');
|
||||
|
||||
var checked = this.getAttribute('checked');
|
||||
if (checked !== null) {
|
||||
this._input.checked = true;
|
||||
}
|
||||
|
||||
var wrapper = this._template.getElementById('switch');
|
||||
wrapper.addEventListener('click', this.handleClick.bind(this));
|
||||
|
||||
shadow.appendChild(this._template);
|
||||
|
||||
ComponentUtils.style.call(this, baseurl);
|
||||
|
||||
// Proxy RTL changes to the shadow root so we can style for RTL.
|
||||
var dirObserver = new MutationObserver(this.updateInternalDir.bind(this));
|
||||
dirObserver.observe(document.documentElement, {
|
||||
attributeFilter: ['dir'],
|
||||
attributes: true
|
||||
});
|
||||
this.updateInternalDir();
|
||||
};
|
||||
|
||||
proto.updateInternalDir = function() {
|
||||
var internal = this.shadowRoot.firstElementChild;
|
||||
if (document.documentElement.dir === 'rtl') {
|
||||
internal.setAttribute('dir', 'rtl');
|
||||
} else {
|
||||
internal.removeAttribute('dir');
|
||||
}
|
||||
};
|
||||
|
||||
proto.handleClick = function(e) {
|
||||
// If user clicked the (optional) link, do not toggle gaia-switch.
|
||||
if (e && e.target.tagName === 'A') {
|
||||
return;
|
||||
}
|
||||
|
||||
e && e.preventDefault();
|
||||
e && e.stopImmediatePropagation();
|
||||
|
||||
// Dispatch a click event.
|
||||
var event = new MouseEvent('click', {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
this.dispatchEvent(event);
|
||||
|
||||
if (!event.defaultPrevented) {
|
||||
this.checked = !this.checked;
|
||||
}
|
||||
|
||||
// Dispatch a change event for the gaia-switch.
|
||||
this.dispatchEvent(new CustomEvent('change', {
|
||||
bubbles: true,
|
||||
cancelable: false
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Allows users to simulate clicking through javascript.
|
||||
*/
|
||||
proto.click = function() {
|
||||
this.handleClick();
|
||||
};
|
||||
|
||||
/**
|
||||
* Proxy the checked property to the input element.
|
||||
*/
|
||||
Object.defineProperty( proto, 'checked', {
|
||||
get: function() {
|
||||
return this._input.checked;
|
||||
},
|
||||
set: function(value) {
|
||||
this._input.checked = value;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Disabled setter
|
||||
*/
|
||||
Object.defineProperty( proto, 'disabled', {
|
||||
get: function() {
|
||||
return this.hasAttribute('disabled');
|
||||
},
|
||||
set: function(value) {
|
||||
if (value) {
|
||||
this.setAttribute('disabled', true);
|
||||
} else {
|
||||
this.removeAttribute('disabled');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Proxy the name property to the input element.
|
||||
*/
|
||||
Object.defineProperty( proto, 'name', {
|
||||
get: function() {
|
||||
return this.getAttribute('name');
|
||||
},
|
||||
set: function(value) {
|
||||
this.setAttribute('name', value);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Proxy the input type.
|
||||
*/
|
||||
Object.defineProperty( proto, 'type', {
|
||||
get: function() {
|
||||
return 'gaia-switch';
|
||||
}
|
||||
});
|
||||
|
||||
// HACK: Create a <template> in memory at runtime.
|
||||
// When the custom-element is created we clone
|
||||
// this template and inject into the shadow-root.
|
||||
// Prior to this we would have had to copy/paste
|
||||
// the template into the <head> of every app that
|
||||
// wanted to use <gaia-switch>, this would make
|
||||
// markup changes complicated, and could lead to
|
||||
// things getting out of sync. This is a short-term
|
||||
// hack until we can import entire custom-elements
|
||||
// using HTML Imports (bug 877072).
|
||||
var template = document.createElement('template');
|
||||
template.innerHTML = `<span id="switch">
|
||||
<input type="checkbox">
|
||||
<span><content select="label"></content></span>
|
||||
<div class="details"><content select="details"></content></div>
|
||||
<content select="a"></content>
|
||||
</span>`;
|
||||
|
||||
// Register and return the constructor
|
||||
return document.registerElement('gaia-switch', { prototype: proto });
|
||||
})(window);
|
||||
116
gaia/shared/elements/gaia_switch/style.css
Executable file
|
|
@ -0,0 +1,116 @@
|
|||
gaia-switch {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#switch {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background: none;
|
||||
}
|
||||
|
||||
#switch span {
|
||||
font-size: 1.9rem;
|
||||
color: var(--label-color);
|
||||
padding: 1rem 0;
|
||||
line-height: 3rem;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
/* Override inheriting nowrap from legacy lists building blocks. */
|
||||
white-space: normal;
|
||||
}
|
||||
#switch span:-moz-dir(ltr) { float: left; }
|
||||
#switch span:-moz-dir(rtl) { float: right; }
|
||||
|
||||
#switch span:not(:empty) {
|
||||
padding-inline-end: 6rem;
|
||||
}
|
||||
|
||||
#switch input {
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
offset-inline-start: 0;
|
||||
}
|
||||
|
||||
#switch input:checked ~ span::after {
|
||||
background-position: center bottom;
|
||||
}
|
||||
|
||||
/* ----------------------------------
|
||||
* ON/OFF SWITCHES
|
||||
* ---------------------------------- */
|
||||
|
||||
#switch input ~ span::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
offset-inline-end: 0;
|
||||
top: 2.5rem;
|
||||
width: 6rem;
|
||||
margin: -1.4rem 0 0;
|
||||
height: 2.7rem;
|
||||
border-radius: 1.35rem;
|
||||
overflow: hidden;
|
||||
background-color: #e6e6e6;
|
||||
background-image: url(images/background_off.png);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 9.2rem 2.7rem;
|
||||
transition: background 0.2s ease;
|
||||
}
|
||||
#switch input ~ span:-moz-dir(ltr)::after { background-position: -3.2rem 0; }
|
||||
#switch input ~ span:-moz-dir(rtl)::after { background-position: 0 0; }
|
||||
|
||||
/* switch: 'ON' state */
|
||||
#switch input:checked ~ span:-moz-dir(ltr)::after {
|
||||
background-image: url(images/background.png);
|
||||
background-position: 0 0;
|
||||
}
|
||||
#switch input:checked ~ span:-moz-dir(rtl)::after {
|
||||
background-image: url(images/background_rtl.png);
|
||||
background-position: -3.2rem 0;
|
||||
}
|
||||
|
||||
/* switch: disabled state */
|
||||
#switch input:disabled ~ span::after {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
#switch input.uninit ~ span::after {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* A <details> slot may be specified in addition the the <label>.
|
||||
* When provided, it appears under the <label> and can provide additional context.
|
||||
*/
|
||||
#switch div.details {
|
||||
clear: both;
|
||||
position: relative;
|
||||
top: -1.5rem;
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding-top: 0.5rem;
|
||||
padding-inline-start: 0;
|
||||
padding-inline-end: 8rem;
|
||||
font-size: 1.4rem;
|
||||
line-height: 1.6rem;
|
||||
color: #505859;
|
||||
font-style: normal;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/**
|
||||
* A <a> link slow may be specified in addition to the <label> and <details>.
|
||||
* When provided, it will appear under the <details> section.
|
||||
*/
|
||||
gaia-switch a {
|
||||
position: relative;
|
||||
top: -0.8rem;
|
||||
font-size: 1.7rem;
|
||||
line-height: 2.4rem;
|
||||
font-weight: 400;
|
||||
color: #35679a;
|
||||
}
|
||||