Skip to content

Commit

Permalink
Added green-red gradient colored slider (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
inescri authored Mar 26, 2024
1 parent b0addfa commit e9db17f
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 3 deletions.
14 changes: 14 additions & 0 deletions packages/design-system/src/elements/toniq-slider/slider-logic.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {clamp, isObject, truncateNumber} from '@augment-vir/common';
import {css, unsafeCSS} from 'element-vir';
import {createReasonableLogarithmicRange, findClosestRangeIndex} from '../../augments/number';
import {ToniqSliderDoubleRangeValue, ToniqSliderInputs} from './toniq-slider-inputs';

Expand Down Expand Up @@ -45,6 +46,19 @@ export const toniqSliderTestIds = {
slider: 'slider',
};

export const toniqSliderTempColorLevels = {
hot: 'rgb(200,0,0)',
medium: 'orange',
cold: 'rgb(0,200,0)',
} as const;

export function setToniqSliderTempColor(level: keyof typeof toniqSliderTempColorLevels) {
return css`
background-color: ${unsafeCSS(toniqSliderTempColorLevels[level])};
color: ${unsafeCSS(toniqSliderTempColorLevels[level])};
`;
}

export function getLabelElementBoxes(host: HTMLElement) {
const lowerLabel = host.shadowRoot?.querySelector(
`.${classNames.lowerLabelWrapper} .${classNames.labelPercentMarginWrapper}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,7 @@ export type ToniqSliderInputs = Readonly<
/** Appends the given string to the slider's value for label text. */
suffix?: string;
disabled?: boolean;
/** Temperature like background */
colorTemperature?: boolean;
} & (ToniqSliderSingleValueInputs | ToniqSliderDoubleValueInputs)
>;
Original file line number Diff line number Diff line change
Expand Up @@ -258,5 +258,31 @@ export const toniqSliderPage = defineBookPage({
`;
},
});
defineExample({
title: 'Color Temperature',
stateInitStatic: {
value: 9,
},
styles: css`
${defaultExampleWidth}
`,
renderCallback({state, updateState}) {
return html`
<${ToniqSlider.assign({
value: state.value,
colorTemperature: true,
min: 0,
max: 100,
})}
${listen(ToniqSlider.events.valueChange, (event) => {
if (typeof event.detail !== 'number') {
throw new Error('was expecting a single numeric slider value');
}
updateState({value: event.detail});
})}
></${ToniqSlider}>
`;
},
});
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,24 @@ describe(ToniqSlider.tagName, () => {
}),
);

it(
'should correctly show slider handle color',
createFixtureTest(async () => {
const rendered = await fixture(html`
<${ToniqSlider.assign({
max: 100,
min: 0,
value: 90,
colorTemperature: true,
})} />
`);

const sliderInput = getByTestId(toniqSliderTestIds.slider, rendered);
assertInstanceOf(sliderInput, HTMLInputElement);
assert.isTrue(sliderInput.classList.contains('hot'));
}),
);

runFocusTests(
html`
<${ToniqSlider.assign({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
makeLabel,
maybeFixSliderValues,
maybeTransformToLogValue,
setToniqSliderTempColor,
toniqSliderTempColorLevels,
toniqSliderTestIds,
} from './slider-logic';
import {ToniqSliderDoubleRangeValue, ToniqSliderInputs} from './toniq-slider-inputs';
Expand All @@ -44,6 +46,16 @@ const thumbHoverStyle = css`
transform: scale(1.2);
`;

function getCurrentTemp(percentage: number) {
if (percentage > 100 * (2 / 3)) {
return 'cold';
}
if (percentage > 100 * (1 / 3)) {
return 'medium';
}
return 'hot';
}

export function maybeFixRecursively(slider: (typeof ToniqSlider)['instanceType']) {
requestAnimationFrame(() => {
const doubleCheckedValue = getAllVerifiedAndFixedInputs(
Expand Down Expand Up @@ -82,6 +94,15 @@ export const ToniqSlider = defineToniqElement<ToniqSliderInputs>()({
display: block;
}
.${unsafeCSS(classNames.range)}-temp {
background: linear-gradient(
90deg,
${unsafeCSS(toniqSliderTempColorLevels.cold)},
${unsafeCSS(toniqSliderTempColorLevels.medium)},
${unsafeCSS(toniqSliderTempColorLevels.hot)}
);
}
.${unsafeCSS(classNames.range)} {
display: flex;
height: 8px;
Expand All @@ -102,6 +123,10 @@ export const ToniqSlider = defineToniqElement<ToniqSliderInputs>()({
${applyBackgroundAndForeground(toniqColors.accentPrimary)};
}
.progress-temp {
background-color: transparent;
}
.${unsafeCSS(classNames.labelOuterWrapper)} {
position: absolute;
z-index: 1;
Expand Down Expand Up @@ -156,11 +181,31 @@ export const ToniqSlider = defineToniqElement<ToniqSliderInputs>()({
${thumbStyle}
}
.${unsafeCSS(classNames.slider)}.hot::-moz-range-thumb {
${setToniqSliderTempColor('hot')}
}
.${unsafeCSS(classNames.slider)}.medium::-moz-range-thumb {
${setToniqSliderTempColor('medium')}
}
.${unsafeCSS(classNames.slider)}.cold::-moz-range-thumb {
${setToniqSliderTempColor('cold')}
}
/* these selectors fail if combined with a comma */
.${unsafeCSS(classNames.slider)}::-webkit-slider-thumb {
${thumbStyle}
}
.${unsafeCSS(classNames.slider)}.hot::-webkit-slider-thumb {
${setToniqSliderTempColor('hot')}
}
.${unsafeCSS(classNames.slider)}.medium::-webkit-slider-thumb {
${setToniqSliderTempColor('medium')}
}
.${unsafeCSS(classNames.slider)}.cold::-webkit-slider-thumb {
${setToniqSliderTempColor('cold')}
}
/* these selectors fail if combined with a comma */
.${unsafeCSS(classNames.slider)}::-webkit-slider-thumb:hover {
${thumbHoverStyle}
Expand Down Expand Up @@ -379,14 +424,17 @@ export const ToniqSlider = defineToniqElement<ToniqSliderInputs>()({

return html`
<div
class="range"
class="range ${inputs.colorTemperature ? 'range-temp' : ''}"
${onResize(() => {
updateState({
rangeWidth: getRangeWidth(host),
});
})}
>
<div class="progress" style="left: 0px; right: ${progressRightPosition}"></div>
<div
class="progress ${inputs.colorTemperature ? 'progress-temp' : ''}"
style="left: 0px; right: ${progressRightPosition}"
></div>
<span
class="${classNames.labelOuterWrapper} ${classNames.rightAlignedLabelWrapper}"
style="right: ${progressRightPosition}"
Expand All @@ -402,7 +450,9 @@ export const ToniqSlider = defineToniqElement<ToniqSliderInputs>()({
<input
?disabled=${inputs.disabled ?? false}
type="range"
class="${classNames.slider}"
class="${classNames.slider} ${inputs.colorTemperature
? getCurrentTemp(Math.abs(labelMargin))
: ''}"
step=${inputs.step}
.min=${elementLimits.min}
.max=${elementLimits.max}
Expand Down

0 comments on commit e9db17f

Please sign in to comment.