Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(slider): Add color theme mixins; default to secondary; remove --off #1544

Merged
merged 36 commits into from
Nov 10, 2017
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5f13367
WIP: Add color theme mixins; default to secondary color
acdvorak Nov 3, 2017
77c524b
WIP: Improve selector readability
acdvorak Nov 3, 2017
6ea9f63
WIP: Colocate all state-dependent color styles
acdvorak Nov 4, 2017
87c46c6
WIP: Colocate disabled color styles
acdvorak Nov 4, 2017
8ad26d1
WIP: Remove unnecessary !important
acdvorak Nov 4, 2017
7d20c68
WIP: Create mixin for off/disabled thumb fill/stroke
acdvorak Nov 4, 2017
5d25bb2
WIP: Add TODOs to rename mixins
acdvorak Nov 4, 2017
e798a29
WIP: Rename mixins to match M2 spec
acdvorak Nov 4, 2017
d2f6514
WIP: Add example of custom color to demo page
acdvorak Nov 4, 2017
a6b08cc
feat(theme): Add new tone mixins and deprecate old one
acdvorak Nov 4, 2017
638a5ed
fix(slider): Don't hide focus ring on discrete sliders
acdvorak Nov 4, 2017
ca11cf0
WIP: Ensure that disabled state always overrides custom colors
acdvorak Nov 4, 2017
f76e929
WIP: M2-ify colors (except `--off`)
acdvorak Nov 4, 2017
6bb2c2f
WIP: Remove `--off` modifier class
acdvorak Nov 4, 2017
c51a0ce
WIP: Auto-generate rail/tick color; remove those public mixins & colo…
acdvorak Nov 4, 2017
05039ba
WIP: Combine/simplify mixins
acdvorak Nov 4, 2017
3f68cd2
WIP: Add accessible mixin for value pin color
acdvorak Nov 4, 2017
9a82f6a
WIP: Lower max value in demo page to make tick marks more visible
acdvorak Nov 4, 2017
30c4497
Merge branch 'master' into feat/theme/slider-mixins
acdvorak Nov 6, 2017
2acab33
WIP: Remove unused variables
acdvorak Nov 6, 2017
43ce89c
WIP: Reorder mixins
acdvorak Nov 7, 2017
0f1b301
WIP: Add mdc-slider-color-accessible mixin
acdvorak Nov 7, 2017
a4b25d8
WIP: Simplify thumb stroke cutout
acdvorak Nov 7, 2017
53582d2
WIP: Use different colors for each element in custom demo
acdvorak Nov 7, 2017
805d5a3
WIP: Fix preexisting demo bug
acdvorak Nov 9, 2017
1e95d4a
WIP: Improve styling of demo page
acdvorak Nov 9, 2017
2951603
WIP: Increase max value of demo params from 50 to 100
acdvorak Nov 9, 2017
cd985cb
Merge branch 'master' into feat/theme/slider-mixins
acdvorak Nov 9, 2017
de882ef
WIP: Replace `-impl_` with `_` in private mixin names
acdvorak Nov 9, 2017
e7188f3
WIP: Use `:not()` selectors instead of `!important`
acdvorak Nov 9, 2017
8af9b25
WIP: Explicitly import theme dependencies
acdvorak Nov 9, 2017
64e2dfd
WIP: Support theme props as color values in mixin
acdvorak Nov 9, 2017
48fac78
WIP: Use high-level color mixin instead of individual mixins
acdvorak Nov 9, 2017
987f595
WIP: Add mixins to customize rail and tick mark color
acdvorak Nov 10, 2017
cdcbf44
WIP: Add mixin param to docs
acdvorak Nov 10, 2017
dc48efe
Merge branch 'master' into feat/theme/slider-mixins
acdvorak Nov 10, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .stylelintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ rules:
- if
- mixin
- return
- warn
# Disallow "@extend" in scss.
# http://csswizardry.com/2016/02/mixins-better-for-performance/
# http://vanseodesign.com/css/sass-mixin-or-extend/
Expand All @@ -259,7 +260,7 @@ rules:
selector-no-qualifying-type: true
# In general, we should not be modifying elements within our components, since we can't
# predict the use cases in which users would add a certain type of element into a component.
selector-max-type:
selector-max-type:
- 0
- ignoreTypes:
- /fieldset/
Expand Down
73 changes: 59 additions & 14 deletions demos/slider.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

.mdc-theme--dark {
background-color: #333;
--mdc-theme-primary: #64dd17;
}

