Skip to content

Commit 2f6ff51

Browse files
Slider core design feedback (#4899)
1 parent c59472d commit 2f6ff51

35 files changed

+793
-667
lines changed

packages/lab/src/__tests__/__e2e__/slider/RangeSlider.cy.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -389,10 +389,13 @@ describe("Given a Range Slider", () => {
389389
cy.findByText("Custom Max Label").should("exist");
390390
});
391391

392-
it("should be disabled when set", () => {
392+
it("should be disabled when set and should not receive focus when disabled", () => {
393393
cy.mount(<Default disabled defaultValue={[2, 3]} />);
394394

395395
cy.findAllByRole("slider").should("be.disabled");
396+
cy.realPress("Tab");
397+
cy.findAllByRole("slider").eq(0).should("not.be.focused");
398+
cy.findAllByRole("slider").eq(1).should("not.be.focused");
396399
});
397400

398401
it("should format the tooltip text and min/max labels when a format function is passed", () => {

packages/lab/src/__tests__/__e2e__/slider/Slider.cy.tsx

+7-5
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,15 @@ describe("Given a Slider", () => {
198198
cy.findByRole("slider").focus().realPress("ArrowRight");
199199
cy.findByRole("slider").should("have.value", "5");
200200
cy.findByRole("slider").focus().realPress("ArrowRight");
201-
cy.findByRole("slider").should("have.value", 9);
201+
cy.findByRole("slider").should("have.value", "9");
202202

203203
// Reverse
204204
cy.findByRole("slider").focus().realPress("ArrowLeft");
205-
cy.findByRole("slider").should("have.value", 5);
205+
cy.findByRole("slider").should("have.value", "5");
206206
cy.findByRole("slider").focus().realPress("ArrowLeft");
207-
cy.findByRole("slider").should("have.value", 2);
207+
cy.findByRole("slider").should("have.value", "2");
208208
cy.findByRole("slider").focus().realPress("ArrowLeft");
209-
cy.findByRole("slider").should("have.value", 2);
209+
cy.findByRole("slider").should("have.value", "2");
210210
});
211211

212212
it("should render inline min/max labels and marks when provided", () => {
@@ -310,10 +310,12 @@ describe("Given a Slider", () => {
310310
cy.findByText("Custom Max Label").should("exist");
311311
});
312312

313-
it("should be disabled when set", () => {
313+
it("should be disabled when set and should not receive focus when disabled", () => {
314314
cy.mount(<Default disabled defaultValue={2} />);
315315

316316
cy.findByRole("slider").should("be.disabled");
317+
cy.realPress("Tab");
318+
cy.findByRole("slider").should("not.be.focused");
317319
});
318320

319321
it("should format the tooltip text when a format function is passed", () => {

packages/lab/src/slider/internal/SliderTooltip.css

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.saltSliderTooltip {
22
background: var(--salt-container-primary-background);
3-
border-color: var(--salt-status-info-borderColor);
3+
border-color: var(--salt-container-primary-borderColor);
44
border-style: var(--saltTooltip-borderStyle, var(--salt-container-borderStyle));
55
border-width: var(--saltTooltip-borderWidth, var(--salt-size-border));
66
border-radius: var(--saltTooltip-borderRadius, var(--salt-palette-corner-weak, 0));
@@ -29,7 +29,11 @@
2929
pointer-events: none;
3030
top: 100%;
3131
transform: translateX(-50%);
32-
stroke: var(--salt-status-info-borderColor);
32+
stroke: var(--salt-container-primary-borderColor);
3333
stroke-width: var(--salt-size-border);
3434
width: var(--salt-size-icon);
3535
}
36+
37+
.saltSliderTooltip-text {
38+
white-space: nowrap;
39+
}

packages/lab/src/slider/internal/SliderTooltip.tsx

+9-2
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,16 @@ export const SliderTooltip = ({ value, open }: SliderTooltipProps) => {
3232
aria-hidden="true"
3333
viewBox="0 1 14 14"
3434
>
35-
<path d="M0,0 H14 L7,7 Q7,7 7,7 Z" />
35+
<path
36+
d="M0,0 H14 L7,7 Q7,7 7,7 Z"
37+
stroke=" var(--salt-container-primary-background)"
38+
/>
39+
<path
40+
d="M0,0 H14 L7,7 Q7,7 7,7 Z"
41+
stroke="var(--salt-container-primary-borderColor)"
42+
/>
3643
</svg>
37-
<Text>{value}</Text>
44+
<Text className={withBaseName("text")}>{value}</Text>
3845
</div>
3946
);
4047
};

packages/lab/src/slider/internal/SliderTrack.css

+73-49
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@
22
--slider-track-background: var(--salt-track-borderColor);
33
--slider-track-fill: var(--salt-accent-borderColor);
44
--slider-progressPercentage: 0%;
5+
--slider-tick-height: calc((var(--salt-size-selectable) - var(--salt-size-bar)) / 2);
56
/* For range */
67
--slider-progressPercentageStart: 0%;
78
--slider-progressPercentageEnd: 0%;
89

9-
--slider-mark-percentage: 0%;
10-
1110
display: flex;
1211
width: 100%;
1312
}
1413

14+
.saltSliderTrack.saltSliderTrack-withMarks {
15+
/* To wrap the marks within the boundary box */
16+
margin-bottom: calc(var(--salt-size-base) / 2);
17+
}
18+
1519
.saltSliderTrack-disabled {
1620
cursor: var(--salt-selectable-cursor-disabled);
1721
}
@@ -20,21 +24,30 @@
2024
align-items: center;
2125
display: flex;
2226
flex-direction: row;
23-
gap: var(--salt-spacing-50);
27+
gap: var(--salt-spacing-100);
2428
width: 100%;
2529
}
2630

2731
.saltSliderTrack-wrapper {
2832
align-items: center;
33+
cursor: var(--salt-selectable-cursor-hover);
2934
display: flex;
3035
flex: 1;
31-
height: var(--salt-size-base);
36+
height: var(--salt-size-selectable);
3237
position: relative;
3338
width: 100%;
3439
}
3540

41+
.saltSliderTrack-disabled,
42+
.saltSliderTrack-disabled .saltSliderTrack-wrapper {
43+
cursor: var(--salt-selectable-cursor-disabled);
44+
}
45+
46+
.saltSliderTrack-disabled .saltSliderTrack-wrapper {
47+
pointer-events: none;
48+
}
49+
3650
.saltSliderTrack-rail {
37-
cursor: var(--salt-selectable-cursor-hover);
3851
display: flex;
3952
flex: 100%;
4053
height: var(--salt-size-bar);
@@ -53,7 +66,7 @@
5366
background: var(--slider-track-fill);
5467
border-top-left-radius: var(--salt-palette-corner-weaker);
5568
border-bottom-left-radius: var(--salt-palette-corner-weaker);
56-
width: calc(var(--slider-progressPercentage) - (var(--salt-size-border-strong) / 2));
69+
width: calc(var(--slider-progressPercentage) - 1.5 * var(--salt-size-border-strong));
5770
}
5871

5972
.saltSliderTrack-hasMinTick.saltSliderTrack-rail::before {
@@ -64,7 +77,7 @@
6477
background: var(--slider-track-background);
6578
border-top-right-radius: var(--salt-palette-corner-weaker);
6679
border-bottom-right-radius: var(--salt-palette-corner-weaker);
67-
width: calc(100% - var(--slider-progressPercentage) - (var(--salt-size-border-strong) * 2));
80+
width: calc(100% - var(--slider-progressPercentage) - 1.5 * var(--salt-size-border-strong));
6881
}
6982

7083
.saltSliderTrack-hasMaxTick.saltSliderTrack-rail::after {
@@ -73,20 +86,20 @@
7386

7487
.saltSliderTrack-range .saltSliderTrack-rail::before {
7588
background: var(--slider-track-background);
76-
width: calc(var(--slider-progressPercentageStart) - (var(--salt-size-border-strong) * 2));
89+
width: calc(var(--slider-progressPercentageStart) - (var(--salt-size-border-strong) * 1.5));
7790
}
7891

7992
.saltSliderTrack-range .saltSliderTrack-rail::after {
8093
background: var(--slider-track-background);
81-
width: calc(100% - var(--slider-progressPercentageEnd) - (var(--salt-size-border-strong) * 2));
94+
width: calc(100% - var(--slider-progressPercentageEnd) - (var(--salt-size-border-strong) * 1.5));
8295
}
8396

8497
.saltSliderTrack-range .saltSliderTrack-rail .saltSliderTrack-fill {
8598
background: var(--slider-track-fill);
8699
height: 100%;
87-
left: calc(var(--slider-progressPercentageStart) + (var(--salt-size-border-strong) / 2));
100+
left: calc(var(--slider-progressPercentageStart) + 1.5 * var(--salt-size-border-strong));
88101
position: absolute;
89-
width: calc(var(--slider-progressPercentageEnd) - var(--slider-progressPercentageStart) - var(--salt-size-border-strong));
102+
width: calc(var(--slider-progressPercentageEnd) - var(--slider-progressPercentageStart) - var(--salt-size-border-strong) * 3);
90103
}
91104

92105
.saltSliderTrack-minLabel,
@@ -95,7 +108,7 @@
95108
}
96109

97110
.saltSliderTrack-dragging,
98-
.saltSliderTrack-dragging .saltSliderTrack-rail {
111+
.saltSliderTrack-dragging .saltSliderTrack-wrapper {
99112
cursor: var(--salt-draggable-grab-cursor-active);
100113
}
101114

@@ -104,65 +117,76 @@
104117
--slider-track-background: var(--salt-track-borderColor-disabled);
105118
}
106119

107-
.saltSliderTrack-disabled .saltSliderTrack-rail {
108-
pointer-events: none;
109-
}
110-
111-
.saltSliderTrack-marks {
120+
.saltSliderTrack-ticks {
121+
top: calc(var(--salt-size-bar) + var(--slider-tick-height));
112122
position: absolute;
113-
user-select: none;
114123
width: 100%;
115-
top: calc((var(--salt-size-base) / 2) + (var(--salt-size-bar) / 2));
116124
}
117125

118-
.saltSliderTrack-mark {
119-
align-items: center;
120-
display: flex;
121-
flex-direction: column;
126+
.saltSliderTrack-tick {
127+
background: var(--slider-track-background);
128+
height: var(--slider-tick-height);
122129
position: absolute;
123-
justify-content: center;
124-
left: var(--slider-mark-percentage);
125-
transform: translateX(-50%);
126-
gap: 4px;
130+
transform: translate(-50%);
131+
width: var(--salt-size-border-strong);
127132
}
128133

129-
.saltSliderTrack-markLabel {
130-
white-space: nowrap;
131-
overflow: hidden;
132-
text-overflow: ellipsis;
134+
.saltSliderTrack-withTicks .saltSliderTrack-tickHidden {
135+
visibility: hidden;
133136
}
134137

135-
.saltSliderTrack-markTick {
136-
height: 5px;
137-
width: var(--salt-size-border-strong);
138-
background: var(--slider-track-background);
139-
visibility: hidden;
138+
.saltSliderTrack-tickSelected {
139+
background: var(--slider-track-fill);
140140
}
141141

142-
.saltSliderTrack-withMarkTicks .saltSliderTrack-markTick {
143-
visibility: visible;
142+
.saltSliderTrack-tick:first-of-type {
143+
transform: unset;
144144
}
145145

146-
.saltSliderTrack-withMarkTicks .saltSliderTrack-markTickHidden {
147-
visibility: hidden;
146+
.saltSliderTrack-tick:last-of-type {
147+
transform: translateX(-100%);
148+
}
149+
150+
.saltSliderTrack-marks {
151+
position: absolute;
152+
user-select: none;
153+
width: 100%;
148154
}
149155

150-
.saltSliderTrack-mark:last-of-type .saltSliderTrack-markTick {
156+
.saltSliderTrack-markLabel {
157+
color: var(--salt-content-secondary-foreground);
158+
font-family: var(--salt-text-label-fontFamily);
159+
font-weight: var(--salt-text-label-fontWeight);
160+
font-size: var(--salt-text-label-fontSize);
161+
line-height: var(--salt-text-label-lineHeight);
162+
overflow: hidden;
163+
position: absolute;
164+
text-overflow: ellipsis;
151165
transform: translateX(-50%);
166+
top: calc(var(--slider-tick-height) + var(--salt-spacing-50));
167+
white-space: nowrap;
152168
}
153169

154-
.saltSliderTrack-mark:first-of-type .saltSliderTrack-markTick {
155-
transform: translateX(50%);
170+
.saltSliderTrack-constrainLabelPosition .saltSliderTrack-markLabel:first-of-type {
171+
transform: translateX(0%);
156172
}
157173

158-
.saltSliderTrack-markSelected {
159-
background: var(--slider-track-fill);
174+
.saltSliderTrack-constrainLabelPosition .saltSliderTrack-markLabel:last-of-type {
175+
transform: translateX(-100%);
160176
}
161177

162-
.saltSliderTrack-constrainLabelPosition .saltSliderTrack-mark:first-of-type .saltSliderTrack-markLabel {
163-
transform: translateX(50%);
178+
/* Styles applied when slider and range slider are inside a form field */
179+
180+
.saltFormField .saltSliderTrack.saltSliderTrack-withMark {
181+
margin-bottom: 0;
164182
}
165183

166-
.saltSliderTrack-constrainLabelPosition .saltSliderTrack-mark:last-of-type .saltSliderTrack-markLabel {
167-
transform: translateX(-50%);
184+
.saltFormField .saltSliderTrack-container {
185+
--saltFormField-label-width: 10%;
186+
187+
height: var(--salt-size-base);
188+
}
189+
190+
.saltFormField .saltSliderTrack-markLabel {
191+
top: calc((var(--salt-size-base) - var(--salt-size-bar)) / 2);
168192
}

0 commit comments

Comments
 (0)