Skip to content

fix(slider): handle negative and decimal values in labels#2828

Open
Br1an67 wants to merge 1 commit intoAvaiga:developfrom
Br1an67:fix/issue-2586-slider-labels-neg-decimal
Open

fix(slider): handle negative and decimal values in labels#2828
Br1an67 wants to merge 1 commit intoAvaiga:developfrom
Br1an67:fix/issue-2586-slider-labels-neg-decimal

Conversation

@Br1an67
Copy link
Copy Markdown

@Br1an67 Br1an67 commented Mar 8, 2026

Fixes #2586

What type of PR is this? (Check all that apply)

  • 🛠 Refactor
  • ✨ Feature
  • 🐛 Bug Fix
  • ⚡ Optimization
  • 📝 Documentation Update

Description

Fixed the slider labels functionality to properly handle negative and decimal values. The issue was caused by two problems in the label parsing logic:

  1. parseInt(key, 10) was used instead of parseFloat(key), causing decimal values like 0.2, 0.4 to be truncated to 0
  2. -1 was used as a sentinel value for "not found", which prevented labels at position -1 from being displayed

The fix uses parseFloat for parsing and undefined as the sentinel value instead of -1.

Related Tickets & Documents

How to reproduce the issue

  1. Create a slider with decimal step and labels:
tgb.slider(
    value="{None}",
    min=0,
    max=1,
    step=0.1,
    labels={
        0.0: "0",
        0.2: "0.2",
        0.4: "0.4",
        0.6: "0.6",
        0.8: "0.8",
        1.0: "1",
    },
)
  1. Observe that all labels except 0 and 1 are grouped at position 0

Or with negative values:

tgb.slider(
    value="{None}",
    min=-2,
    max=2,
    step=1,
    labels={
        -2: "-2",
        -1: "-1",  # This label disappears
        0: "0",
        1: "1",
        2: "2",
    },
)
  1. Observe that the label at position -1 is missing

Backporting

This change should be backported to:

  • 3.0
  • 3.1
  • 4.0
  • develop

Checklist

  • ✅ This solution meets the acceptance criteria of the related issue.
  • 📝 The related issue checklist is completed.
  • 🧪 This PR includes unit tests for the developed code.
  • 🔄 End-to-End tests have been added or updated.
    • Not needed: Unit tests cover the fix adequately
  • 📚 The documentation has been updated, or a dedicated issue has been created.
    • Not needed: This is a bug fix, no API changes
  • 📌 The release notes have been updated.
    • Not needed: Minor bug fix

Changes

 frontend/taipy-gui/src/components/Taipy/Slider.spec.tsx | 47 ++++++++++++++++++++++
 frontend/taipy-gui/src/components/Taipy/Slider.tsx      | 16 ++++----
 2 files changed, 56 insertions(+), 7 deletions(-)

