Skip to content

Commit

Permalink
Fix: Make slider handle decimal values (#959)
Browse files Browse the repository at this point in the history
* Make slider handle decimal values
  • Loading branch information
nikolajlauridsen authored Nov 18, 2024
1 parent ed30b6d commit 4b814df
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 38 deletions.
21 changes: 18 additions & 3 deletions packages/uui-range-slider/lib/uui-range-slider.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const TRACK_HEIGHT = 3;
const TRACK_PADDING = 12;
const STEP_MIN_WIDTH = 24;

const CountDecimalPlaces = (num: number) => {
const decimalIndex = num.toString().indexOf('.');
return decimalIndex >= 0 ? num.toString().length - decimalIndex - 1 : 0;
};

// TODO: ability to focus on the range, to enable keyboard interaction to move the range.
// TODO: Ability to click outside a range, to move the range if the maxGap has been reached.
// TODO: .
Expand Down Expand Up @@ -624,8 +629,16 @@ export class UUIRangeSliderElement extends UUIFormControlMixin(LitElement, '') {

private _renderThumbValues() {
return html`<div class="thumb-values">
<span><span>${this._lowInputValue}</span></span>
<span><span>${this._highInputValue}</span></span>
<span
><span
>${this._lowInputValue.toFixed(CountDecimalPlaces(this._step))}</span
></span
>
<span
><span
>${this._highInputValue.toFixed(CountDecimalPlaces(this._step))}</span
></span
>
</div>`;
}

Expand Down Expand Up @@ -656,7 +669,9 @@ export class UUIRangeSliderElement extends UUIFormControlMixin(LitElement, '') {
let index = 0;
const stepValues = new Array(stepAmount + 1)
.fill(this._step)
.map(step => this._min + step * index++);
.map(step =>
(this._min + step * index++).toFixed(CountDecimalPlaces(this._step)),
);

return html`<div class="step-values">
${stepValues.map(value => html`<span><span>${value}</span></span>`)}
Expand Down
73 changes: 38 additions & 35 deletions packages/uui-slider/lib/uui-slider.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,14 @@ import { UUISliderEvent } from './UUISliderEvent';
const TRACK_PADDING = 12;
const STEP_MIN_WIDTH = 24;

const RenderTrackSteps = (steps: number[], stepWidth: number) => {
return svg`
${steps.map(el => {
if (stepWidth >= STEP_MIN_WIDTH) {
const x = Math.round(TRACK_PADDING + stepWidth * steps.indexOf(el));
return svg`<circle class="track-step" cx="${x}" cy="50%" r="4.5" />`;
}
return svg``;
})}
`;
};

const RenderStepValues = (
steps: number[],
stepWidth: number,
hide: boolean,
) => {
if (hide) return nothing;

return html`<div id="step-values">
${steps.map(
el =>
html` <span
><span>
${steps.length <= 20 && stepWidth >= STEP_MIN_WIDTH
? el.toFixed(0)
: nothing}
</span></span
>`,
)}
</div>`;
};

const GenerateStepArray = (start: number, stop: number, step: number) =>
Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step);

const CountDecimalPlaces = (num: number) => {
const decimalIndex = num.toString().indexOf('.');
return decimalIndex >= 0 ? num.toString().length - decimalIndex - 1 : 0;
};

/**
* @element uui-slider
* @description - Native `<input type="range">` wrapper.
Expand Down Expand Up @@ -295,6 +267,37 @@ export class UUISliderElement extends UUIFormControlMixin(LitElement, '') {
this.dispatchEvent(new UUISliderEvent(UUISliderEvent.CHANGE));
}

renderTrackSteps() {
return svg`
${this._steps.map(el => {
if (this._stepWidth >= STEP_MIN_WIDTH) {
const x = Math.round(
TRACK_PADDING + this._stepWidth * this._steps.indexOf(el),
);
return svg`<circle class="track-step" cx="${x}" cy="50%" r="4.5" />`;
}
return svg``;
})}
`;
}

renderStepValues() {
if (this.hideStepValues) return nothing;

return html`<div id="step-values">
${this._steps.map(
el =>
html` <span
><span>
${this._steps.length <= 20 && this._stepWidth >= STEP_MIN_WIDTH
? el.toFixed(CountDecimalPlaces(this.step))
: nothing}
</span></span
>`,
)}
</div>`;
}

render() {
return html`
<input
Expand All @@ -312,7 +315,7 @@ export class UUISliderElement extends UUIFormControlMixin(LitElement, '') {
<div id="track" aria-hidden="true">
<svg height="100%" width="100%">
<rect x="9" y="9" height="3" rx="2" />
${RenderTrackSteps(this._steps, this._stepWidth)}
${this.renderTrackSteps()}
</svg>
<div id="track-inner" aria-hidden="true">
Expand All @@ -323,7 +326,7 @@ export class UUISliderElement extends UUIFormControlMixin(LitElement, '') {
</div>
</div>
</div>
${RenderStepValues(this._steps, this._stepWidth, this.hideStepValues)}
${this.renderStepValues()}
`;
}

Expand Down
9 changes: 9 additions & 0 deletions packages/uui-slider/lib/uui-slider.story.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,12 @@ export const Readonly: Story = {
readonly: true,
},
};

export const DecimalValue: Story = {
args: {
min: 0,
max: 1,
step: 0.1,
value: 0.5,
},
};

0 comments on commit 4b814df

Please sign in to comment.