.custom-bg {
Expand Down Expand Up @@ -69,7 +68,7 @@
<section class="hero">
<div id="hero-slider-wrapper">
<div id="hero-slider" class="mdc-slider" tabindex="0"
role="slider" aria-valuemin="0" aria-valuemax="100" aria-valuenow="30"
role="slider" aria-valuemin="0" aria-valuemax="50" aria-valuenow="20"
aria-label="Select Value">
<div class="mdc-slider__track-container">
<div class="mdc-slider__track"></div>
Expand All @@ -84,17 +83,14 @@
</div>
</section>

<section class="example"><em>Note that in browsers that support custom properties, we alter theme's primary
color when using the dark theme toggle so that the slider appears more visible</em></section>

<section id="slider-example" class="example">
<h2>Continuous Slider</h2>
<div class="slider-example">
<p id="example-cs-label">Select Value:</p>

<div class="example-slider-wrapper">
<div id="continuous-mdc-slider" class="mdc-slider" tabindex="0" role="slider"
aria-valuemin="0" aria-valuemax="100" aria-valuenow="30"
aria-valuemin="0" aria-valuemax="50" aria-valuenow="20"
aria-labelledby="example-cs-label">
<div class="mdc-slider__track-container">
<div class="mdc-slider__track"></div>
Expand Down Expand Up @@ -123,14 +119,14 @@ <h2>Discrete Slider</h2>

<div class="example-slider-wrapper">
<div id="discrete-mdc-slider" class="mdc-slider mdc-slider--discrete" tabindex="0" role="slider"
aria-valuemin="0" aria-valuemax="100" aria-valuenow="30"
aria-valuemin="0" aria-valuemax="50" aria-valuenow="20"
aria-labelledby="example-ds-label">
<div class="mdc-slider__track-container">
<div class="mdc-slider__track"></div>
</div>
<div class="mdc-slider__thumb-container">
<div class="mdc-slider__pin">
<span class="mdc-slider__pin-value-marker">30</span>
<span class="mdc-slider__pin-value-marker">20</span>
</div>
<svg class="mdc-slider__thumb" width="21" height="21">
<circle cx="10.5" cy="10.5" r="7.875"></circle>
Expand All @@ -148,13 +144,13 @@ <h2>Discrete Slider</h2>
</p>
</div>

<h2>Discrete Slider with markers</h2>
<h2>Discrete Slider with Tick Marks</h2>
<div class="slider-example">
<p id="example-ds-marker-label">Select Value:</p>

<div class="example-slider-wrapper">
<div id="discrete-mdc-slider-w-marker" class="mdc-slider mdc-slider--discrete mdc-slider--display-markers" tabindex="0" role="slider"
aria-valuemin="0" aria-valuemax="100" aria-valuenow="30"
aria-valuemin="0" aria-valuemax="50" aria-valuenow="20"
aria-labelledby="example-ds-marker-label">
<div class="mdc-slider__track-container">
<div class="mdc-slider__track"></div>
Expand All @@ -163,7 +159,7 @@ <h2>Discrete Slider with markers</h2>
</div>
<div class="mdc-slider__thumb-container">
<div class="mdc-slider__pin">
<span class="mdc-slider__pin-value-marker">30</span>
<span class="mdc-slider__pin-value-marker">20</span>
</div>
<svg class="mdc-slider__thumb" width="21" height="21">
<circle cx="10.5" cy="10.5" r="7.875"></circle>
Expand All @@ -181,19 +177,52 @@ <h2>Discrete Slider with markers</h2>
</p>
</div>

<h2>Custom Colored Discrete Slider with Tick Marks</h2>
<div class="slider-example">
<p id="example-custom-ds-marker-label">Select Value:</p>

<div class="example-slider-wrapper">
<div id="custom-discrete-mdc-slider-w-marker" class="mdc-slider mdc-slider--discrete mdc-slider--display-markers demo-slider--custom" tabindex="0" role="slider"
aria-valuemin="0" aria-valuemax="50" aria-valuenow="20"
aria-labelledby="example-custom-ds-marker-label">
<div class="mdc-slider__track-container">
<div class="mdc-slider__track"></div>
<div class="mdc-slider__track-marker-container">
</div>
</div>
<div class="mdc-slider__thumb-container">
<div class="mdc-slider__pin">
<span class="mdc-slider__pin-value-marker">20</span>
</div>
<svg class="mdc-slider__thumb" width="21" height="21">
<circle cx="10.5" cy="10.5" r="7.875"></circle>
</svg>
<div class="mdc-slider__focus-ring"></div>
</div>
</div>
</div>

<p>
Value from <code>MDCSlider:input</code> event: <span id="custom-discrete-slider-w-marker-value">0</span>
</p>
<p>
Value from <code>MDCSlider:change</code> event: <span id="custom-discrete-slider-w-marker-committed-value">0</span>
</p>
</div>

<div>
<label>
Min: <input name="min" type="number" min="0" max="100" value="0">
Min: <input name="min" type="number" min="0" max="50" value="0">
</label>
</div>
<div>
<label>
Max: <input name="max" type="number" min="0" max="100" value="100">
Max: <input name="max" type="number" min="0" max="50" value="50">
</label>
</div>
<div>
<label>
Step: <input name="step" type="number" min="0" max="100" value="0">
Step: <input name="step" type="number" min="0" max="50" value="0">
</label>
</div>
<div>
Expand Down Expand Up @@ -268,22 +297,36 @@ <h2>Discrete Slider with markers</h2>
discreteWMarkerCommittedValue.textContent = discreteWMarkerSlider.value;
});

