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.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

View 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);

View 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;
}

View file

@ -0,0 +1,45 @@
(function(exports) {
'use strict';
/**
* ComponentUtils is a utility which allows us to use web components earlier
* than we should be able to by polyfilling and fixing platform deficiencies.
*/
exports.ComponentUtils = {
/**
* Injects a style.css into both the shadow root and outside the shadow
* root so we can style projected content. Bug 992249.
*/
style: function(baseUrl) { if (window.VulpesCompat) { window.VulpesCompat.componentStyle(this, baseUrl).catch(console.error); return; }
var style = document.createElement('style');
var url = baseUrl + 'style.css';
var self = this;
style.setAttribute('scoped', '');
style.innerHTML = '@import url(' + url + ');';
this.appendChild(style);
this.style.visibility = 'hidden';
// Wait for the stylesheet to load before injecting
// it into the shadow-dom. This is to work around
// bug 1003294, let's review once landed.
style.addEventListener('load', function() {
// Put a clone of the stylesheet into the shadow-dom.
// We have to use two <style> nodes, to work around
// the lack of `:host` (bug 992245) and `:content`
// (bug 992249) selectors. Once we have those we
// can do all our styling from a single style-sheet
// within the shadow-dom.
if (self.shadowRoot) {
self.shadowRoot.appendChild(style.cloneNode(true));
}
self.style.visibility = '';
});
}
};
}(window));

View file

@ -0,0 +1,684 @@
/* exported GestureDetector */
'use strict';
/**
* GestureDetector.js: generate events for one and two finger gestures.
*
* A GestureDetector object listens for touch events on a specified
* element and generates higher-level events that describe one and two finger
* gestures on the element.
*
* Supported events:
*
* tap like a click event
* dbltap like dblclick
* pan one finger motion
* swipe when a finger is released following pan events
* holdstart touch and hold. Must set an option to get these.
* holdmove motion after a holdstart event
* holdend when the finger goes up after holdstart/holdmove
* transform 2-finger pinch and twist gestures for scaling and rotation
*
* Each of these events is a bubbling CustomEvent with important details in the
* event.detail field. The event details are not yet stable and are not yet
* documented. See the calls to emitEvent() for details.
*
* To use this library, create a GestureDetector object by passing an element to
* the GestureDetector() constructor and then calling startDetecting() on it.
* The element will be the target of all the emitted gesture events. You can
* also pass an optional object as the second constructor argument. If you're
* interested in holdstart/holdmove/holdend events, pass {holdEvents:true} as
* this second argument. Otherwise they will not be generated.
* If you want to customize the pan threshold, pass {panThreshold:X}
* (X and Y in pixels) in the options argument.
*
* Implementation note: event processing is done with a simple finite-state
* machine. This means that in general, the various kinds of gestures are
* mutually exclusive. You won't get pan events until your finger has
* moved more than a minimum threshold, for example, but it does, the FSM enters
* a new state in which it can emit pan and swipe events and cannot emit hold
* events. Similarly, if you've started a 1 finger pan/swipe gesture and
* accidentally touch with a second finger, you'll continue to get pan events,
* and won't suddenly start getting 2-finger transform events.
*
* This library never calls preventDefault() or stopPropagation on any of the
* events it processes, so the raw touch events should still be
* available for other code to process. It is not clear to me whether this is a
* feature or a bug.
*/
var GestureDetector = (function() {
//
// Constructor
//
function GD(e, options) {
this.element = e;
this.options = options || {};
this.options.panThreshold = this.options.panThreshold || GD.PAN_THRESHOLD;
this.state = initialState;
this.timers = {};
}
//
// Public methods
//
GD.prototype.startDetecting = function() {
var self = this;
eventtypes.forEach(function(t) {
self.element.addEventListener(t, self);
});
};
GD.prototype.stopDetecting = function() {
var self = this;
eventtypes.forEach(function(t) {
self.element.removeEventListener(t, self);
});
};
//
// Internal methods
//
GD.prototype.handleEvent = function(e) {
var handler = this.state[e.type];
if (!handler) {
return;
}
// If this is a touch event handle each changed touch separately
if (e.changedTouches) {
for (var i = 0; i < e.changedTouches.length; i++) {
handler(this, e, e.changedTouches[i]);
// The first changed touch might have changed the state of the FSM.
handler = this.state[e.type];
if (!handler) {
return;
}
}
}
else { // Otherwise, just dispatch the event to the handler
handler(this, e);
}
};
GD.prototype.startTimer = function(type, time) {
this.clearTimer(type);
var self = this;
this.timers[type] = setTimeout(function() {
self.timers[type] = null;
var handler = self.state[type];
if (handler) {
handler(self, type);
}
}, time);
};
GD.prototype.clearTimer = function(type) {
if (this.timers[type]) {
clearTimeout(this.timers[type]);
this.timers[type] = null;
}
};
// Switch to a new FSM state, and call the init() function of that
// state, if it has one. The event and touch arguments are optional
// and are just passed through to the state init function.
GD.prototype.switchTo = function(state, event, touch) {
this.state = state;
if (state.init) {
state.init(this, event, touch);
}
};
GD.prototype.emitEvent = function(type, detail) {
if (!this.target) {
console.error('Attempt to emit event with no target');
return;
}
var event = this.element.ownerDocument.createEvent('CustomEvent');
event.initCustomEvent(type, true, true, detail);
this.target.dispatchEvent(event);
};
//
// Tuneable parameters
//
GD.HOLD_INTERVAL = 1000; // Hold events after 1000 ms
GD.PAN_THRESHOLD = 20; // 20 pixels movement before touch panning
GD.DOUBLE_TAP_DISTANCE = 50;
GD.DOUBLE_TAP_TIME = 500;
GD.VELOCITY_SMOOTHING = 0.5;
// Don't start sending transform events until the gesture exceeds a threshold
GD.SCALE_THRESHOLD = 20; // pixels
GD.ROTATE_THRESHOLD = 22.5; // degrees
// For pans and zooms, we compute new starting coordinates that are part way
// between the initial event and the event that crossed the threshold so that
// the first event we send doesn't cause a big lurch. This constant must be
// between 0 and 1 and says how far along the line between the initial value
// and the new value we pick
GD.THRESHOLD_SMOOTHING = 0.9;
//
// Helpful shortcuts and utility functions
//
var abs = Math.abs, floor = Math.floor, sqrt = Math.sqrt, atan2 = Math.atan2;
var PI = Math.PI;
// The names of events that we need to register handlers for
var eventtypes = [
'touchstart',
'touchmove',
'touchend'
];
// Return the event's timestamp in ms
function eventTime(e) {
// In gecko, synthetic events seem to be in microseconds rather than ms.
// So if the timestamp is much larger than the current time, assue it is
// in microseconds and divide by 1000
var ts = e.timeStamp;
if (ts > 2 * Date.now()) {
return Math.floor(ts / 1000);
} else {
return ts;
}
}
// Return an object containg the space and time coordinates of
// and event and touch. We freeze the object to make it immutable so
// we can pass it in events and not worry about values being changed.
function coordinates(e, t) {
return Object.freeze({
screenX: t.screenX,
screenY: t.screenY,
clientX: t.clientX,
clientY: t.clientY,
timeStamp: eventTime(e)
});
}
// Like coordinates(), but return the midpoint between two touches
function midpoints(e, t1, t2) {
return Object.freeze({
screenX: floor((t1.screenX + t2.screenX) / 2),
screenY: floor((t1.screenY + t2.screenY) / 2),
clientX: floor((t1.clientX + t2.clientX) / 2),
clientY: floor((t1.clientY + t2.clientY) / 2),
timeStamp: eventTime(e)
});
}
// Given coordinates objects c1 and c2, return a new coordinates object
// representing a point and time along the line between those points.
// The position of the point is controlled by the THRESHOLD_SMOOTHING constant
function between(c1, c2) {
var r = GD.THRESHOLD_SMOOTHING;
return Object.freeze({
screenX: floor(c1.screenX + r * (c2.screenX - c1.screenX)),
screenY: floor(c1.screenY + r * (c2.screenY - c1.screenY)),
clientX: floor(c1.clientX + r * (c2.clientX - c1.clientX)),
clientY: floor(c1.clientY + r * (c2.clientY - c1.clientY)),
timeStamp: floor(c1.timeStamp + r * (c2.timeStamp - c1.timeStamp))
});
}
// Compute the distance between two touches
function touchDistance(t1, t2) {
var dx = t2.screenX - t1.screenX;
var dy = t2.screenY - t1.screenY;
return sqrt(dx * dx + dy * dy);
}
// Compute the direction (as an angle) of the line between two touches
// Returns a number d, -180 < d <= 180
function touchDirection(t1, t2) {
return atan2(t2.screenY - t1.screenY,
t2.screenX - t1.screenX) * 180 / PI;
}
// Compute the clockwise angle between direction d1 and direction d2.
// Returns an angle a -180 < a <= 180.
function touchRotation(d1, d2) {
var angle = d2 - d1;
if (angle > 180) {
angle -= 360;
} else if (angle <= -180) {
angle += 360;
}
return angle;
}
// Determine if two taps are close enough in time and space to
// trigger a dbltap event. The arguments are objects returned
// by the coordinates() function.
function isDoubleTap(lastTap, thisTap) {
var dx = abs(thisTap.screenX - lastTap.screenX);
var dy = abs(thisTap.screenY - lastTap.screenY);
var dt = thisTap.timeStamp - lastTap.timeStamp;
return (dx < GD.DOUBLE_TAP_DISTANCE &&
dy < GD.DOUBLE_TAP_DISTANCE &&
dt < GD.DOUBLE_TAP_TIME);
}
//
// The following objects are the states of our Finite State Machine
//
// In this state we're not processing any gestures, just waiting
// for an event to start a gesture and ignoring others
var initialState = {
name: 'initialState',
init: function(d, e, t) {
// When we enter or return to the initial state, clear
// the detector properties that were tracking gestures
// Don't clear d.lastTap here, though. We need it for dbltap events
d.target = null;
d.start = d.last = null;
d.touch1 = d.touch2 = null;
d.vx = d.vy = null;
d.startDistance = d.lastDistance = null;
d.startDirection = d.lastDirection = null;
d.lastMidpoint = null;
d.scaled = d.rotated = null;
// If we were invoked with an event and touch, then process it.
if (e && t && e.type === 'touchstart') {
initialState.touchstart(d, e, t);
}
},
// Switch to the touchstarted state and process the touch event there
touchstart: function(d, e, t) {
d.switchTo(touchStartedState, e, t);
}
};
// One finger is down but we haven't generated any event yet. We're
// waiting to see... If the finger goes up soon, its a tap. If the finger
// stays down and still, its a hold. If the finger moves its a pan/swipe.
// And if a second finger goes down, its a transform
var touchStartedState = {
name: 'touchStartedState',
init: function(d, e, t) {
// Remember the target of the event
d.target = e.target;
// Remember the id of the touch that started
d.touch1 = t.identifier;
// Get the coordinates of the touch
d.start = d.last = coordinates(e, t);
// Start a timer for a hold
// If we're doing hold events, start a timer for them
if (d.options.holdEvents) {
d.startTimer('holdtimeout', GD.HOLD_INTERVAL);
}
},
touchstart: function(d, e, t) {
// If another finger goes down in this state, then
// go to transform state to start 2-finger gestures.
d.clearTimer('holdtimeout');
if (e.touches.length > 1) { // verify that we have 2 fingers
d.switchTo(transformState, e, t);
}
else {
// If Gecko fails to deliver a touchend event to us (bug 1162771, e.g.)
// then we might get two touchstart events in a row and end up here
// when there is actually only one finger currently on the screen.
// In that case, we switch back to the initial state and process
// this touch from that state. (We don't switch directly to
// touchStartedState because we need to reset things in the
// initialState init() function.)
console.warn('Ignoring missing touchend event. See bug 1162771.');
d.switchTo(initialState, e, t);
}
},
touchmove: function(d, e, t) {
// Ignore any touches but the initial one
// This could happen if there was still a finger down after
// the end of a previous 2-finger gesture, e.g.
if (t.identifier !== d.touch1) {
return;
}
if (abs(t.screenX - d.start.screenX) > d.options.panThreshold ||
abs(t.screenY - d.start.screenY) > d.options.panThreshold) {
d.clearTimer('holdtimeout');
d.switchTo(panStartedState, e, t);
}
},
touchend: function(d, e, t) {
// Ignore any touches but the initial one
if (t.identifier !== d.touch1) {
return;
}
// If there was a previous tap that was close enough in time
// and space, then emit a 'dbltap' event
if (d.lastTap && isDoubleTap(d.lastTap, d.start)) {
d.emitEvent('tap', d.start);
d.emitEvent('dbltap', d.start);
// clear the lastTap property, so we don't get another one
d.lastTap = null;
}
else {
// Emit a 'tap' event using the starting coordinates
// as the event details
d.emitEvent('tap', d.start);
// Remember the coordinates of this tap so we can detect double taps
d.lastTap = coordinates(e, t);
}
// In either case clear the timer and go back to the initial state
d.clearTimer('holdtimeout');
d.switchTo(initialState);
},
holdtimeout: function(d) {
d.switchTo(holdState);
}
};
// A single touch has moved enough to exceed the pan threshold and now
// we're going to generate pan events after each move and a swipe event
// when the touch ends. We ignore any other touches that occur while this
// pan/swipe gesture is in progress.
var panStartedState = {
name: 'panStartedState',
init: function(d, e, t) {
// Panning doesn't start until the touch has moved more than a
// certain threshold. But we don't want the pan to have a jerky
// start where the first event is a big distance. So proceed as
// pan actually started at a point along the path between the
// first touch and this current touch.
d.start = d.last = between(d.start, coordinates(e, t));
// If we transition into this state with a touchmove event,
// then process it with that handler. If we don't do this then
// we can end up with swipe events that don't know their velocity
if (e.type === 'touchmove') {
panStartedState.touchmove(d, e, t);
}
},
touchmove: function(d, e, t) {
// Ignore any fingers other than the one we're tracking
if (t.identifier !== d.touch1) {
return;
}
// Each time the touch moves, emit a pan event but stay in this state
var current = coordinates(e, t);
d.emitEvent('pan', {
absolute: {
dx: current.screenX - d.start.screenX,
dy: current.screenY - d.start.screenY
},
relative: {
dx: current.screenX - d.last.screenX,
dy: current.screenY - d.last.screenY
},
position: current
});
// Track the pan velocity so we can report this with the swipe
// Use a exponential moving average for a bit of smoothing
// on the velocity
var dt = current.timeStamp - d.last.timeStamp;
var vx = (current.screenX - d.last.screenX) / dt;
var vy = (current.screenY - d.last.screenY) / dt;
if (d.vx == null) { // first time; no average
d.vx = vx;
d.vy = vy;
}
else {
d.vx = d.vx * GD.VELOCITY_SMOOTHING +
vx * (1 - GD.VELOCITY_SMOOTHING);
d.vy = d.vy * GD.VELOCITY_SMOOTHING +
vy * (1 - GD.VELOCITY_SMOOTHING);
}
d.last = current;
},
touchend: function(d, e, t) {
// Ignore any fingers other than the one we're tracking
if (t.identifier !== d.touch1) {
return;
}
// Emit a swipe event when the finger goes up.
// Report start and end point, dx, dy, dt, velocity and direction
var current = coordinates(e, t);
var dx = current.screenX - d.start.screenX;
var dy = current.screenY - d.start.screenY;
// angle is a positive number of degrees, starting at 0 on the
// positive x axis and increasing clockwise.
var angle = atan2(dy, dx) * 180 / PI;
if (angle < 0) {
angle += 360;
}
// Direction is 'right', 'down', 'left' or 'up'
var direction;
if (angle >= 315 || angle < 45) {
direction = 'right';
} else if (angle >= 45 && angle < 135) {
direction = 'down';
} else if (angle >= 135 && angle < 225) {
direction = 'left';
} else if (angle >= 225 && angle < 315) {
direction = 'up';
}
d.emitEvent('swipe', {
start: d.start,
end: current,
dx: dx,
dy: dy,
dt: e.timeStamp - d.start.timeStamp,
vx: d.vx,
vy: d.vy,
direction: direction,
angle: angle
});
// Go back to the initial state
d.switchTo(initialState);
}
};
// We enter this state if the user touches and holds for long enough
// without moving much. When we enter we emit a holdstart event. Motion
// after the holdstart generates holdmove events. And when the touch ends
// we generate a holdend event. holdmove and holdend events can be used
// kind of like drag and drop events in a mouse-based UI. Currently,
// these events just report the coordinates of the touch. Do we need
// other details?
var holdState = {
name: 'holdState',
init: function(d) {
d.emitEvent('holdstart', d.start);
},
touchmove: function(d, e, t) {
var current = coordinates(e, t);
d.emitEvent('holdmove', {
absolute: {
dx: current.screenX - d.start.screenX,
dy: current.screenY - d.start.screenY
},
relative: {
dx: current.screenX - d.last.screenX,
dy: current.screenY - d.last.screenY
},
position: current
});
d.last = current;
},
touchend: function(d, e, t) {
var current = coordinates(e, t);
d.emitEvent('holdend', {
start: d.start,
end: current,
dx: current.screenX - d.start.screenX,
dy: current.screenY - d.start.screenY
});
d.switchTo(initialState);
}
};
// We enter this state if a second touch starts before we start
// recoginzing any other gesture. As the touches move we track the
// distance and angle between them to report scale and rotation values
// in transform events.
var transformState = {
name: 'transformState',
init: function(d, e, t) {
// Remember the id of the second touch
d.touch2 = t.identifier;
// Get the two Touch objects
var t1 = e.touches.identifiedTouch(d.touch1);
var t2 = e.touches.identifiedTouch(d.touch2);
// Compute and remember the initial distance and angle
d.startDistance = d.lastDistance = touchDistance(t1, t2);
d.startDirection = d.lastDirection = touchDirection(t1, t2);
// Don't start emitting events until we're past a threshold
d.scaled = d.rotated = false;
},
touchmove: function(d, e, t) {
// Ignore touches we're not tracking
if (t.identifier !== d.touch1 && t.identifier !== d.touch2) {
return;
}
// Get the two Touch objects
var t1 = e.touches.identifiedTouch(d.touch1);
var t2 = e.touches.identifiedTouch(d.touch2);
// Compute the new midpoints, distance and direction
var midpoint = midpoints(e, t1, t2);
var distance = touchDistance(t1, t2);
var direction = touchDirection(t1, t2);
var rotation = touchRotation(d.startDirection, direction);
// Check all of these numbers against the thresholds. Otherwise
// the transforms are too jittery even when you try to hold your
// fingers still.
if (!d.scaled) {
if (abs(distance - d.startDistance) > GD.SCALE_THRESHOLD) {
d.scaled = true;
d.startDistance = d.lastDistance =
floor(d.startDistance +
GD.THRESHOLD_SMOOTHING * (distance - d.startDistance));
} else {
distance = d.startDistance;
}
}
if (!d.rotated) {
if (abs(rotation) > GD.ROTATE_THRESHOLD) {
d.rotated = true;
} else {
direction = d.startDirection;
}
}
// If nothing has exceeded the threshold yet, then we
// don't even have to fire an event.
if (d.scaled || d.rotated) {
// The detail field for the transform gesture event includes
// 'absolute' transformations against the initial values and
// 'relative' transformations against the values from the last
// transformgesture event.
d.emitEvent('transform', {
absolute: { // transform details since gesture start
scale: distance / d.startDistance,
rotate: touchRotation(d.startDirection, direction)
},
relative: { // transform since last gesture change
scale: distance / d.lastDistance,
rotate: touchRotation(d.lastDirection, direction)
},
midpoint: midpoint
});
d.lastDistance = distance;
d.lastDirection = direction;
d.lastMidpoint = midpoint;
}
},
touchend: function(d, e, t) {
// If either finger goes up, we're done with the gesture.
// The user might move that finger and put it right back down
// again to begin another 2-finger gesture, so we can't go
// back to the initial state while one of the fingers remains up.
// On the other hand, we can't go back to touchStartedState because
// that would mean that the finger left down could cause a tap or
// pan event. So we need an afterTransform state that waits for
// a finger to come back down or the other finger to go up.
if (t.identifier === d.touch2) {
d.touch2 = null;
} else if (t.identifier === d.touch1) {
d.touch1 = d.touch2;
d.touch2 = null;
} else {
return; // It was a touch we weren't tracking
}
// If we emitted any transform events, now we need to emit
// a transformend event to end the series. The details of this
// event use the values from the last touchmove, and the
// relative amounts will 1 and 0, but they are included for
// completeness even though they are not useful.
if (d.scaled || d.rotated) {
d.emitEvent('transformend', {
absolute: { // transform details since gesture start
scale: d.lastDistance / d.startDistance,
rotate: touchRotation(d.startDirection, d.lastDirection)
},
relative: { // nothing has changed relative to the last touchmove
scale: 1,
rotate: 0
},
midpoint: d.lastMidpoint
});
}
d.switchTo(afterTransformState);
}
};
// We did a tranform and one finger went up. Wait for that finger to
// come back down or the other finger to go up too.
var afterTransformState = {
name: 'afterTransformState',
touchstart: function(d, e, t) {
d.switchTo(transformState, e, t);
},
touchend: function(d, e, t) {
if (t.identifier === d.touch1) {
d.switchTo(initialState);
}
}
};
return GD;
}());

