Commit c86e1a26 authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

std-switch: Expose some parts

This CL exposes 'track', 'trackFill', 'thumb', and their variants
'trackTransitioning', 'trackFillTransitioning', 'thumbTransitionning'.

Bug: 972476
Change-Id: I807b35156cf0d0264dee5476583f22a01de7cfab
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1687250
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: default avatarFergal Daly <fergal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#674411}
parent 94d5af98
......@@ -79,6 +79,7 @@ export class StdSwitchElement extends HTMLElement {
let thumbElement = this[_containerElement].appendChild(factory.createElement('span'));
thumbElement.id = 'thumb';
thumbElement.part.add('thumb');
this[_rippleElement] = thumbElement.appendChild(factory.createElement('span'));
this[_rippleElement].id = 'ripple';
......
......@@ -44,11 +44,11 @@ export function styleSheetFactory() {
box-sizing: border-box;
display: inline-block;
margin-inline-start: calc(-100% + ${THUMB_MARGIN_START});
max-inline-size: ${THUMB_WIDTH};
min-inline-size: ${THUMB_WIDTH};
inline-size: ${THUMB_WIDTH};
}
#thumb.transitioning {
/* :host::part(thumbTransitioning) doesn't work. crbug.com/980506 */
#thumb[part~="thumbTransitioning"] {
transition: all linear 0.1s;
}
......@@ -80,7 +80,7 @@ export function styleSheetFactory() {
vertical-align: top;
}
#trackFill.transitioning {
#trackFill[part~="trackFillTransitioning"] {
transition: all linear 0.1s;
}
......@@ -113,8 +113,7 @@ export function styleSheetFactory() {
}
:host(:not(:disabled):hover) #thumb {
max-inline-size: 26px;
min-inline-size: 26px;
inline-size: 26px;
}
:host([on]:not(:disabled):hover) #thumb {
......@@ -163,13 +162,17 @@ export function styleSheetFactory() {
* @param {!Element} element
*/
export function markTransition(element) {
const CLASS_NAME = 'transitioning';
element.classList.add(CLASS_NAME);
// Should check hasAttribute() to avoid creating a DOMTokenList instance.
if (!element.hasAttribute('part') || element.part.length < 1) {
return;
}
let partName = element.part[0] + 'Transitioning';
element.part.add(partName);
let durations = element.computedStyleMap().getAll('transition-duration');
if (!durations.some(duration => duration.value > 0)) {
// If the element will have no transitions, we remove CLASS_NAME
// If the element will have no transitions, we remove the part name
// immediately.
element.classList.remove(CLASS_NAME);
element.part.remove(partName);
return;
}
// If the element will have transitions, initialize counters and listeners
......@@ -188,7 +191,7 @@ export function markTransition(element) {
// events; crbug.com/979556.
if (e.target === element && element.runningTransitions > 0 &&
--element.runningTransitions === 0) {
element.classList.remove(CLASS_NAME);
element.part.remove(partName);
}
};
element.addEventListener('transitionend', handleEndOrCancel);
......
......@@ -49,8 +49,10 @@ export class SwitchTrack {
_initializeDOM(factory) {
this[_trackElement] = factory.createElement('div');
this[_trackElement].id = 'track';
this[_trackElement].part.add('track');
this[_fillElement] = factory.createElement('span');
this[_fillElement].id = 'trackFill';
this[_fillElement].part.add('trackFill');
this[_trackElement].appendChild(this[_fillElement]);
this[_slotElement] = factory.createElement('slot');
this._addSlot();
......
......@@ -6112,6 +6112,7 @@ crbug.com/959693 external/wpt/trusted-types/WorkerGlobalScope-importScripts.http
# Allow failure until its appearance gets stable.
crbug.com/972476 std-switch/switch-appearance.html [ Failure ]
crbug.com/972476 std-switch/switch-appearance-customization.html [ Failure ]
# Sheriff 2019-05-20
crbug.com/963739 [ Fuchsia ] synthetic_gestures/smooth-scroll-tiny-delta.html [ Pass Timeout ]
......
function generateSwitchElements(callback) {
const MASK_ON = 1;
const MASK_FOCUS = 1 << 1;
const MASK_HOVER = 1 << 2;
const MASK_ACTIVE = 1 << 3;
const MASK_DISABLED = 1 << 4;
const MASK_END = 1 << 5;
for (let mask = 0; mask < MASK_END; ++mask) {
let indicator = '';
let switchElement = document.createElement('std-switch');
if (mask & MASK_ON) {
switchElement.on = true;
indicator += 'o';
} else {
indicator += '-';
}
if (mask & MASK_FOCUS) {
internals.setPseudoClassState(switchElement, ':focus', true);
indicator += 'f';
} else {
indicator += '-';
}
if (mask & MASK_HOVER) {
internals.setPseudoClassState(switchElement, ':hover', true);
indicator += 'h';
} else {
indicator += '-';
}
if (mask & MASK_ACTIVE) {
internals.setPseudoClassState(switchElement, ':active', true);
indicator += 'a';
} else {
indicator += '-';
}
if (mask & MASK_DISABLED) {
switchElement.disabled = true;
indicator += 'd';
} else {
indicator += '-';
}
// Skip some impossible combinations
if (mask & MASK_DISABLED && (mask & MASK_FOCUS || mask & MASK_ACTIVE)) {
continue;
}
callback(indicator, switchElement);
}
}
<!DOCTYPE html>
<body>
<style>
std-switch {
margin: 0.5em;
}
/* ---------------------------------------------------------------- */
.material std-switch {
block-size: 20px;
inline-size: 36px;
}
.material std-switch::part(track) {
background: rgba(0,0,0,0.4);
block-size: 14px;
border: none;
box-shadow: none;
}
.material std-switch::part(trackFill) {
background: rgba(63,81,181,0.5);
}
.material std-switch::part(thumb) {
block-size: 20px;
border-radius: 10px;
border: none;
box-shadow: 0 1px 5px 0 rgba(0,0,0,0.6);
inline-size: 20px;
margin-inline-start: -100%;
}
.material std-switch[on]::part(thumb) {
background: rgb(63,81,181);
margin-inline-start: calc(0px - 20px);
}
.material std-switch:hover::part(thumb) {
inline-size: 20px;
}
/* TODO(tkent): add style for ripple effect. */
/* ---------------------------------------------------------------- */
.cocoa std-switch {
block-size: 31px;
inline-size: 51px;
}
.cocoa std-switch::part(track) {
border-radius: 15px;
border: 1px solid lightgray;
box-shadow: none;
}
.cocoa std-switch::part(trackFill) {
background: #4ad963;
}
.cocoa std-switch[on]::part(track) {
border: 1px solid #4ad963;
}
.cocoa std-switch::part(thumb) {
block-size: 29px;
border-radius: 14.5px;
border: none;
box-shadow: 0px 3px 4px 1px rgba(0,0,0,0.2);
inline-size: 29px;
margin-inline-start: calc(-100% + 1px);
}
.cocoa std-switch[on]::part(thumb) {
margin-inline-start: calc(0px - 29px - 1px);
}
/* ---------------------------------------------------------------- */
.fluent std-switch {
block-size: 20px;
inline-size: 44px;
}
.fluent std-switch::part(track) {
border: 2px solid #333333;
box-shadow: none;
}
.fluent std-switch[on]::part(track) {
border: 2px solid #4cafff;
}
.fluent std-switch::part(trackFill) {
background: #4cafff;
}
.fluent std-switch::part(thumb) {
background: #333333;
block-size: 10px;
border-radius: 5px;
border: none;
inline-size: 10px;
margin-inline-start: calc(-100% + 5px);
}
.fluent std-switch[on]::part(thumb) {
background: white;
margin-inline-start: calc(0px - 10px - 5px);
}
.fluent std-switch:active::part(track) {
background: darkgray;
border: 2px solid darkgray;
}
.fluent std-switch:active::part(thumb) {
background: white;
}
/* ---------------------------------------------------------------- */
div.material, div.cocoa, div.fluent {
overflow: auto;
}
.container {
float: left;
font-family: monospace;
}
</style>
<div class="material"><h2>Material-like</h2></div>
<div class="cocoa"><h2>Cocoa-like</h2></div>
<div class="fluent"><h2>Fluent-like</h2></div>
<script src="resources/state-combo.js"></script>
<script type="module">
import 'std:elements/switch';
function wrapAndConnect(query, indicator, element) {
let container = document.createElement('div');
container.className = 'container';
container.appendChild(document.createTextNode(indicator));
container.appendChild(element);
document.querySelector(query).appendChild(container);
}
generateSwitchElements(wrapAndConnect.bind(null, 'div.material'));
generateSwitchElements(wrapAndConnect.bind(null, 'div.cocoa'));
generateSwitchElements(wrapAndConnect.bind(null, 'div.fluent'));
</script>
</body>
......@@ -20,55 +20,14 @@ import 'std:elements/switch';
<div><std-switch><div style="display:inline-block; text-align:right; width:100%;">off</div></std-switch></div>
<div><std-switch on>on</std-switch></div>
<div>Hidden attribute: <std-switch hidden></std-switch> <std-switch on hidden></std-switch></div>
<script src="resources/state-combo.js"></script>
<script type="module">
const MASK_ON = 1;
const MASK_FOCUS = 1 << 1;
const MASK_HOVER = 1 << 2;
const MASK_ACTIVE = 1 << 3;
const MASK_DISABLED = 1 << 4;
const MASK_END = 1 << 5;
for (let mask = 0; mask < MASK_END; ++mask) {
let indicator = '';
let switchElement = document.createElement('std-switch');
if (mask & MASK_ON) {
switchElement.on = true;
indicator += 'o';
} else {
indicator += '-';
}
if (mask & MASK_FOCUS) {
internals.setPseudoClassState(switchElement, ':focus', true);
indicator += 'f';
} else {
indicator += '-';
}
if (mask & MASK_HOVER) {
internals.setPseudoClassState(switchElement, ':hover', true);
indicator += 'h';
} else {
indicator += '-';
}
if (mask & MASK_ACTIVE) {
internals.setPseudoClassState(switchElement, ':active', true);
indicator += 'a';
} else {
indicator += '-';
}
if (mask & MASK_DISABLED) {
switchElement.disabled = true;
indicator += 'd';
} else {
indicator += '-';
}
// Skip some impossible combinations
if (mask & MASK_DISABLED && (mask & MASK_FOCUS || mask & MASK_ACTIVE)) {
continue;
}
generateSwitchElements((indicator, element) => {
let container = document.createElement('div');
container.className = 'container';
container.appendChild(document.createTextNode(indicator));
container.appendChild(switchElement);
container.appendChild(element);
document.body.appendChild(container);
}
});
</script>
</body>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment