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 { ...@@ -79,6 +79,7 @@ export class StdSwitchElement extends HTMLElement {
let thumbElement = this[_containerElement].appendChild(factory.createElement('span')); let thumbElement = this[_containerElement].appendChild(factory.createElement('span'));
thumbElement.id = 'thumb'; thumbElement.id = 'thumb';
thumbElement.part.add('thumb');
this[_rippleElement] = thumbElement.appendChild(factory.createElement('span')); this[_rippleElement] = thumbElement.appendChild(factory.createElement('span'));
this[_rippleElement].id = 'ripple'; this[_rippleElement].id = 'ripple';
......
...@@ -44,11 +44,11 @@ export function styleSheetFactory() { ...@@ -44,11 +44,11 @@ export function styleSheetFactory() {
box-sizing: border-box; box-sizing: border-box;
display: inline-block; display: inline-block;
margin-inline-start: calc(-100% + ${THUMB_MARGIN_START}); margin-inline-start: calc(-100% + ${THUMB_MARGIN_START});
max-inline-size: ${THUMB_WIDTH}; inline-size: ${THUMB_WIDTH};
min-inline-size: ${THUMB_WIDTH};
} }
#thumb.transitioning { /* :host::part(thumbTransitioning) doesn't work. crbug.com/980506 */
#thumb[part~="thumbTransitioning"] {
transition: all linear 0.1s; transition: all linear 0.1s;
} }
...@@ -80,7 +80,7 @@ export function styleSheetFactory() { ...@@ -80,7 +80,7 @@ export function styleSheetFactory() {
vertical-align: top; vertical-align: top;
} }
#trackFill.transitioning { #trackFill[part~="trackFillTransitioning"] {
transition: all linear 0.1s; transition: all linear 0.1s;
} }
...@@ -113,8 +113,7 @@ export function styleSheetFactory() { ...@@ -113,8 +113,7 @@ export function styleSheetFactory() {
} }
:host(:not(:disabled):hover) #thumb { :host(:not(:disabled):hover) #thumb {
max-inline-size: 26px; inline-size: 26px;
min-inline-size: 26px;
} }
:host([on]:not(:disabled):hover) #thumb { :host([on]:not(:disabled):hover) #thumb {
...@@ -163,13 +162,17 @@ export function styleSheetFactory() { ...@@ -163,13 +162,17 @@ export function styleSheetFactory() {
* @param {!Element} element * @param {!Element} element
*/ */
export function markTransition(element) { export function markTransition(element) {
const CLASS_NAME = 'transitioning'; // Should check hasAttribute() to avoid creating a DOMTokenList instance.
element.classList.add(CLASS_NAME); 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'); let durations = element.computedStyleMap().getAll('transition-duration');
if (!durations.some(duration => duration.value > 0)) { 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. // immediately.
element.classList.remove(CLASS_NAME); element.part.remove(partName);
return; return;
} }
// If the element will have transitions, initialize counters and listeners // If the element will have transitions, initialize counters and listeners
...@@ -188,7 +191,7 @@ export function markTransition(element) { ...@@ -188,7 +191,7 @@ export function markTransition(element) {
// events; crbug.com/979556. // events; crbug.com/979556.
if (e.target === element && element.runningTransitions > 0 && if (e.target === element && element.runningTransitions > 0 &&
--element.runningTransitions === 0) { --element.runningTransitions === 0) {
element.classList.remove(CLASS_NAME); element.part.remove(partName);
} }
}; };
element.addEventListener('transitionend', handleEndOrCancel); element.addEventListener('transitionend', handleEndOrCancel);
......
...@@ -49,8 +49,10 @@ export class SwitchTrack { ...@@ -49,8 +49,10 @@ export class SwitchTrack {
_initializeDOM(factory) { _initializeDOM(factory) {
this[_trackElement] = factory.createElement('div'); this[_trackElement] = factory.createElement('div');
this[_trackElement].id = 'track'; this[_trackElement].id = 'track';
this[_trackElement].part.add('track');
this[_fillElement] = factory.createElement('span'); this[_fillElement] = factory.createElement('span');
this[_fillElement].id = 'trackFill'; this[_fillElement].id = 'trackFill';
this[_fillElement].part.add('trackFill');
this[_trackElement].appendChild(this[_fillElement]); this[_trackElement].appendChild(this[_fillElement]);
this[_slotElement] = factory.createElement('slot'); this[_slotElement] = factory.createElement('slot');
this._addSlot(); this._addSlot();
......
...@@ -6112,6 +6112,7 @@ crbug.com/959693 external/wpt/trusted-types/WorkerGlobalScope-importScripts.http ...@@ -6112,6 +6112,7 @@ crbug.com/959693 external/wpt/trusted-types/WorkerGlobalScope-importScripts.http
# Allow failure until its appearance gets stable. # Allow failure until its appearance gets stable.
crbug.com/972476 std-switch/switch-appearance.html [ Failure ] crbug.com/972476 std-switch/switch-appearance.html [ Failure ]
crbug.com/972476 std-switch/switch-appearance-customization.html [ Failure ]
# Sheriff 2019-05-20 # Sheriff 2019-05-20
crbug.com/963739 [ Fuchsia ] synthetic_gestures/smooth-scroll-tiny-delta.html [ Pass Timeout ] 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'; ...@@ -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><div style="display:inline-block; text-align:right; width:100%;">off</div></std-switch></div>
<div><std-switch on>on</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> <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"> <script type="module">
const MASK_ON = 1; generateSwitchElements((indicator, element) => {
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;
}
let container = document.createElement('div'); let container = document.createElement('div');
container.className = 'container'; container.className = 'container';
container.appendChild(document.createTextNode(indicator)); container.appendChild(document.createTextNode(indicator));
container.appendChild(switchElement); container.appendChild(element);
document.body.appendChild(container); document.body.appendChild(container);
} });
</script> </script>
</body> </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