Skip to content

Commit cb557ca

Browse files
committed
Add a tooltip showing the actual range slider input values
1 parent df32014 commit cb557ca

File tree

3 files changed

+54
-26
lines changed

3 files changed

+54
-26
lines changed

package-lock.json

Lines changed: 0 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
},
3232
"dependencies": {
3333
"@node-projects/base-custom-webcomponent": "^0.27.6",
34-
"@node-projects/slider.webcomponent": "^1.0.6",
3534
"@node-projects/web-component-designer-visualization-addons": "^0.1.45",
3635
"construct-style-sheets-polyfill": "^3.1.0"
3736
}

src/slider/SliderWebcomponent.ts

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { BaseCustomWebComponentConstructorAppend, css, html } from "@node-projec
33
export class SliderWebcomponent extends BaseCustomWebComponentConstructorAppend {
44

55
public static override readonly style = css`
6-
76
.slider-container {
87
width: 100%;
98
}
@@ -57,11 +56,34 @@ export class SliderWebcomponent extends BaseCustomWebComponentConstructorAppend
5756
pointer-events: auto;
5857
appearance: none;
5958
}
60-
59+
60+
.tooltip {
61+
position: absolute;
62+
background-color: #555;
63+
color: #fff;
64+
padding: 5px;
65+
border-radius: 4px;
66+
font-size: 12px;
67+
white-space: nowrap;
68+
transform: translateX(-50%);
69+
z-index: 1;
70+
visibility: hidden;
71+
margin-top: 10px; /* Adjust based on your needs */
72+
}
73+
74+
.tooltip::after {
75+
content: '';
76+
position: absolute;
77+
bottom: 100%; /* Position at the top of the tooltip */
78+
left: 50%;
79+
transform: translateX(-50%);
80+
border-width: 5px;
81+
border-style: solid;
82+
border-color: transparent transparent #555 transparent;
83+
}
6184
`;
6285

6386
public static override readonly template = html`
64-
6587
<div class="slider-container">
6688
<div id="slider"></div>
6789
</div>
@@ -70,8 +92,9 @@ export class SliderWebcomponent extends BaseCustomWebComponentConstructorAppend
7092
<div class="range-input">
7193
<input type="range" class="min-range" step="1">
7294
<input type="range" class="max-range" step="1">
95+
<div class="tooltip" id="min-tooltip"></div>
96+
<div class="tooltip" id="max-tooltip"></div>
7397
</div>
74-
7598
`;
7699

77100
public static readonly is = 'node-projects-slider';
@@ -80,6 +103,8 @@ export class SliderWebcomponent extends BaseCustomWebComponentConstructorAppend
80103

81104
private _rangeInputs: HTMLInputElement[];
82105
private _valuesGap: number = 1;
106+
private _minTooltip: HTMLElement;
107+
private _maxTooltip: HTMLElement;
83108

84109
attributeChangedCallback(name: string, oldValue: string, newValue: string) {
85110
if (newValue === 'undefined') return;
@@ -101,13 +126,15 @@ export class SliderWebcomponent extends BaseCustomWebComponentConstructorAppend
101126

102127
ready() {
103128
this._rangeInputs = Array.from(this._getDomElements(".range-input input"));
129+
this._minTooltip = this._getDomElement("min-tooltip");
130+
this._maxTooltip = this._getDomElement("max-tooltip");
104131

105132
this._parseAttributesToProperties();
106133

107134
// Add event listeners to range input elements
108135
for (let i = 0; i < this._rangeInputs.length; i++) {
109136
this._rangeInputs[i].addEventListener("input", e => {
110-
this._handleRangeInputInputEvent(e);
137+
this._handleRangeInputInputEvent(e);
111138
});
112139

113140
this._rangeInputs[i].addEventListener("change", e => {
@@ -136,7 +163,7 @@ export class SliderWebcomponent extends BaseCustomWebComponentConstructorAppend
136163
valueMin = Math.max(min, Math.min(parseInt(newValue), valueMax - this._valuesGap));
137164
this._updateSliderPosition(valueMin, max, true);
138165
if (this._rangeInputs) {
139-
this._rangeInputs[0].value = valueMin.toString();
166+
this._rangeInputs[0].value = valueMin.toString();
140167
}
141168
} else if (changedAttr === 'value-max') {
142169
if (parseInt(newValue) > max) {
@@ -180,17 +207,31 @@ export class SliderWebcomponent extends BaseCustomWebComponentConstructorAppend
180207
this._rangeInputs[1].value = (minRangeInputMinVal + this._valuesGap).toString();
181208
}
182209
} else {
183-
if ((e.target as HTMLInputElement).className === "min-range") {
210+
if ((e.target as HTMLInputElement).className === "min-range") {
184211
this._setAttributeFromInternal('value-min', minRangeInputMinVal.toString());
212+
this._updateTooltipPosition(this._minTooltip, this._rangeInputs[0]);
185213

186-
} else if ((e.target as HTMLInputElement).className === "max-range") {
214+
} else if ((e.target as HTMLInputElement).className === "max-range") {
187215
this._setAttributeFromInternal('value-max', maxRangeInputMaxVal.toString());
188-
}
216+
this._updateTooltipPosition(this._maxTooltip, this._rangeInputs[1]);
217+
}
189218
}
190219
}
191220

221+
private _updateTooltipPosition(tooltip: HTMLElement, rangeInput: HTMLInputElement) {
222+
const rangeInputRect = rangeInput.getBoundingClientRect();
223+
const thumbWidth = 18; // Width of the thumb (adjust if needed)
224+
const relativeThumbPosition = ((parseInt(rangeInput.value) - parseInt(rangeInput.min)) / (parseInt(rangeInput.max) - parseInt(rangeInput.min))) * (rangeInputRect.width - thumbWidth);
225+
const unknownOffset = 3;
226+
227+
tooltip.style.left = `${relativeThumbPosition + thumbWidth / 2 + unknownOffset}px`;
228+
tooltip.style.top = '10px';
229+
tooltip.textContent = rangeInput.value;
230+
tooltip.style.visibility = 'visible';
231+
}
232+
192233
private _setAttributeFromInternal(name: string, value: string) {
193-
this.setAttribute(name,value);
234+
this.setAttribute(name, value);
194235
}
195236

196237
private _handleRangeInputChangeEvent(e: Event) {
@@ -203,6 +244,9 @@ export class SliderWebcomponent extends BaseCustomWebComponentConstructorAppend
203244
} else if ((e.target as HTMLInputElement).className === "max-range") {
204245
this._dispatchChangeEvent('value-max-changed', maxRangeInputMaxVal);
205246
}
247+
248+
this._minTooltip.style.visibility = 'hidden';
249+
this._maxTooltip.style.visibility = 'hidden';
206250
}
207251

208252
private _updateSliderPosition(value: number, max: number, isMin: boolean) {

0 commit comments

Comments
 (0)