View file

@ -0,0 +1,428 @@
/* ----------------------------------
* Buttons
* ---------------------------------- */
.button::-moz-focus-inner,
.bb-button::-moz-focus-inner,
button::-moz-focus-inner {
border: none;
outline: none;
}
button,
.bb-button,
.button {
font-family: sans-serif;
font-style: italic;
width: 100%;
height: 4rem;
margin: 0 0 1rem;
padding: 0 1.2rem;
box-sizing: border-box;
display: inline-block;
vertical-align: middle;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
background: #d8d8d8;
border: none;
border-radius: 2rem;
font-weight: normal;
font-size: 1.6rem;
line-height: 4rem;
color: #333;
text-align: center;
text-decoration: none;
outline: none;
}
/* Recommend */
button.recommend,
.bb-button.recommend {
background-color: #00caf2;
color: #fff;
}
/* Danger */
button.danger,
.danger.bb-button {
background-color: #e51e1e;
color: #fff;
}
/* Pressed */
button:active,
.bb-button:active,
.button:active {
background-color: #b2f2ff;
color: #fff;
}
/* Icons */
button[data-icon],
.bb-button[data-icon],
.button[data-icon] {
position: relative;
}
button[data-icon]:before,
.bb-button[data-icon]:before,
.button[data-icon]:before {
position: absolute;
top: 50%;
margin-top: -1.5rem;
offset-inline-end: 1.5rem;
line-height: 3rem;
}
button[data-icon]:active:before,
.bb-button[data-icon]:active:before,
.button[data-icon]:active:before {
color: #fff;
}
/* Pressed with dark skin */
.skin-dark button:active,
.skin-dark .bb-button:active,
.skin-dark .button:active {
background-color: #00aacc;
}
/* Disabled */
button[disabled],
.bb-button[aria-disabled="true"],
.button[aria-disabled="true"] {
background-color: rgba(0,0,0,0.05);
color: #c7c7c7;
pointer-events: none;
}
button[disabled].recommend,
.bb-button[aria-disabled="true"].recommend,
.button[aria-disabled="true"].recommend {
background-color: #97cbd5;
color: rgba(255,255,255,0.5);
}
button[disabled].danger,
.bb-button[aria-disabled="true"].danger,
.button[aria-disabled="true"].danger {
background-color: #eb7474;
color: rgba(255,255,255,0.5);
}
/* Disabled with dark background */
.skin-dark button[disabled],
.skin-dark .button[aria-disabled="true"],
.skin-dark .bb-button[aria-disabled="true"] {
background-color: #565656;
color: rgba(255,255,255,0.4);
}
.skin-dark button[disabled].recommend,
.skin-dark .button[aria-disabled="true"].recommend,
.skin-dark .bb-button[aria-disabled="true"].recommend {
background-color: #006579;
}
.skin-dark button[disabled].danger,
.skin-dark .button[aria-disabled="true"].danger,
.skin-dark .bb-button[aria-disabled="true"].danger {
background-color: #730f0f;
}
button[disabled]::-moz-selection,
.button[aria-disabled="true"]::-moz-selection,
.bb-button[aria-disabled="true"]::-moz-selection {
-moz-user-select: none;
}
/* ----------------------------------
* Buttons inside lists
* ---------------------------------- */
li button,
li .bb-button,
li .button {
position: relative;
border: 0.1rem solid #c7c7c7;
background: rgba(0,0,0,0.05);
margin: 0 0 1rem;
overflow: hidden;
border-radius: 0;
display: flex;
height: auto;
min-height: 4rem;
text-overflow: initial;
white-space: normal;
line-height: 2rem;
padding: 1rem 1.2rem;
}
html[dir="ltr"] li button,
html[dir="ltr"] li .bb-button,
html[dir="ltr"] li .button {
text-align: left;
}
html[dir="rtl"] li button,
html[dir="rtl"] li .bb-button,
html[dir="rtl"] li .button {
text-align: right;
}
/* Press */
li .bb-button:active:after,
li .button:active:after,
li button:active:after {
opacity: 0;
}
/* Disabled */
li button:disabled,
li .bb-button[aria-disabled="true"],
li .button[aria-disabled="true"] {
opacity: 0.5;
}
/* Icons */
li button.icon,
li .bb-button.icon,
li .button.icon {
padding-inline-end: 4rem;
}
li button.icon:before,
li .bb-button.icon:before,
li .button.icon:before {
content: "";
width: 3rem;
height: 3rem;
position: absolute;
top: 50%;
offset-inline-end: 0.5rem;
margin-top: -1.5rem;
background: transparent no-repeat center center / 100% auto;
pointer-events: none;
}
li button[data-icon]:before,
li .bb-button[data-icon]:before,
li .button[data-icon]:before {
offset-inline-end: 1rem;
}
li button.icon-view:active,
li .bb-button.icon-view:active,
li .button.icon-view:active {
background-color: #b2f2ff;
}
li button[data-icon="expand"]:before,
li .bb-button[data-icon="expand"]:before,
li .button[data-icon="expand"]:before {
color: #00aac5;
top: unset;
bottom: 0;
}
li button[data-icon="expand"][disabled]:before,
li .bb-button[data-icon="expand"][aria-disabled="true"]:before,
li .button[data-icon="expand"][aria-disabled="true"]:before {
color: #A9A9A9;
}
li button[data-icon="forward"]:before,
li .bb-button[data-icon="forward"]:before,
li .button[data-icon="forward"]:before {
color: #686f72;
}
/* Getting more space for text, as icon is shorter */
li button.icon-dialog,
li .bb-button.icon-dialog,
li .button.icon-dialog {
padding-inline-end: 3rem;
}
li button.icon-dialog:before,
li .bb-button.icon-dialog:before,
li .button.icon-dialog:before {
width: 0;
height: 0;
top: auto;
offset-inline-end: 0.8rem;
bottom: 0.5rem;
border-top: 0.7rem solid transparent;
border-bottom: 0.7rem solid transparent;
border-inline-start: 0.7rem solid #00aac5;
z-index: 1;
}
html[dir="ltr"] li button.icon-dialog:before,
html[dir="ltr"] li .bb-button.icon-dialog:before,
html[dir="ltr"] li .button.icon-dialog:before {
transform: rotate(45deg);
}
html[dir="rtl"] li button.icon-dialog:before,
html[dir="rtl"] li .bb-button.icon-dialog:before,
html[dir="rtl"] li .button.icon-dialog:before {
transform: rotate(-45deg);
}
li button.icon-dialog:disabled:before,
li .bb-button[aria-disabled="true"].icon-dialog:before,
li .button[aria-disabled="true"].icon-dialog:before {
border-inline-start: 0.7rem solid #a9a9a9;
}
/* ----------------------------------
* Theme: Dark
* ---------------------------------- */
.skin-dark li button,
.skin-dark li .bb-button,
.skin-dark li .button {
background-color: #454545;
border: none;
color: #fff;
font-weight: normal;
}
.skin-dark li button:active,
.skin-dark li .button:active,
.skin-dark li .bb-button:active {
background-color: #00aacc;
}
.skin-dark li button.icon-view:active,
.skin-dark li .button.icon-view:active,
.skin-dark li .bb-button.icon-view:active {
background-color: #00aacc;
}
.skin-dark li button.icon-dialog:active:before,
.skin-dark li .bb-button.icon-dialog:active:before,
.skin-dark li .button.icon-dialog:active:before {
border-inline-start: 0.7rem solid #b2f2ff;
}
.skin-dark li button:disabled,
.skin-dark li .bb-button[aria-disabled="true"],
.skin-dark li .button[aria-disabled="true"] {
background-color: #454545;
opacity: 0.5;
}
/* Inputs inside of .button */
.button input,
body[role="application"] .bb-button input,
body[role="application"] .button input {
border: 0;
background: none;
}
/* select */
select {
width: 100%;
box-sizing: border-box;
font-family: sans-serif;
font-style: italic;
font-size: 1.6rem;
color: #333;
margin: 0 0 1rem;
padding: 0;
padding-inline-start: 1.1rem;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
height: 4rem;
border: 0.1rem solid #c7c7c7;
background: rgba(0,0,0,0.05);
}
.skin-dark select {
background-color: rgba(87, 87, 87, 0.8);
border: none;
color: #fff;
}
/* remove dotted outline */
select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #333;
}
.skin-dark select:-moz-focusring {
text-shadow: 0 0 0 #fff;
}
/* Hides dropdown arrow until bug #649849 is fixed */
.bb-button.icon select,
.button.icon select,
.bb-button[data-icon] select,
.button[data-icon] select {
position: absolute;
top: -0.6rem;
offset-inline-start: 0;
width: calc(100% + 3rem);
height: 100%;
margin: 0;
padding: 0;
padding-inline-end: 5rem;
text-indent: 0;
font-weight: 400;
font-size: 1.7rem;
color: rgba(0,0,0,0);
border: none;
background: none;
}
/**
* The select element uses the text color to determine the color of the outline.
* We put a text shadow with needed offset and no blur, so that replaces the text.
*/
html[dir="ltr"] .bb-button.icon select,
html[dir="ltr"] .button.icon select,
html[dir="ltr"] .bb-button[data-icon] select,
html[dir="ltr"] .button[data-icon] select,
html[dir="ltr"] .bb-button.icon-dialog select,
html[dir="ltr"] .button.icon-dialog select {
text-shadow: 1rem 0.5rem 0 #333;
}
html[dir="rtl"] .bb-button.icon select,
html[dir="rtl"] .button.icon select,
html[dir="rtl"] .bb-button[data-icon] select,
html[dir="rtl"] .button[data-icon] select,
html[dir="rtl"] .bb-button.icon-dialog select,
html[dir="rtl"] .button.icon-dialog select {
text-shadow: -1rem 0.5rem 0 #333;
}
.bb-button.icon select option,
.button.icon select option,
.bb-button[data-icon] select option,
.button[data-icon] select option {
color: #000;
border: 0;
padding: 0.6rem 1.3rem;
text-shadow: 0 0 0 rgba(0,0,0,0);
}
.bb-button.icon-dialog,
.button.icon-dialog {
overflow: hidden;
}
html[dir="ltr"] .skin-dark .bb-button.icon select,
html[dir="ltr"] .skin-dark .button.icon select,
html[dir="ltr"] .skin-dark .bb-button[data-icon] select,
html[dir="ltr"] .skin-dark .button[data-icon] select,
html[dir="ltr"] .skin-dark .bb-button.icon-dialog select,
html[dir="ltr"] .skin-dark .button.icon-dialog select {
text-shadow: 1rem 0.5rem 0 #fff;
}
html[dir="rtl"] .skin-dark .bb-button.icon select,
html[dir="rtl"] .skin-dark .button.icon select,
html[dir="rtl"] .skin-dark .bb-button[data-icon] select,
html[dir="rtl"] .skin-dark .button[data-icon] select,
html[dir="rtl"] .skin-dark .bb-button.icon-dialog select,
html[dir="rtl"] .skin-dark .button.icon-dialog select {
text-shadow: -1rem 0.5rem 0 #fff;
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><path fill="#667174" fill-opacity=".7" d="m 18.2995,19.66 -5.056,-5.057 5.056,-5.056 c -0.31,-0.516 -0.62,-1.032 -0.93,-1.34 l -5.672,5.673 v 1.652 l 5.675,5.676 c 0.31,-0.515 0.722,-0.928 0.93,-1.547 z"/></svg>

After

Width:  |  Height:  |  Size: 294 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><path fill="#667174" fill-opacity=".7" d="m 11.698,19.66 5.056,-5.057 -5.056,-5.056 c 0.31,-0.516 0.62,-1.032 0.93,-1.34 L 18.3,13.88 v 1.652 l -5.675,5.676 c -0.31,-0.515 -0.722,-0.928 -0.93,-1.547 z"/></svg>

After

Width:  |  Height:  |  Size: 292 B

View file

@ -0,0 +1,280 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="utf-8">
<title>Buttons</title>
<link rel="stylesheet" href="../buttons.css">
<link rel="stylesheet" href="../../elements/gaia-icons/gaia-icons-embedded.css">
<link rel="stylesheet" href="../../elements/gaia-icons/bidi-helper.css">
<!--
- These <style> and <script> elements are only used for the example code,
- they are not needed for the real case.
-->
<style>
html, body {
margin: 0;
padding: 0;
font-size: 10px;
background-color: #fff;
}
label.bb-docs {
font-family: sans-serif;
font-size: 1.2rem;
margin-left: 1.5rem;
}
h2.bb-docs {
font-size: 1.8rem;
font-weight: 300;
color: #666;
margin: -0.1rem 0 0;
background-color: #f5f5f5;
padding: 0.4rem 3rem;
border: solid 0.1rem #e8e8e8;
font-family: sans-serif;
}
div.bb-docs {
padding: 1.5rem;
}
div.bb-docs.skin-organic {
background: #f4f4f4;
}
div.bb-docs.skin-dark {
background: #000;
}
ul {
padding: 0;
margin: 0;
list-style: none;
}
body[role="application"] > [role="region"] {
height: 100%;
position: relative;
}
[data-icon]:before {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</style>
<script>
window.onload = function() {
document.getElementById('dir').checked = false;
};
</script>
</head>
<body role="application">
<p dir="ltr">
<label class="bb-docs">
<input id="dir" type="checkbox" checked="false"
onchange="document.documentElement.dir = this.checked ? 'rtl' : 'ltr'">
RTL mode
</label>
</p>
<h2 class="bb-docs">Special buttons</h2>
<div class="bb-docs skin-organic">
<button>Default</button>
<button class="recommend">Recommend</button>
<button class="danger">Danger</button>
</div>
<h2 class="bb-docs">Buttons with icons</h2>
<div class="bb-docs skin-organic">
<button data-icon="forward" aria-label="forward" data-l10n-id="">Default</button>
<button data-icon="forward" aria-label="forward" data-l10n-id="" class="recommend">Recommend</button>
<button data-icon="forward" aria-label="forward" data-l10n-id="" class="danger">Danger</button>
<button data-icon="forward-light" aria-label="forward-light" data-l10n-id="">Default</button>
<button data-icon="back" aria-label="back" data-l10n-id="">Default</button>
<button data-icon="back-light" aria-label="back-light" data-l10n-id="">Default</button>
</div>
<h2 class="bb-docs">Disabled</h2>
<div class="bb-docs skin-organic">
<button disabled>Default</button>
<a href="#" role="button" aria-disabled="true" class="recommend bb-button">Recommend</a>
<button disabled class="danger">Danger</button>
</div>
<h2 class="bb-docs">Skin dark</h2>
<div class="bb-docs skin-dark">
<button>Default</button>
<button class="recommend">Recommend</button>
<button class="danger">Danger</button>
</div>
<h2 class="bb-docs">Disabled</h2>
<div class="bb-docs skin-dark">
<button disabled>Default</button>
<a href="#" role="button" aria-disabled="true" class="recommend bb-button">Recommend</a>
<button disabled class="danger">Danger</button>
</div>
<h2 class="bb-docs">List buttons</h2>
<div class="bb-docs skin-organic">
<ul>
<li>
<button>Default</button>
</li>
<li>
<button disabled>Disabled</button>
</li>
<li>
<button class="icon icon-view">
Icon view button
</button>
</li>
<li>
<button class="icon icon-dialog">
Icon dialog button
</button>
</li>
<li>
<span class="button icon icon-dialog">
<select>
<option selected>Icon dialog with options</option>
<option>option 1</option>
<option>option 2</option>
<option>option 3</option>
</select>
</span>
</li>
<li>
<button class="icon icon-dialog" disabled>
Icon dialog button disabled
</button>
</li>
<li>
<button data-icon="forward" aria-label="forward" data-l10n-id="">
Side navigation
</button>
</li>
<li>
<button disabled data-icon="forward" aria-label="forward" data-l10n-id="">
Side navigation
</button>
</li>
<li>
<a role="button" data-icon="expand" class="bb-button" aria-label="expand" data-l10n-id="">
Tuesday Sept. 18, 2012
</a>
</li>
<li>
<a role="button" aria-disabled="true" data-icon="expand" class="bb-button" aria-label="expand" data-l10n-id="">
Tuesday Sept. 18, 2012
</a>
</li>
</ul>
</div>
<h2 class="bb-docs">Skin Dark</h2>
<div class="bb-docs skin-dark">
<ul>
<li>
<button>Default</button>
</li>
<li>
<button disabled>Disabled</button>
</li>
<li>
<button class="icon icon-dialog">
Dark icon dialog button
</button>
</li>
<li>
<button data-icon="forward" aria-label="forward" data-l10n-id="">
Side navigation
</button>
</li>
<li>
<button disabled data-icon="forward" aria-label="forward" data-l10n-id="">
Side navigation
</button>
</li>
<li>
<a role="button" data-icon="expand" class="bb-button" aria-label="expand" data-l10n-id="">
Tuesday Sept. 18, 2012
</a>
</li>
<li>
<a role="button" aria-disabled="true" data-icon="expand" class="bb-button" aria-label="expand" data-l10n-id="">
Tuesday Sept. 18, 2012
</a>
</li>
</ul>
</div>
<h2 class="bb-docs">Select</h2>
<div class="bb-docs">
<select>
<option>option 1</option>
<option>option 2</option>
</select>
</div>
<h2 class="bb-docs">Fake select</h2>
<div class="bb-docs">
<ul>
<li>
<span class="bb-button" data-icon="expand" aria-label="expand" data-l10n-id="">
<select>
<option>option 1</option>
<option>option 2</option>
</select>
</span>
</li>
</ul>
</div>
<h2 class="bb-docs">Disabled select</h2>
<div class="bb-docs">
<ul>
<li>
<span aria-disabled="true" class="bb-button" data-icon="expand" aria-label="expand" data-l10n-id="">
<select>
<option>option 1</option>
<option>option 2</option>
</select>
</span>
</li>
</ul>
</div>
<h2 class="bb-docs">Skin dark</h2>
<div class="bb-docs skin-dark">
<select>
<option>option 1</option>
<option>option 2</option>
</select>
</div>
<h2 class="bb-docs">Fake select</h2>
<div class="bb-docs skin-dark">
<ul>
<li>
<span class="bb-button" data-icon="expand" aria-label="expand" data-l10n-id="">
<select>
<option>option 1</option>
<option>option 2</option>
</select>
</span>
</li>
<li>
<span aria-disabled="true" class="bb-button" data-icon="expand" aria-label="expand" data-l10n-id="">
<select>
<option>option 1</option>
<option>option 2</option>
</select>
</span>
</li>
</ul>
</div>
</body>
</html>

View file

@ -0,0 +1,378 @@
/* -------------------------------------------------------------------
HEADERS: layout
Form factor or Skin dependent styles should NOT be defined here.
------------------------------------------------------------------- */
section[role="region"] > header:first-child {
position: relative;
display: block;
z-index: 10;
padding: 0;
height: 5rem;
border: none;
}
section[role="region"] > header:first-child h1 {
font-size: 2.3rem;
line-height: 5rem;
white-space: nowrap;
text-overflow: ellipsis;
display: block;
overflow: hidden;
margin: 0;
padding: 0 1rem;
height: 100%;
font-weight: 300;
font-style: italic;
text-align: center;
}
section[role="region"] > header:first-child h1 em {
font-weight: 400;
font-size: 1.5rem;
line-height: 1em;
font-style: normal;
}
section[role="region"] > header:first-child menu {
height: 100%;
padding: 0;
margin: 0;
}
html[dir="ltr"] section[role="region"] > header:first-child menu {
float: right;
}
html[dir="rtl"] section[role="region"] > header:first-child menu {
float: left;
}
/* ----------------------------------
Buttons
---------------------------------- */
section[role="region"] > header:first-child a,
section[role="region"] > header:first-child button {
box-sizing: border-box;
position: relative;
display: block;
overflow: hidden;
min-width: 5rem;
width: auto;
height: 5rem;
border: none;
background: none;
padding: 0 1rem;
margin: 0;
font-weight: 400;
font-size: 1.5rem;
line-height: 5rem;
border-radius: 0;
text-decoration: none;
text-align: center;
text-shadow: none;
font-style: italic;
}
html[dir="ltr"] section[role="region"] > header:first-child a,
html[dir="ltr"] section[role="region"] > header:first-child button {
float: left;
}
html[dir="rtl"] section[role="region"] > header:first-child a,
html[dir="rtl"] section[role="region"] > header:first-child button {
float: right;
}
/* Pressed state */
section[role="region"] > header:first-child a:focus {
outline: none;
}
section[role="region"] > header:first-child button::-moz-focus-inner {
outline: none;
border: none;
margin-top: -0.2rem; /* To fix line-height bug (697451) */
padding: 0;
}
/* Disabled state */
section[role="region"] > header:first-child a[aria-disabled="true"],
section[role="region"] > header:first-child button[disabled] {
opacity: 0.3;
pointer-events: none;
}
/* ----------------------------------
Icons
---------------------------------- */
section[role="region"] > header:first-child .icon {
display: block;
width: 3rem;
height: 5rem;
background: transparent no-repeat center / 3rem auto;
font-size: 0;
}
/* ----------------------------------
Subheader
---------------------------------- */
section[role="region"] > header {
z-index: 0;
height: auto;
}
section[role="region"] header h2 {
margin: 0;
padding: 0.8rem 3rem;
font-weight: 400;
font-size: 1.5rem;
line-height: 1.8rem;
}
/* -----------------------------------------------------------------
HEADER SKIN: default
Default values in case we are not overriding them using
class="skin-*"
----------------------------------------------------------------- */
section[role="region"] > header:first-child {
color: #fff;
background-color: #f97c17;
}
section[role="region"] > header:first-child h1 {
color: #fff;
}
section[role="region"] > header:first-child a,
section[role="region"] > header:first-child button {
color: rgba(0,0,0,0.6);
}
section[role="region"] > header:first-child a:active,
section[role="region"] > header:first-child button:active,
section[role="region"] > header:first-child a:hover,
section[role="region"] > header:first-child button:hover {
background-color: rgba(0,0,0,0.07);
}
section[role="region"] > header:first-child a:focus,
section[role="region"] > header:first-child button:focus {
background-color: transparent;
}
/* ----------------------------------
Icons
---------------------------------- */
section[role="region"] > header:first-child .icon-add {
background-image: url(headers/images/icons/add.png);
}
section[role="region"] > header:first-child .icon-compose {
background-image: url(headers/images/icons/compose.png);
}
html[dir="ltr"] section[role="region"] > header:first-child .icon-edit {
background-image: url(headers/images/icons/edit.png);
}
html[dir="rtl"] section[role="region"] > header:first-child .icon-edit {
background-image: url(headers/images/icons/edit-rtl.png);
}
html[dir="ltr"] section[role="region"] > header:first-child .icon-send {
background-image: url(headers/images/icons/send.png);
}
html[dir="rtl"] section[role="region"] > header:first-child .icon-send {
background-image: url(headers/images/icons/send_rtl.png);
}
section[role="region"] > header:first-child .icon-close {
background-image: url(headers/images/icons/close.png);
}
html[dir="ltr"] section[role="region"] > header:first-child .icon-back {
background-image: url(headers/images/icons/left.png);
}
html[dir="rtl"] section[role="region"] > header:first-child .icon-back {
background-image: url(headers/images/icons/right.png);
}
section[role="region"] > header:first-child .icon-menu {
background-image: url(headers/images/icons/menu.png);
}
section[role="region"] > header:first-child .icon-user {
background-image: url(headers/images/icons/user.png);
}
section[role="region"] > header:first-child .icon-up {
background-image: url(headers/images/icons/up.png);
}
section[role="region"] > header:first-child .icon-down {
background-image: url(headers/images/icons/down.png);
}
section[role="region"] > header:first-child .icon-options {
background-image: url(headers/images/icons/options.png);
}
/* ----------------------------------
Subheader
---------------------------------- */
section[role="region"] header h2 {
color: #424242;
border-bottom: solid 0.1rem #e6e6e6;
}
/* -----------------------------------------------------------------
HEADER SKIN: comms
.skin-comms will override default values
----------------------------------------------------------------- */
.skin-comms section[role="region"] > header:first-child,
section[role="region"].skin-comms > header:first-child {
background-color: #00adad;
}
.skin-comms section[role="region"] > header:first-child a,
.skin-comms section[role="region"] > header:first-child button,
section[role="region"].skin-comms > header:first-child a,
section[role="region"].skin-comms > header:first-child button {
color: rgba(0,0,0,0.5);
}
.skin-comms section[role="region"] > header:first-child a:active,
.skin-comms section[role="region"] > header:first-child button:active,
.skin-comms section[role="region"] > header:first-child a:hover,
.skin-comms section[role="region"] > header:first-child button:hover,
section[role="region"].skin-comms > header:first-child a:active,
section[role="region"].skin-comms > header:first-child button:active,
section[role="region"].skin-comms > header:first-child a:hover,
section[role="region"].skin-comms > header:first-child button:hover {
background-color: rgba(0,0,0,0.1);
}
.skin-comms section[role="region"] > header:first-child a:focus,
.skin-comms section[role="region"] > header:first-child button:focus,
section[role="region"].skin-comms > header:first-child a:focus,
section[role="region"].skin-comms > header:first-child button:focus {
background-color: transparent;
}
/* -----------------------------------------------------------------
HEADER SKIN: dark
.skin-dark will override default values
----------------------------------------------------------------- */
section[role="region"].skin-dark > header:first-child,
.skin-dark > section[role="region"] > header:first-child {
background-color: #242d33;
}
.skin-dark section[role="region"] > header:first-child a,
.skin-dark section[role="region"] > header:first-child button,
section[role="region"].skin-dark > header:first-child a,
section[role="region"].skin-dark > header:first-child button {
color: #00aac5;
}
.skin-dark section[role="region"] > header:first-child a:active,
.skin-dark section[role="region"] > header:first-child button:active,
.skin-dark section[role="region"] > header:first-child a:hover,
.skin-dark section[role="region"] > header:first-child button:hover,
section[role="region"].skin-dark > header:first-child a:active,
section[role="region"].skin-dark > header:first-child button:active,
section[role="region"].skin-dark > header:first-child a:hover,
section[role="region"].skin-dark > header:first-child button:hover {
background-color: rgba(0,0,0,0.4);
}
.skin-dark section[role="region"] > header:first-child a:focus,
.skin-dark section[role="region"] > header:first-child button:focus,
section[role="region"].skin-dark > header:first-child a:focus,
section[role="region"].skin-dark > header:first-child button:focus {
background-color: transparent;
}
section[role="region"].skin-dark header h2,
.skin-dark > section[role="region"] header h2 {
background-color: #2c353b;
color: #fff;
border: none;
}
/* -----------------------------------------------------------------
HEADER SKIN: organic
.skin-organic will override default values
----------------------------------------------------------------- */
section[role="region"].skin-organic > header:first-child,
.skin-organic section[role="region"] > header:first-child {
color: #868692;
background-color: #f4f4f4;
}
section[role="region"].skin-organic > header:first-child h1,
.skin-organic section[role="region"] > header:first-child h1 {
color: #868692;
}
section[role="region"].skin-organic > header:first-child a,
section[role="region"].skin-organic > header:first-child button,
.skin-organic section[role="region"] > header:first-child a,
.skin-organic section[role="region"] > header:first-child button {
color: #00aac5;
}
section[role="region"].skin-organic > header:first-child a:focus,
section[role="region"].skin-organic > header:first-child button:focus,
.skin-organic section[role="region"] > header:first-child a:focus,
.skin-organic section[role="region"] > header:first-child button:focus {
background-color: transparent;
}
/* ----------------------------------
Icons
---------------------------------- */
html[dir="ltr"] section[role="region"].skin-organic > header:first-child .icon-back,
html[dir="ltr"] .skin-organic section[role="region"] > header:first-child .icon-back {
background-image: url(headers/images/icons/organic/left.png);
}
html[dir="rtl"] section[role="region"].skin-organic > header:first-child .icon-back,
html[dir="rtl"] .skin-organic section[role="region"] > header:first-child .icon-back {
background-image: url(headers/images/icons/organic/right.png);
}
section[role="region"].skin-organic > header:first-child .icon-close,
.skin-organic section[role="region"] > header:first-child .icon-close {
background-image: url(headers/images/icons/organic/close.png);
}
section[role="region"].skin-organic > header:first-child .icon-add,
.skin-organic section[role="region"] > header:first-child .icon-add {
background-image: url(headers/images/icons/organic/add.png);
}
html[dir="ltr"] section[role="region"].skin-organic > header:first-child .icon-edit,
html[dir="ltr"] .skin-organic section[role="region"] > header:first-child .icon-edit {
background-image: url(headers/images/icons/organic/edit.png);
}
html[dir="rtl"] section[role="region"].skin-organic > header:first-child .icon-edit,
html[dir="rtl"] .skin-organic section[role="region"] > header:first-child .icon-edit {
background-image: url(headers/images/icons/organic/edit-rtl.png);
}
/* ----------------------------------
Subheader
---------------------------------- */
section[role="region"].skin-organic header h2,
.skin-organic section[role="region"] header h2 {
background-color: #e7e7e7;
color: #4d4d4d;
border: none;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

View file

@ -0,0 +1,180 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="utf-8">
<title>Headers</title>
<meta name="description" content="Providing top-level navigation and inputs for the active view">
<!--
- This <style> and <link> is only used for the example preview,
- it isn't needed for the real use case.
-->
<link rel="stylesheet" href="../headers.css">
<style type="text/css">
html, body {
margin: 0;
padding: 0;
font-size: 10px;
background-color: #fff;
}
body {
background: none;
}
h2.bb-docs {
font-size: 1.8rem;
font-weight: 300;
color: #666;
margin: -0.1rem 0 0;
background-color: #f5f5f5;
padding: 0.4rem;
padding-inline-start: 3rem;
border: solid 0.1rem #e8e8e8;
margin: 3rem 0 1rem;
}
section[role="region"] {
margin-bottom: 1.5rem;
position: relative;
}
</style>
<script>
window.onload = function() {
document.getElementById('dir').checked = false;
};
</script>
</head>
<body role="application">
<p dir="ltr">
<label>
<input type="checkbox" id="dir"
onchange="document.documentElement.dir = this.checked ? 'rtl' : 'ltr'">
RTL mode
</label>
</p>
<section role="region">
<header>
<a href="#"><span class="icon icon-close">close</span></a>
<menu type="toolbar">
<button>done</button>
</menu>
<h1>Email</h1>
</header>
</section>
<section role="region">
<header>
<a href="#"></a>
<menu type="toolbar">
<button><span class="icon icon-send">send</span></button>
</menu>
<h1>Send message to X</h1>
</header>
</section>
<section role="region">
<header>
<a href="#"><span class="icon icon-back">back</span></a>
<menu type="toolbar">
<button><span class="icon icon-edit">edit</span></button>
<button><span class="icon icon-add">add</span></button>
</menu>
<h1>Email</h1>
</header>
<header>
<h2>Subheader text</h2>
</header>
</section>
<section role="region">
<header>
<button><span class="icon icon-menu">menu</span></button>
<menu type="toolbar">
<button><span class="icon icon-edit">edit</span></button>
<button><span class="icon icon-add">add</span></button>
</menu>
<h1>Inbox <em>(2)</em></h1>
</header>
</section>
<h2 class="bb-docs">Skin: Dark</h2>
<section role="region" class="skin-dark">
<header>
<a href="#"><span class="icon icon-close">close</span></a>
<menu type="toolbar">
<button>done</button>
</menu>
<h1>Music</h1>
</header>
</section>
<section role="region" class="skin-dark">
<header>
<a href="#"><span class="icon icon-back">back</span></a>
<menu type="toolbar">
<button><span class="icon icon-edit">edit</span></button>
<button><span class="icon icon-add">add</span></button>
</menu>
<h1>Music</h1>
</header>
<header>
<h2>Subheader text</h2>
</header>
</section>
<h2 class="bb-docs">Skin: Organic</h2>
<section role="region" class="skin-organic">
<header>
<a href="#"><span class="icon icon-close">close</span></a>
<menu type="toolbar">
<button>done</button>
</menu>
<h1>Settings</h1>
</header>
</section>
<div class="skin-organic">
<section role="region">
<header>
<a href="#"><span class="icon icon-back">back</span></a>
<menu type="toolbar">
<button><span class="icon icon-edit">edit</span></button>
<button><span class="icon icon-add">add</span></button>
</menu>
<h1>Settings</h1>
</header>
<header>
<h2>Subheader text</h2>
</header>
</section>
</div>
<h2 class="bb-docs">Skin: Comms</h2>
<div class="skin-comms">
<section role="region">
<header>
<a href="#"><span class="icon icon-close">close</span></a>
<menu type="toolbar">
<button>done</button>
</menu>
<h1>Contacts</h1>
</header>
</section>
<section role="region">
<header>
<a href="#"><span class="icon icon-back">back</span></a>
<menu type="toolbar">
<button><span class="icon icon-edit">edit</span></button>
<button><span class="icon icon-add">add</span></button>
</menu>
<h1>Contacts</h1>
</header>
<header>
<h2>Subheader text</h2>
</header>
</section>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,575 @@
/* ----------------------------------
* Input areas
* ---------------------------------- */
/**
* BiDi notes:
*
* - as the <input>, <textarea> and [contentEditable] elements are filled by
* the user, they need a `unicode-bidi: -moz-plaintext` attribute for their
* content to be displayed properly (e.g. LTR content in an RTL document,
* or vice-versa);
*
* - consequence: *-inline-start/end properties can still be used on such
* elements content direction doesn't impact element's direction
*
* - however, the one-line inputs must still be aligned along with the
* *document* direction: to the left in LTR, to the right in RTL
* -- no matter what the *content* direction is.
*/
html[dir="ltr"] input { text-align: left; }
html[dir="rtl"] input { text-align: right; }
input[type="text"],
input[type="password"],
input[type="email"],
input[type="tel"],
input[type="search"],
input[type="url"],
input[type="number"],
textarea {
font-family: sans-serif;
box-sizing: border-box;
display: block;
width: 100%;
height: 4rem;
line-height: 4rem;
resize: none;
padding: 0 1.5rem;
font-size: 1.6rem;
border: 0.1rem solid #c7c7c7;
border-radius: 0;
box-shadow: none; /* override the box-shadow from the system (performance issue) */
color: #333;
background: #fff;
margin: 0 0 1rem;
unicode-bidi: -moz-plaintext;
}
label:active {
background-color: transparent;
}
textarea {
height: 10rem;
max-height: 10rem;
line-height: 2rem;
}
input::-moz-placeholder,
textarea::-moz-placeholder {
color: #a9a9a9;
opacity: 1;
font-style: italic;
font-weight: 400;
}
input[disabled],
textarea[disabled] {
opacity: 0.5;
}
.skin-dark input[type="text"],
.skin-dark input[type="password"],
.skin-dark input[type="email"],
.skin-dark input[type="tel"],
.skin-dark input[type="search"],
.skin-dark input[type="url"],
.skin-dark input[type="number"],
.skin-dark textarea {
color: #fff;
background-color: transparent;
border-color: #454545;
}
form p {
position: relative;
margin: 0;
}
form p input + button[type="reset"],
form p textarea + button[type="reset"] {
position: absolute;
top: 0;
width: 4rem;
height: 4rem;
padding: 0;
border: none;
font-size: 0;
opacity: 0;
pointer-events: none;
background: url(input_areas/images/clear.png) no-repeat 50% 50% / 2.4rem auto;
}
html[dir="ltr"] form p input + button[type="reset"],
html[dir="ltr"] form p textarea + button[type="reset"] {
right: -0.3rem;
}
html[dir="rtl"] form p input + button[type="reset"],
html[dir="rtl"] form p textarea + button[type="reset"] {
left: -0.3rem;
}
.skin-dark p input + button[type="reset"],
.skin-dark p textarea + button[type="reset"] {
background-image: url(input_areas/images/clear_dark.png);
}
/* To avoid colission with BB butons */
li input + button[type="reset"]:after,
li textarea + button[type="reset"]:after {
background: none;
}
textarea {
padding: 1.2rem;
}
html[dir="ltr"] form p input:focus { padding-right: 3rem; }
html[dir="rtl"] form p input:focus { padding-left: 3rem; }
form p input:focus + button[type="reset"],
form p textarea:focus + button[type="reset"] {
opacity: 1;
pointer-events: all;
}
/* Fieldset */
fieldset {
position: relative;
overflow: hidden;
margin: 1.5rem 0 0;
padding: 0;
font-size: 2rem;
line-height: 1em;
background: none;
border: 0;
}
fieldset legend,
input[type="date"],
input[type="time"],
input[type="datetime"],
input[type="datetime-local"] {
border: 0.1rem solid #c7c7c7;
width: 100%;
box-sizing: border-box;
font-family: sans-serif;
font-style: italic;
font-size: 1.6rem;
margin: 0 0 1.5rem;
padding: 0 1.5rem;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
height: 4rem;
color: #333;
border-radius: 0;
background-color: #fff;
background-repeat: no-repeat;
}
html[dir="ltr"] fieldset legend,
html[dir="ltr"] input[type="date"],
html[dir="ltr"] input[type="time"],
html[dir="ltr"] input[type="datetime"],
html[dir="ltr"] input[type="datetime-local"] {
background-image: url(input_areas/images/dialog.svg);
background-position: right 1rem bottom 1rem;
}
html[dir="rtl"] fieldset legend,
html[dir="rtl"] input[type="date"],
html[dir="rtl"] input[type="time"],
html[dir="rtl"] input[type="datetime"],
html[dir="rtl"] input[type="datetime-local"] {
background-image: url(input_areas/images/dialog_rtl.svg);
background-position: left 1rem bottom 1rem;
}
fieldset legend {
margin: 0 0 1rem;
padding: 1rem 1.5rem 0;
background-color: rgba(0,0,0,0.05);
}
fieldset[disabled] {
opacity: 0.5;
pointer-events: none;
}
.skin-dark fieldset legend,
.skin-dark input[type="date"],
.skin-dark input[type="time"],
.skin-dark input[type="datetime"],
.skin-dark input[type="datetime-local"] {
color: #fff;
background-color: transparent;
border-color: #454545;
}
fieldset[disabled] legend,
input[type="date"][disabled],
input[type="time"][disabled],
input[type="datetime"][disabled],
input[type="datetime-local"][disabled] {
background-color: transparent;
}
html[dir="ltr"] fieldset[disabled] legend,
html[dir="ltr"] input[type="date"][disabled],
html[dir="ltr"] input[type="time"][disabled],
html[dir="ltr"] input[type="datetime"][disabled],
html[dir="ltr"] input[type="datetime-local"][disabled] {
background-image: url(input_areas/images/dialog_disabled.svg);
}
html[dir="rtl"] fieldset[disabled] legend,
html[dir="rtl"] input[type="date"][disabled],
html[dir="rtl"] input[type="time"][disabled],
html[dir="rtl"] input[type="datetime"][disabled],
html[dir="rtl"] input[type="datetime-local"][disabled] {
background-image: url(input_areas/images/dialog_disabled_rtl.svg);
}
input[type="date"]:focus,
input[type="time"]:focus,
input[type="datetime"]:focus,
input[type="datetime-local"]:focus {
box-shadow: none;
border-bottom-color: #c7c7c7;
}
.skin-dark input[type="date"]:focus,
.skin-dark input[type="time"]:focus,
.skin-dark input[type="datetime"]:focus,
.skin-dark input[type="datetime-local"]:focus {
box-shadow: none;
border-bottom-color: #454545;
}
input[type="date"]:active,
input[type="time"]:active,
input[type="datetime"]:active,
input[type="datetime-local"]:active {
background-color: #b2f2ff;
color: #fff;
}
.skin-dark input[type="date"]:active,
.skin-dark input[type="time"]:active,
.skin-dark input[type="datetime"]:active,
.skin-dark input[type="datetime-local"]:active {
background-color: #00aacc;
background-image: url(input_areas/images/dialog_active.svg);
}
/* fix for required inputs with wrong or empty value e.g. [type=email] */
input:invalid,
textarea:invalid,
.skin-dark input:invalid,
.skin-dark textarea:invalid {
color: #b90000;
}
input:focus,
textarea:focus,
.skin-dark input:focus,
.skin-dark textarea:focus {
box-shadow: inset 0 -0.1rem 0 #00caf2;
border-bottom-color: #00caf2;
}
input:invalid:focus,
textarea:invalid:focus,
.skin-dark input:invalid:focus,
.skin-dark textarea:invalid:focus {
box-shadow: inset 0 -0.1rem 0 #820000;
border-bottom-color: #820000;
}
input[type="range"]:focus,
.skin-dark input[type="range"]:focus {
box-shadow: none;
border-bottom: 0;
}
/* Tidy (search/submit) */
form[role="search"] {
position: relative;
height: 3.7rem;
background: #f4f4f4;
}
form[role="search"].skin-dark {
background: #202020;
}
form[role="search"] p {
padding: 0 1.5rem;
padding-inline-start: 3rem;
overflow: hidden;
position: relative;
}
form[role="search"] p input,
form[role="search"] p textarea {
height: 3.7rem;
border: none;
background: none;
padding: 0;
margin: 0;
box-shadow: none;
}
form[role="search"] p textarea {
padding: 1rem 0 0;
}
form[role="search"] p input::-moz-placeholder {
background-image: url(input_areas/images/search.svg);
background-repeat: no-repeat;
background-size: 3rem;
}
html[dir="ltr"] form[role="search"] p input::-moz-placeholder {
background-position: right -0.5rem center;
}
html[dir="rtl"] form[role="search"] p input::-moz-placeholder {
background-position: left -0.5rem center;
}
form[role="search"].skin-dark p input::-moz-placeholder {
background-image: url(input_areas/images/search_dark.svg);
}
form[role="search"] p input:focus::-moz-placeholder {
background: none;
}
form[role="search"] p input:invalid,
form[role="search"] p textarea:invalid,
form[role="search"] p input:focus,
form[role="search"] p textarea:focus {
border: none;
box-shadow: none;
}
form[role="search"].skin-dark p input,
form[role="search"].skin-dark p textarea {
color: #fff;
background: none;
box-shadow: none;
}
form[role="search"] button[type="submit"] {
min-width: 6rem;
height: 3.7rem;
padding: 0 1.5rem;
border: none;
color: #00aac5;
font-weight: normal;
font-size: 1.6rem;
line-height: 3.7rem;
width: auto;
border-radius: 0;
margin: 0;
position: relative;
background-image: none;
background-color: unset;
font-style: italic;
overflow: visible;
}
html[dir="ltr"] form[role="search"] button[type="submit"] { float: right; }
html[dir="rtl"] form[role="search"] button[type="submit"] { float: left; }
form[role="search"] button[type="submit"]:after {
content: "";
position: absolute;
offset-inline-start: -0.1rem;
top: 0.7rem;
bottom: 0.7rem;
width: 0.1rem;
background: #c7c7c7;
}
form[role="search"] button[type="submit"].icon {
font-size: 0;
background-repeat: no-repeat;
background-position: center;
background-size: 3rem;
}
form[role="search"] p input + button[type="reset"]{
height: 3.7rem;
offset-inline-end: 0.5rem;
}
form[role="search"].skin-dark button[type="submit"]:after {
background-color: #575757;
}
form[role="search"] button[type="submit"] + p > textarea {
height: 3.7rem;
line-height: 2rem;
}
form[role="search"] button[type="submit"] + p button {
height: 3.7rem;
}
form[role="search"].full button[type="submit"] {
display: none;
}
form[role="search"] button.icon:active,
form[role="search"] button[type="submit"]:active {
background-color: #b2f2ff;
color: #fff;
}
form[role="search"].skin-dark button.icon:active,
form[role="search"].skin-dark button[type="submit"]:active {
background: #00aacc;
}
form[role="search"] button[type="submit"][disabled] {
color: #adadad;
pointer-events: none;
}
form button::-moz-focus-inner {
border: none;
outline: none;
}
/* .bb-editable - e.g email & SMS recipients */
.bb-editable [contenteditable] {
display: inline-block;
box-sizing: border-box;
position: relative;
max-width: calc(100% - 1.4rem);
overflow: hidden;
padding: 0 1.5rem;
margin: 0 0 0.6rem;
line-height: 2.8rem;
border-radius: 1.4rem;
text-overflow: ellipsis;
font-size: 1.6rem;
font-style: italic;
white-space: nowrap;
color: #333;
background: #fff;
}
html[dir="ltr"] .bb-editable [contenteditable].icon {
padding-right: 3.7rem;
}
html[dir="rtl"] .bb-editable [contenteditable].icon {
padding-left: 3.7rem;
}
.bb-editable [contenteditable="false"].invalid {
background-color: #fedcdc;
padding: 0 1.5rem;
}
html[dir="ltr"] .bb-editable [contenteditable="false"].invalid { padding-left: 3.3rem; }
html[dir="rtl"] .bb-editable [contenteditable="false"].invalid { padding-right: 3.3rem; }
.bb-editable [contenteditable="false"].invalid:before {
content: "!";
position: absolute;
top: 0.6rem;
display: block;
width: 1.7rem;
height: 1.6rem;
padding: 0;
border-radius: 50%;
line-height: 1.6rem;
font-size: 1.2rem;
text-align: center;
text-indent: -0.1rem;
font-style: normal;
font-weight: 600;
color: #fff;
background-color: #b80404;
}
html[dir="ltr"] .bb-editable [contenteditable="false"].invalid:before { left: 0.8rem; }
html[dir="rtl"] .bb-editable [contenteditable="false"].invalid:before { right: 0.8rem; }
.bb-editable [contenteditable="false"].invalid:hover:before,
.bb-editable [contenteditable="false"].invalid:active:before {
color: #b2f2ff;
background-color: #fff;
}
.bb-editable [contenteditable]:hover,
.bb-editable [contenteditable]:active,
.bb-editable [contenteditable].invalid:hover,
.bb-editable [contenteditable].invalid:active {
color: #fff;
background-color: #b2f2ff;
}
.bb-editable [contenteditable].icon:after {
content: "";
position: absolute;
top: 0.7rem;
width: 3rem;
height: 3rem;
background-repeat: no-repeat;
background-size: 3rem;
}
html[dir="ltr"] .bb-editable [contenteditable].icon:after {
right: 0;
background-position: -0.7rem -3.8rem;
}
html[dir="rtl"] .bb-editable [contenteditable].icon:after {
left: 0;
background-position: 0.7rem -3.8rem;
}
html[dir="ltr"] .bb-editable [contenteditable].icon:hover:after,
html[dir="ltr"] .bb-editable [contenteditable].icon:active:after {
background-position: -0.7rem -0.8rem;
}
html[dir="rtl"] .bb-editable [contenteditable].icon:hover:after,
html[dir="rtl"] .bb-editable [contenteditable].icon:active:after {
background-position: 0.7rem -0.8rem;
}
html[dir="ltr"] .bb-editable [contenteditable].invalid.icon {
padding-right: 3.7rem;
}
html[dir="rtl"] .bb-editable [contenteditable].invalid.icon {
padding-left: 3.7rem;
}
html[dir="ltr"] .bb-editable [contenteditable].invalid.icon:after {
background-position: -0.7rem -6.8rem;
}
html[dir="rtl"] .bb-editable [contenteditable].invalid.icon:after {
background-position: 0.7rem -6.8rem;
}
html[dir="ltr"] .bb-editable [contenteditable].invalid.icon:hover:after,
html[dir="ltr"] .bb-editable [contenteditable].invalid.icon:active:after {
background-position: -0.7rem -0.8rem;
}
html[dir="rtl"] .bb-editable [contenteditable].invalid.icon:hover:after,
html[dir="rtl"] .bb-editable [contenteditable].invalid.icon:active:after {
background-position: 0.7rem -0.8rem;
}
.bb-editable [contenteditable="true"],
.bb-editable [contenteditable="true"]:hover,
.skin-comms .bb-editable [contenteditable="true"]:hover {
padding: 0 0.2rem;
white-space: normal;
font-size: 1.8rem;
font-style: normal;
color: #000;
background: none repeat scroll 0 0 transparent;
}
.skin-comms .bb-editable [contenteditable]:hover,
.skin-comms .bb-editable [contenteditable]:active {
color: #fff;
background-color: #29bbb5;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path fill="#00AAC5" enable-background="new" d="M9 0L9 9 0 9"/></svg>

After

Width:  |  Height:  |  Size: 148 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path fill="#B2F2FF" d="M9 0v9h-9"/></svg>

After

Width:  |  Height:  |  Size: 121 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path opacity=".5" fill="#A9A9A9" d="M9 0L9 9 0 9"/></svg>

After

Width:  |  Height:  |  Size: 137 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path opacity=".5" fill="#A9A9A9" enable-background="new" d="M0 0L0 9 9 9"/></svg>

After

Width:  |  Height:  |  Size: 161 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 9 9"><path fill="#00AAC5" enable-background="new" d="M0 0L0 9 9 9"/></svg>

After

Width:  |  Height:  |  Size: 148 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><path fill-rule="evenodd" clip-rule="evenodd" fill="#424242" d="M23.385 21.494c.266.266.057.903-.465 1.426s-1.16.729-1.426.465l-4.041-4.039c-1.01.656-2.21 1.047-3.505 1.047-3.561 0-6.448-2.885-6.448-6.446 0-3.56 2.887-6.446 6.448-6.446 3.562 0 6.449 2.887 6.449 6.446 0 1.297-.393 2.499-1.051 3.509l4.041 4.039h-.002zm-9.437-12.459c-2.712 0-4.914 2.198-4.914 4.912s2.202 4.913 4.914 4.913c2.714 0 4.914-2.199 4.914-4.913-.001-2.714-2.2-4.912-4.914-4.912z"/></svg>

After

Width:  |  Height:  |  Size: 546 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><path fill-rule="evenodd" clip-rule="evenodd" fill="#8F9091" d="M23.385 21.494c.266.266.057.903-.465 1.426s-1.16.729-1.426.465l-4.041-4.039c-1.01.656-2.21 1.047-3.505 1.047-3.561 0-6.448-2.885-6.448-6.446 0-3.56 2.887-6.446 6.448-6.446 3.562 0 6.449 2.887 6.449 6.446 0 1.297-.393 2.499-1.051 3.509l4.041 4.039h-.002zm-9.437-12.459c-2.712 0-4.914 2.198-4.914 4.912s2.202 4.913 4.914 4.913c2.714 0 4.914-2.199 4.914-4.913-.001-2.714-2.2-4.912-4.914-4.912z"/></svg>

After

Width:  |  Height:  |  Size: 546 B

View file

@ -0,0 +1,236 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="utf-8">
<title>Input areas</title>
<link rel="stylesheet" href="../input_areas.css">
<link rel="stylesheet" href="../../elements/gaia-icons/gaia-icons-embedded.css">
<link rel="stylesheet" href="../../elements/gaia-icons/bidi-helper.css">
<!--
- These <style> and <script> elements are only used for the example code,
- they are not needed for the real use case.
-->
<style>
html, body {
margin: 0;
padding: 0;
font-size: 10px;
background-color: #f4f4f4;
}
label.bb-docs {
font-family: sans-serif;
font-size: 1.2rem;
margin-left: 1.5rem;
}
h2.bb-docs {
font-family: sans-serif;
padding: 0.4rem 3rem;
margin: -0.1rem 0 0;
border: solid 0.1rem #e8e8e8;
color: #666;
font-size: 1.8rem;
font-weight: 300;
background-color: #fff;
}
form { margin: 1rem 1.5rem; }
form[role="search"] { margin: 1rem 0; }
div.skin-dark {
background: #000;
}
div.skin-dark.margins {
margin: 1rem -1.5rem;
padding: 1.5rem 1.5rem 0.5rem;
}
/**
* .bb-editable
* Added properties for this example, don't add on app.
*/
.bb-editable {
padding: 1.5rem 1rem 0.5rem;
background: #bbb;
}
/**
* .icon-email:before
* Define the background-image with custom icon for App.
* Attention, the pseudo-element is required for compatibility with Building Blocks.
*
* Example:
* .icon-mms:before { background-image: url(...); }
*/
.icon-email:after {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAABaCAYAAACv+ebYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAASRJREFUeNrsl8ENgjAUhqlhAEfxQDyzgXdOjoCT0ClYg54Nu+gGtcRiAlJ5fQ9CDP+XFJOW+hlo6/uTBADw76hfg9ba0n0cBd//VErp6FlO3FgZDevn9pO50u4iEXPkn/ul4hj54L4lxBT51/hS4odrVUA62b+UOCSvfP+q4rE8KF1DTF5w3JPLio9Gx1T/Yauzen/idGb8Jv13QgEAAAAAyNJi27bitJhlmeYUAhfXcoHYuKY5pU/uJ3OluaTm4sjN3JOiFnsxckN5PTFVJkVuqGsitrw9hRaL7ycvxFhxt7WuE3Lt+1ct6MfyXhq131PmVukkpX+n5RYRhn24IC0iLQIAAABIi2/uRSFOi+e6RlpEWkRaRFpEWkRaRFoEYG+8BBgAvaeWTjgXDaoAAAAASUVORK5CYII=);
}
</style>
<script>
window.onload = function() {
document.getElementById('dir').checked = false;
};
</script>
</head>
<body role="application">
<p dir="ltr">
<label class="bb-docs">
<input id="dir" type="checkbox" checked="false"
onchange="document.documentElement.dir = this.checked ? 'rtl' : 'ltr'">
RTL mode
</label>
</p>
<h2 class="bb-docs">Default inputs</h2>
<form>
<p>
<input dir="auto" type="text" placeholder="Placeholder">
<button type="reset">Clear</button>
</p>
<p>
<textarea placeholder="Placeholder in textarea"></textarea>
</p>
<p>
<input dir="auto" type="text" placeholder="Placeholder" value="Some written text" required>
<button type="reset">Clear</button>
</p>
<p>
<input dir="auto" type="text" placeholder="Disabled" disabled required>
<button type="reset">Clear</button>
</p>
<div class="skin-dark margins">
<p>
<input dir="auto" type="text" placeholder="Placeholder" value="Some written text">
<button type="reset">Clear</button>
</p>
</div>
</form>
<h2 class="bb-docs">Required inputs</h2>
<form>
<p>
<input dir="auto" type="text" placeholder="Placeholder" required>
<button type="reset">Clear</button>
</p>
<p>
<textarea placeholder="Placeholder in textarea" required></textarea>
</p>
</form>
<h2 class="bb-docs">Date/time inputs</h2>
<form>
<p>
<input dir="auto" disabled type="date" placeholder="YYYY-MM-DD">
</p>
<p>
<input dir="auto" type="time" placeholder="hh:mm:ss">
</p>
</form>
<h2 class="bb-docs">Fieldset</h2>
<form>
<fieldset>
<legend class="action">Mobile</legend>
<section>
<p>
<input dir="ltr" type="tel" placeholder="Phone number">
<button type="reset">Clear</button>
</p>
<p>
<input dir="auto" type="text" placeholder="Name" value="Jessy James">
<button type="reset">Clear</button>
</p>
</section>
</fieldset>
<fieldset disabled>
<legend>Work</legend>
<section>
<p>
<input dir="ltr" type="tel" placeholder="Email">
<button type="reset">Clear</button>
</p>
</section>
</fieldset>
</form>
<h2 class="bb-docs">Forms: Input text</h2>
<form role="search">
<p>
<input dir="auto" type="text" placeholder="Search…">
<button type="reset">Clear</button>
</p>
</form>
<form role="search">
<button type="submit">Cancel</button>
<p>
<input dir="auto" type="text" placeholder="Search…" value="Some text here">
<button type="reset">Clear</button>
</p>
</form>
<div class="skin-dark">
<h2 class="bb-docs">Skin dark</h2>
<form role="search" class="skin-dark">
<p>
<input dir="auto" type="text" placeholder="Search…">
<button type="reset">Clear</button>
</p>
</form>
<form role="search" class="skin-dark">
<button type="submit">Cancel</button>
<p>
<input dir="auto" type="text" placeholder="Search…" value="Some text here">
<button type="reset">Clear</button>
</p>
</form>
</div>
<h2 class="bb-docs">Forms: Text area</h2>
<form role="search" class="bottom">
<!-- this button should be enabled after start typing in the input field-->
<button type="submit" disabled>Send</button>
<p>
<textarea></textarea>
</p>
</form>
<form role="search" class="bottom">
<button type="submit">Send</button>
<p>
<textarea>Some text here</textarea>
</p>
</form>
<form role="search" class="bottom">
<button type="submit" class="icon" data-icon="send" aria-hidden="true">Send</button>
<p>
<textarea>Some text here</textarea>
</p>
</form>
<h2 class="bb-docs">Content Editable</h2>
<ul class="bb-editable">
<li dir="auto" contenteditable="false">Travis Gray Travis Gray</li>
<li dir="auto" contenteditable="false" class="invalid">Lucy B.</li>
<li dir="auto" contenteditable="false" class="icon icon-email">Mary</li>
<li dir="auto" contenteditable="false" class="invalid icon icon-email">Paul C.</li>
<li dir="auto" contenteditable="true">John</li>
</ul>
</body>
</html>

View file

@ -0,0 +1,330 @@
/* ------------------------------------
* Layout.css will allow us creating
* easy structures using flexbox.
* This file will replace lists.css
* ------------------------------------ */
html {
height: 100%;
}
body {
margin: 0;
height: 100%;
display: flex;
flex-direction: column;
font-size: 18px;
color: #333;
overflow: hidden;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
p {
margin: 0;
line-height: 22px
}
/* Horizontal layout */
.hbox {
display: flex;
flex-direction: row;
}
.hbox.left { justify-content: flex-start; }
.hbox.center { justify-content: center; }
.hbox.right { justify-content: flex-end; }
.hbox.top { align-items: flex-start; }
.hbox.middle { align-items: center; }
.hbox.bottom { align-items: flex-end; }
.hbox > .self-top { align-self: flex-start; }
.hbox > .self-middle { align-self: center; }
.hbox > .self-bottom { align-self: flex-end; }
/* Vertical layout */
.vbox {
display: flex;
flex-direction: column;
}
.vbox.left { align-items: flex-start; }
.vbox.center { align-items: center; }
.vbox.right { align-items: flex-end; }
.vbox.top { justify-content: flex-start; }
.vbox.middle { justify-content: center; }
.vbox.bottom { justify-content: flex-end; }
.vbox > .self-left { align-self: flex-start; }
.vbox > .self-center { align-self: center; }
.vbox > .self-right { align-self: flex-end; }
/*
* Layout properties
*/
.fit {
flex: 1;
}
.scroll {
overflow: auto;
}
.fit.two { flex: 2; }
.fit.three { flex: 3; }
.fit.four { flex: 4; }
.fit.five { flex: 5; }
.fit.six { flex: 6; }
/*
* Elements
*/
/* Lists */
.gaia-list {
font-size: 18px;
}
.gaia-list li {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
min-height: 40px;
padding: 10px 15px;
}
.gaia-list li:after {
position: absolute;
content: "";
right: 15px;
top: 0;
bottom: 0;
left: 15px;
border-bottom: 1px solid #e7e7e7;
pointer-events: none;
}
.gaia-list li:last-of-type:after {
display: none;
}
.gaia-list.active li:active,
.gaia-list li.active:active {
background-color: rgba(0, 213, 255, 0.3);
}
.gaia-list li.vbox {
flex-direction: column;
align-items: flex-start;
justify-content: center;
}
/* List header */
.gaia-list header {
padding: 0 30px;
margin: 0;
font-size: 16px;
height: 30px;
line-height: 40px;
font-weight: normal;
color: #ff4e00;
text-transform: uppercase;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
background: #fff;
}
.gaia-list.sticky header {
position: sticky;
top: 0;
right: 0;
left: 0;
z-index: 1;
}
/* List elements */
.gaia-list li p,
.gaia-list li label {
-moz-margin-start: 15px;
}
.gaia-list li p:not(:first-of-type) {
color: #858585;
font-size: 15px;
line-height: 20px;
}
.gaia-list li p em {
font-size: 15px;
font-style: normal;
}
.gaia-list li p time {
margin-right: 3px;
text-transform: uppercase;
}
.gaia-list label.pack-checkbox,
.gaia-list label.pack-switch {
width: 100%;
overflow: hidden;
display: flex;
align-items: center;
height: auto;
min-height: 40px;
padding: 10px 0;
margin: -10px 0;
-moz-margin-start: 15px;
}
.gaia-list label.vbox.pack-checkbox,
.gaia-list label.vbox.pack-switch {
align-items: flex-start;
justify-content: center;
}
.gaia-list label.pack-checkbox:not(.reverse) {
-moz-padding-start: 30px;
-moz-margin-start: 0;
}
.gaia-list label.pack-checkbox span:after {
left: 10px;
}
.gaia-list label.pack-checkbox.reverse span:after,
.gaia-list label.pack-switch span:after {
left: auto;
right: 0;
}
.gaia-list label.pack-checkbox span,
.gaia-list label.pack-switch span,
.gaia-list label p {
word-wrap: break-word;
width: 100%;
}
.gaia-list label.pack-checkbox.reverse span,
.gaia-list label.pack-checkbox.reverse p {
width: calc(100% - 30px);
}
.gaia-list label.pack-switch span,
.gaia-list label.pack-switch p {
width: calc(100% - 70px);
}
.gaia-list label p {
color: #858585;
font-size: 15px;
line-height: 20px;
-moz-margin-start: 0;
}
.gaia-list li.icon {
-moz-padding-start: 40px;
background-position: left 15px center;
background-repeat: no-repeat;
background-size: 30px;
}
.gaia-list [data-type=img],
.gaia-list li img {
display: block;
overflow: hidden;
width: 50px;
height: 50px;
border-radius: 25px;
margin-top: 5px;
box-sizing: border-box;
box-shadow: 0 0 0 1px #dedede;
background: transparent center center / cover;
position: relative;
}
.gaia-list li button,
.gaia-list li .button {
margin: 0;
}
.gaia-list li button + button,
.gaia-list li p + button,
.gaia-list li p + .button,
.gaia-list li button + p,
.gaia-list li .button + p,
.gaia-list li label + button,
.gaia-list li label + .button {
margin-top: 10px;
}
/* Footer */
.gaia-footer {
border-top: 1px solid #e7e7e7;
background-color: #fff;
padding: 10px 15px;
display: flex;
}
.gaia-footer p {
margin: 0 15px 10px;
word-break: break-all;
text-align: center;
color: #858585;
font-size: 15px;
line-height: 20px;
}
.gaia-footer button,
.gaia-footer .button {
margin: 0 0 0 15px;
}
.gaia-footer button:first-of-type,
.gaia-footer .button:first-of-type {
margin-left: 0;
}
/*
* Skins
*/
.skin-comms .gaia-list header {
color: #4997a7;
}
.skin-organic .gaia-list header {
background-color: #e7e7e7;
color: #4d4d4d;
font-size: 15px;
line-height: 34px;
text-transform: none;
}
/**
* Right-to-Left layout
*/
.gaia-list:-moz-dir(rtl) label.pack-checkbox span:after {
left: unset;
right: 10px;
}
.gaia-list:-moz-dir(rtl) label.pack-checkbox.reverse span:after,
.gaia-list:-moz-dir(rtl) label.pack-switch span:after {
left: 0;
right: unset;
}
.gaia-list:-moz-dir(rtl) li.icon {
background-position: right 15px center;
}

View file

@ -0,0 +1,342 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Layout</title>
<meta name="description" content="Displaying an enumeration of a set of items ">
<link rel="stylesheet" href="../layout.css">
<!--
This <style> and <link> is only used for the example code, is no needed for the real case use
-->
<link rel="stylesheet" href="../../style/headers.css">
<link rel="stylesheet" href="../../style/switches.css">
<link rel="stylesheet" href="../../style/buttons.css">
<link rel="stylesheet" href="../../elements/gaia-icons/gaia-icons-embedded.css">
<style>
html {
font-size: 10px;
}
.gaia-list li img[alt="placeholder"] {
background: #ccc url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNS4wLjIsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkNhcGFfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHdpZHRoPSI1MHB4IiBoZWlnaHQ9IjUwcHgiIHZpZXdCb3g9IjAgMCA1MCA1MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNTAgNTAiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPGxpbmUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHgxPSIwIiB5MT0iMCIgeDI9IjUwIiB5Mj0iNTAiLz4NCjxsaW5lIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB4MT0iNTAiIHkxPSIwIiB4Mj0iMC4wODIiIHkyPSI0OS45MTkiLz4NCjwvc3ZnPg0K);
background-size: 100% 100%;
font-size: 0;
}
.gaia-list .icon-call-incoming {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0ZWQgYnkgSWNvTW9vbi5pbyAtLT4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCIgdmlld0JveD0iMCAwIDMwIDMwIj4KPGc+Cgk8bGluZSBzdHJva2Utd2lkdGg9IjEiIHgxPSIiIHkxPSIiIHgyPSIiIHkyPSIiIHN0cm9rZT0iIzQ0OUZEQiIgb3BhY2l0eT0iIj48L2xpbmU+CjwvZz4KCTxwYXRoIGQ9Ik0xNy43MTQgOS44MzN2Mi42NTZjLTAuMzE3IDAuMDY1LTAuNjU3LTAuMDA3LTAuOTA2LTAuMjUzbC0zLjAyMS0zLjAyMWMtMC4zODktMC4zOTItMC4zODktMS4wMjUgMC0xLjQxNGwzLjAyMS0zLjAyMWMwLjI0OS0wLjI0NiAwLjU4OS0wLjMyIDAuOTA2LTAuMjU1djIuNjcxaDcuMDM1YzAuMTc3IDAuODcxIDAuMTc3IDEuNzY4LTAuMDAzIDIuNjM2aC03LjAzMnpNMTguMzU2IDIxLjY0N2wwLjAyMiAwLjAyMmMwLjYwOC0wLjMzNiAxLjIwOC0wLjczOCAxLjgwMy0xLjE3bDUuNjg0IDUuMDM0Yy0xLjE5OSAxLjAzNi0yLjQ5NyAxLjg4NC0zLjg2NiAyLjUyMy0zLjYzOS0wLjY3MS04LjI5OS0zLjM3Ni0xMi40ODUtNy41NjItNC4xODItNC4xODItNi44ODctOC44MzgtNy41NjEtMTIuNDc0IDAuNjQtMS4zNzIgMS40OS0yLjY3NCAyLjUyNi0zLjg3NWw1LjAzOSA1LjY5Yy0wLjQzMyAwLjU5My0wLjgzNSAxLjE5NS0xLjE3MSAxLjgwMWwwLjAyMSAwLjAyMmMtMC41ODkgMS4yOTMgMC43NzQgNC4xMSAzLjMyNyA2LjY2M3M1LjM2NyAzLjkxNyA2LjY2MSAzLjMyNnoiIGZpbGw9IiMwMDAwMDAiPjwvcGF0aD4KPC9zdmc+Cg==);
}
.fb-example > div {
border-bottom: 1px solid #e7e7e7;
overflow: hidden;
padding: 10px 15px;
margin: 0 15px;
}
.fb-example > div > div {
position: relative;
text-indent: 10px;
}
.fb-example > div > div:before {
content: "";
top: 5px;
left: 0;
height: 6px;
width: 6px;
background-color: #333;
border-radius: 50%;
position: absolute;
}
.fb-example .vbox {
height: 100px;
}
.fb-example .hbox {
height: 70px;
}
.fb-example .hbox > div {
margin-left: 10px;
}
.fb-example .hbox > div:first-child {
margin-left: 0;
}
</style>
</head>
<body class="skin-comms">
<section role="region" class="vbox fit scroll">
<header>
<h1>App name</h1>
</header>
<section class="gaia-list fit scroll sticky">
<article>
<header>Paragraphs</header>
<ul>
<li>
<p>Only one paragraph</p>
</li>
<li class="vbox">
<p></p>
<p>Paragraph 2 (Paragraph 1 is empty)</p>
</li>
<li class="vbox">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<p>Paragraph 3</p>
</li>
</ul>
</article>
<article>
<header>Active state</header>
<ul>
<li class="active">
<p>This row has active state</p>
</li>
</ul>
</article>
<article>
<header>Text + image</header>
<ul>
<li>
<p class="fit">Contact name</p>
<img src="noimage" alt="placeholder">
</li>
<li class="icon icon-call-incoming">
<p class="fit">Contact name</p>
<img src="noimage" alt="placeholder">
</li>
</ul>
</article>
<article>
<header>Buttons</header>
<ul>
<li>
<button>Default button</button>
</li>
<li>
<button class="icon icon-view">View button</button>
</li>
<li>
<button class="icon icon-dialog">Dialog button</button>
</li>
<li class="vbox">
<button>Button</button>
<p>Paragraph</p>
</li>
<li class="vbox">
<p>Paragraph</p>
<button>Button</button>
</li>
<li class="vbox">
<label>Label</label>
<button>Button</button>
</li>
<li class="vbox">
<button>Button 1</button>
<button>Button 2</button>
</li>
<li>
<div class="fit">
<p>Text (fit)</p>
</div>
<div>
<button class="icon icon-dialog">Select</button>
</div>
</li>
<li>
<div class="fit">
<p>text (1/2)</p>
</div>
<div class="fit">
<button class="icon icon-dialog">Select</button>
</div>
</li>
<li>
<div class="fit">
<p>text (1/3)</p>
</div>
<div class="fit two">
<button class="icon icon-dialog">Select</button>
</div>
</li>
<li>
<div class="fit">
<p>text (1/4)</p>
</div>
<div class="fit three">
<button class="icon icon-dialog">Select</button>
</div>
</li>
<li>
<div class="fit">
<p>text (1/5)</p>
</div>
<div class="fit four">
<button class="icon icon-dialog">Select</button>
</div>
</li>
<li>
<div class="fit">
<p>text (1/6)</p>
</div>
<div class="fit five">
<button class="icon icon-dialog">Select</button>
</div>
</li>
<li>
<div class="fit">
<p>text (1/7)</p>
</div>
<div class="fit six">
<button class="icon icon-dialog">Select</button>
</div>
</li>
</ul>
</article>
<article>
<header>Checkboxes</header>
<ul>
<li class="active">
<label class="pack-checkbox">
<input type="checkbox" checked>
<span>Default checkbox</span>
</label>
</li>
<li class="active">
<label class="pack-checkbox danger">
<input type="checkbox" checked>
<span>Danger checkbox</span>
</label>
</li>
<li class="active">
<label class="pack-checkbox reverse">
<input type="checkbox">
<span>Reverse checkbox</span>
</label>
</li>
<li class="active">
<label class="pack-checkbox reverse danger">
<input type="checkbox">
<span>Reverse danger checkbox</span>
</label>
</li>
</ul>
</article>
<article>
<header>Switches</header>
<ul>
<li class="active">
<label class="pack-switch">
<input type="checkbox">
<span>Default switch</span>
</label>
</li>
<li class="active">
<label class="pack-switch">
<input type="checkbox" checked>
<span>Checked switch</span>
</label>
</li>
</ul>
</article>
<!-- flexbox properties -->
<article class="fb-example">
<header>vbox: left</header>
<div class="vbox left">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>vbox: center</header>
<div class="vbox center">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>vbox: right</header>
<div class="vbox right">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>vbox: top</header>
<div class="vbox top">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>vbox: middle</header>
<div class="vbox middle">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>vbox: bottom</header>
<div class="vbox bottom">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>vbox: children positioning</header>
<div class="vbox">
<div class="self-left">Item 1: left</div>
<div class="self-center">Item 2: center</div>
<div class="self-right">Item 3: right</div>
</div>
</article>
<article class="fb-example">
<header>hbox: left</header>
<div class="hbox">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>hbox: center</header>
<div class="hbox center">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>hbox: right</header>
<div class="hbox right">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>hbox: top</header>
<div class="hbox top">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>hbox: middle</header>
<div class="hbox middle">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>hbox: bottom</header>
<div class="hbox bottom">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<header>hbox: children positioning</header>
<div class="hbox">
<div class="self-top">Item 1: top</div>
<div class="self-middle">Item 2: middle</div>
<div class="self-bottom">Item 3: bottom</div>
</div>
</article>
</section>
</section>
</body>
</html>

View file

@ -0,0 +1,31 @@
/* ----------------------------------
* Status
* ---------------------------------- */
html[dir="ltr"] section[role="status"] [dir] { text-align: left; }
html[dir="rtl"] section[role="status"] [dir] { text-align: right; }
section[role="status"] {
background-color: #4d4d4d;
overflow: hidden;
position: absolute;
z-index: 100;
left: 0;
right: 0;
bottom: 0;
color: #fff;
}
html[dir="ltr"] section[role="status"] { background-position: left top; }
html[dir="rtl"] section[role="status"] { background-position: right top; }
section[role="status"] p {
font-size: 1.8rem;
font-weight: normal;
line-height: 2.2rem;
margin: 1rem 3rem;
padding: 0;
}
section[role="status"] p strong {
font-weight: 500;
}

View file

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="utf-8">
<title>Status</title>
<meta name="description" content="Most common used after Multi-Select edit, to confirm user action, and optional provide 'Undo' input">
<link rel="stylesheet" href="../status.css">
<!--
This <style>, <script> and <link> are only used for the example code,
they are not needed for the real use case
-->
<style>
html, body {
margin: 0;
padding: 0;
font-size: 10px;
background-color: #fff;
}
body {
background: none;
}
</style>
<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 role="status">
<p>The Alarm is set for <strong>7 hours</strong> and <strong>14 minutes</strong> from now</p>
</section>
</body>
</html>