Use parseFloat instead of parseInt to properly parse decimal label
keys, and use undefined as sentinel instead of -1 to allow labels
at position -1.
@arcanaxion arcanaxion requested a review from FredLL-Avaiga March 9, 2026 00:51
@FredLL-Avaiga FredLL-Avaiga requested a review from Copilot March 9, 2026 08:16
@FredLL-Avaiga FredLL-Avaiga added 📈 Improvement Improvement of a feature. 🟨 Priority: Medium Not blocking but should be addressed 📝Release Notes Impacts the Release Notes or the Documentation in general GUI: Front-End labels Mar 9, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes slider label parsing so marks can be created for negative and decimal positions (addressing #2586), avoiding truncation and the -1 “not found” sentinel collision.

Changes:

  • Updated label-key parsing to use parseFloat() and undefined as the “not found” sentinel.
  • Added unit tests covering decimal, negative, and negative-decimal label keys.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
frontend/taipy-gui/src/components/Taipy/Slider.tsx Adjusts marks/labels parsing to correctly accept negative and fractional numeric keys.
frontend/taipy-gui/src/components/Taipy/Slider.spec.tsx Adds tests intended to validate mark rendering for decimal/negative label keys.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +312 to +358
it("shows marks with decimal values", async () => {
const labels = {
"0": "0",
"0.2": "0.2",
"0.4": "0.4",
"0.6": "0.6",
"0.8": "0.8",
"1": "1",
};
const { container } = render(<Slider value={0.5} min={0} max={1} step={0.1} labels={JSON.stringify(labels)} />);
expect(container).toHaveTextContent("0");
expect(container).toHaveTextContent("0.2");
expect(container).toHaveTextContent("0.4");
expect(container).toHaveTextContent("0.6");
expect(container).toHaveTextContent("0.8");
expect(container).toHaveTextContent("1");
});
it("shows marks with negative values including -1", async () => {
const labels = {
"-2": "-2",
"-1": "-1",
"0": "0",
"1": "1",
"2": "2",
};
const { container } = render(<Slider value={0} min={-2} max={2} step={1} labels={JSON.stringify(labels)} />);
expect(container).toHaveTextContent("-2");
expect(container).toHaveTextContent("-1");
expect(container).toHaveTextContent("0");
expect(container).toHaveTextContent("1");
expect(container).toHaveTextContent("2");
});
it("shows marks with negative decimal values", async () => {
const labels = {
"-1.0": "-1.0",
"-0.5": "-0.5",
"0": "0",
"0.5": "0.5",
"1.0": "1.0",
};
const { container } = render(<Slider value={0} min={-1} max={1} step={0.5} labels={JSON.stringify(labels)} />);
expect(container).toHaveTextContent("-1.0");
expect(container).toHaveTextContent("-0.5");
expect(container).toHaveTextContent("0");
expect(container).toHaveTextContent("0.5");
expect(container).toHaveTextContent("1.0");
});
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

These new tests are declared async but don’t await anything. Removing async avoids misleading signal about asynchronous behavior and prevents accidental swallowed assertion timing issues.

Copilot uses AI. Check for mistakes.
Comment on lines +321 to +327
const { container } = render(<Slider value={0.5} min={0} max={1} step={0.1} labels={JSON.stringify(labels)} />);
expect(container).toHaveTextContent("0");
expect(container).toHaveTextContent("0.2");
expect(container).toHaveTextContent("0.4");
expect(container).toHaveTextContent("0.6");
expect(container).toHaveTextContent("0.8");
expect(container).toHaveTextContent("1");
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

The new decimal-label test only asserts that the label text exists in the DOM; it doesn’t verify that marks are placed at distinct positions/values. This test would likely still pass in the pre-fix behavior where decimal keys were truncated (marks rendered but grouped at the same tick). Consider asserting mark placement (e.g., querying mark label elements and checking their computed left/bottom percentages, or verifying the style/position differs per label).

Suggested change
const { container } = render(<Slider value={0.5} min={0} max={1} step={0.1} labels={JSON.stringify(labels)} />);
expect(container).toHaveTextContent("0");
expect(container).toHaveTextContent("0.2");
expect(container).toHaveTextContent("0.4");
expect(container).toHaveTextContent("0.6");
expect(container).toHaveTextContent("0.8");
expect(container).toHaveTextContent("1");
const { container, getByText } = render(
<Slider value={0.5} min={0} max={1} step={0.1} labels={JSON.stringify(labels)} />
);
expect(container).toHaveTextContent("0");
expect(container).toHaveTextContent("0.2");
expect(container).toHaveTextContent("0.4");
expect(container).toHaveTextContent("0.6");
expect(container).toHaveTextContent("0.8");
expect(container).toHaveTextContent("1");
// Ensure that the marks corresponding to decimal values are positioned distinctly.
const labelElements = Object.values(labels).map((text) => getByText(text));
const leftPositions = labelElements.map((elt) => (elt as HTMLElement).style.left);
const distinctLeftPositions = new Set(leftPositions);
// If all labels were rendered at the same tick, all left positions would be identical (or all empty).
expect(distinctLeftPositions.size).toBeGreaterThan(1);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

@FredLL-Avaiga FredLL-Avaiga left a comment

Choose a reason for hiding this comment

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

Excellent @Br1an67
Thank you
can you change parseFloat to Number ?

if (lovIdx !== -1) {
idx = lovIdx;
} else {
const num = parseFloat(key);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd prefer to use Number(key)

@FredLL-Avaiga
Copy link
Copy Markdown
Member

@Br1an67 can you reply to copilot ?

@Br1an67 Br1an67 force-pushed the fix/issue-2586-slider-labels-neg-decimal branch from 4e0a386 to f21c998 Compare March 18, 2026 00:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

GUI: Front-End 📈 Improvement Improvement of a feature. 🟨 Priority: Medium Not blocking but should be addressed 📝Release Notes Impacts the Release Notes or the Documentation in general

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[🐛 BUG] Slider labels don't work well with negative and decimal values

3 participants