var customDiscreteWMarkerValue = demoRoot.querySelector('#custom-discrete-slider-w-marker-value');
var customDiscreteWMarkerCommittedValue = demoRoot.querySelector('#custom-discrete-slider-w-marker-committed-value');
var customDiscreteWMarkerSliderEl = demoRoot.querySelector('#custom-discrete-mdc-slider-w-marker');
var customDiscreteWMarkerSlider = new mdc.slider.MDCSlider(customDiscreteWMarkerSliderEl);
customDiscreteWMarkerSlider.listen('MDCSlider:input', function() {
customDiscreteWMarkerValue.textContent = customDiscreteWMarkerSlider.value;
});
customDiscreteWMarkerSlider.listen('MDCSlider:change', function() {
customDiscreteWMarkerCommittedValue.textContent = customDiscreteWMarkerSlider.value;
});

min.addEventListener('input', function() {
continuousSlider.min = parseFloat(min.value);
discreteSlider.min = parseFloat(min.value);
discreteWMarkerSlider.min = parseFloat(min.value);
customDiscreteWMarkerSlider.min = parseFloat(min.value);
});

max.addEventListener('input', function() {
continuousSlider.max = parseFloat(max.value);
discreteSlider.max = parseFloat(max.value);
discreteWMarkerSlider.max = parseFloat(max.value);
customDiscreteWMarkerSlider.max = parseFloat(max.value);
});

step.addEventListener('input', function() {
continuousSlider.step = parseFloat(step.value);
discreteSlider.step = parseFloat(step.value);
discreteWMarkerSlider.step = parseFloat(step.value);
customDiscreteWMarkerSlider.step = parseFloat(step.value);
});

darkTheme.addEventListener('change', function() {
Expand All @@ -296,6 +339,7 @@ <h2>Discrete Slider with markers</h2>
continuousSlider.disabled = disabled.checked;
discreteSlider.disabled = disabled.checked;
discreteWMarkerSlider.disabled = disabled.checked;
customDiscreteWMarkerSlider.disabled = disabled.checked;
});

useCustomColor.addEventListener('change', function() {
Expand All @@ -315,6 +359,7 @@ <h2>Discrete Slider with markers</h2>
continuousSlider.layout();
discreteSlider.layout();
discreteWMarkerSlider.layout();
customDiscreteWMarkerSlider.layout();
});
}
})();
Expand Down
11 changes: 11 additions & 0 deletions demos/slider.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,14 @@
@import "./common";
@import "../packages/mdc-slider/mdc-slider";
@import "../packages/mdc-typography/mdc-typography";
@import "../packages/mdc-theme/color-palette";

.demo-slider--custom {
$main-color: $material-color-red-700;
$tick-color: $material-color-red-300;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to be used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Removed. I originally had a separate mixin for tick mark color, but then I removed it because I wasn't sure if it was supposed to be customizable. I figured we can always add that mixin back if necessary.


@include mdc-slider-rail-color($main-color);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that it seems to be ridiculously common to set all of these to the same color, should we have a mixin that sets all of them? Maybe takes a color + an ink color for the popup indicator?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

I decided to keep it simple and pick the ink color automatically, just like mdc-slider-value-pin-fill-color-accessible.

The new combined mixin is mdc-slider-color-accessible.

@include mdc-slider-thumb-color($main-color);
@include mdc-slider-focus-halo-color($main-color);
@include mdc-slider-value-pin-fill-color-accessible($main-color);
}
52 changes: 21 additions & 31 deletions packages/mdc-slider/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ Note that **vertical sliders and range (multi-thumb) sliders are not supported,
from the material design spec**.

Also note that we have taken certain deviations from the UX within the spec, e.g. nuances as to the
slider's motion across the track, as well as the style of the slider thumb when in the "off" state
in dark mode. Thus, there may be some treatments which deviate from the mocks. These deviations
arose out of design feedback from seeing sliders used on the web, and thus have been endorsed by
the Material Design team.
slider's motion across the track, as well as the color of the tick marks. Thus, there may be some
treatments which deviate from the mocks. These deviations arose out of design feedback from seeing
sliders used on the web, and thus have been endorsed by the Material Design team.

## Design and API Documentation

Expand Down Expand Up @@ -170,8 +169,8 @@ track container.
</div>
```

> **NOTE**: When the provided step is indivisble to distance between max and min,
> we place the secondary to last marker proportionally at where thumb could reach and
> **NOTE**: When the provided step is indivisible to distance between max and min,
> we place the second to last marker proportionally at where thumb could reach and
> place the last marker at max value.

### Disabled sliders
Expand Down Expand Up @@ -276,20 +275,31 @@ use to build a custom MDCSlider component for their framework.

### Theming

All thematic elements of sliders make use of the **primary theme color**, including when the
By default, all thematic elements of sliders make use of the **secondary theme color**, including when the
component is used within a dark mode context.

#### Setting the correct background color for disabled/off slider thumbs
#### Sass Mixins

One tricky issue with sliders is how the thumb is supposed to look when in the disabled or
"off" states. In these cases, certain portions of the slider's thumb and track are supposed to
Mixin | Description
--- | ---
`mdc-slider-rail-color($color)` | Sets the color of the rail (aka track)
`mdc-slider-thumb-color($color)` | Sets the color of the thumb (grab handle)
`mdc-slider-focus-halo-color($color)` | Sets the color of the focus halo
`mdc-slider-value-pin-fill-color-accessible($color)` | Sets the fill color of the value indicator pin and automatically sets an accessible ink color with high contrast
`mdc-slider-value-pin-fill-color($color)` | Sets the fill color of the value indicator pin
`mdc-slider-value-pin-ink-color($color)` | Sets the ink color of the value indicator pin

#### Setting the correct background color for disabled slider thumbs

One tricky issue with sliders is how the thumb is supposed to look when in the disabled state.
In this case, certain portions of the slider's thumb and track are supposed to
become "transparent" and reveal the background color behind it. However, this presents a problem as
there is no elegant way to derive what the background color behind the slider should be. We could
theoretically walk up the DOM until we found an ancestor with a set background, but that would break
the component's encapsulation model.

To solve this, you can supply a css custom property `--mdc-slider-bg-color-behind-component`. When
used, this will override the default colors used for the disabled/off state slider thumb and use
used, this will override the default color used for the disabled state slider thumb and use
the color specified:

```css
Expand All @@ -313,23 +323,6 @@ $mdc-slider-default-assumed-bg-color: #fafafa;

If you're using the `.mdc-theme--dark` classes, you'll want to override `$mdc-slider-dark-theme-assumed-bg-color` instead.

Finally, if you'd prefer not to use Sass, you can use the following CSS snippet which should be
included _after_ the `@material/slider` styles have been loaded onto the page:

```css
.mdc-slider--off .mdc-slider__thumb {
fill: YOUR_CUSTOM_COLOR;
}

.mdc-slider--disabled .mdc-slider__thumb {
stroke: YOUR_CUSTOM_COLOR !important;
}
```

Note that the following snippet assumes you are not using `mdc-theme--dark`. If you are, you may
need to add `.mdc-theme--dark` as an additional ancestor selector before the `.mdc-slider--*`
classes.

### Tips/Tricks

#### Preventing [FOUC](https://en.wikipedia.org/wiki/Flash_of_unstyled_content)
Expand All @@ -338,9 +331,6 @@ Because `MDCSlider` updates its UI based on the values it reads in when it is in
potential for an incorrect first render before the script containing the `MDCSlider` initialization
logic executes. To avoid this, there are a few things you can attempt to do:

If the slider's `aria-valuenow` is set to `"0"`, you can manually add the class `mdc-slider--off`
to the root `mdc-slider` element.

If you know how wide the slider will be at the time of instantiation, you can add an inline style
to the `mdc-slider__thumb-container`/`mdc-slider__track` elements which will position it correctly
by using similar logic to that within our code:
Expand Down
30 changes: 30 additions & 0 deletions packages/mdc-slider/_keyframes.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

@keyframes mdc-slider-emphasize {
0% {
animation-timing-function: ease-out;
}

50% {
animation-timing-function: ease-in;
transform: scale(.85);
}

100% {
transform: scale(.571);
}
}
Loading