draft-components 2.9.2 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/css/draft-components.css +156 -311
- package/css/draft-components.dark.css +12 -1
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.js +0 -1
- package/dist/components/slider/get-offset-relative-to-thumb.d.ts +1 -0
- package/dist/components/slider/get-offset-relative-to-thumb.js +8 -0
- package/dist/components/slider/index.d.ts +2 -1
- package/dist/components/slider/index.js +1 -1
- package/dist/components/slider/range-slider.d.ts +30 -0
- package/dist/components/slider/range-slider.js +47 -0
- package/dist/components/slider/slider-thumb.d.ts +20 -0
- package/dist/components/slider/slider-thumb.js +15 -0
- package/dist/components/slider/slider-tick-marks.d.ts +9 -4
- package/dist/components/slider/slider-tick-marks.js +11 -10
- package/dist/components/slider/slider-track.d.ts +11 -0
- package/dist/components/slider/slider-track.js +14 -0
- package/dist/components/slider/slider.d.ts +18 -13
- package/dist/components/slider/slider.js +23 -32
- package/dist/lib/react-helpers.d.ts +0 -1
- package/dist/lib/react-helpers.js +0 -3
- package/package.json +1 -1
- package/dist/components/slider-range/index.d.ts +0 -2
- package/dist/components/slider-range/index.js +0 -1
- package/dist/components/slider-range/slider-range-data-list.d.ts +0 -10
- package/dist/components/slider-range/slider-range-data-list.js +0 -12
- package/dist/components/slider-range/slider-range-label.d.ts +0 -9
- package/dist/components/slider-range/slider-range-label.js +0 -5
- package/dist/components/slider-range/slider-range.d.ts +0 -20
- package/dist/components/slider-range/slider-range.js +0 -147
package/css/draft-components.css
CHANGED
|
@@ -1969,396 +1969,241 @@
|
|
|
1969
1969
|
}
|
|
1970
1970
|
|
|
1971
1971
|
.dc-slider {
|
|
1972
|
+
--dc-slider-icon-color: var(--dc-secondary-text-color);
|
|
1973
|
+
|
|
1974
|
+
/* Track properties */
|
|
1972
1975
|
--dc-slider-track-height: 4px;
|
|
1976
|
+
--dc-slider-track-radius: 2px;
|
|
1973
1977
|
--dc-slider-track-bg: var(--dc-control-bg-inset);
|
|
1974
|
-
--dc-slider-track-bg
|
|
1975
|
-
--dc-slider-tick-color: var(--dc-control-border-color);
|
|
1976
|
-
--dc-slider-tick-label-color: var(--dc-control-secondary-text-color);
|
|
1977
|
-
--dc-slider-focus-ring-color: var(--dc-focus-ring-color);
|
|
1978
|
+
--dc-slider-active-track-bg: var(--dc-control-primary-color);
|
|
1978
1979
|
|
|
1979
1980
|
/* Thumb properties */
|
|
1980
|
-
--dc-slider-thumb-width: 20px;
|
|
1981
1981
|
--dc-slider-thumb-height: 20px;
|
|
1982
|
-
--dc-slider-thumb-
|
|
1982
|
+
--dc-slider-thumb-width: 20px;
|
|
1983
|
+
--dc-slider-thumb-radius: 50%;
|
|
1984
|
+
--dc-slider-thumb-bg: var(--dc-control-primary-color);
|
|
1985
|
+
--dc-slider-thumb-border: 2px solid var(--dc-control-bg);
|
|
1986
|
+
--dc-slider-thumb-transition: box-shadow 150ms ease-in-out;
|
|
1983
1987
|
--dc-slider-thumb-shadow:
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1988
|
+
var(--dc-shadow-sm),
|
|
1989
|
+
var(--dc-shadow),
|
|
1990
|
+
var(--dc-shadow-md);
|
|
1991
|
+
--dc-slider-thumb-focus-ring:
|
|
1987
1992
|
var(--dc-slider-thumb-shadow),
|
|
1988
|
-
0 0 0
|
|
1993
|
+
0 0 0 4px var(--dc-focus-ring-color);
|
|
1989
1994
|
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1995
|
+
/* Label properties */
|
|
1996
|
+
--dc-slider-label-gap: 4px;
|
|
1997
|
+
--dc-slider-label-height: 24px;
|
|
1998
|
+
--dc-slider-label-padding-x: 0.5em;
|
|
1999
|
+
--dc-slider-label-radius: 6px;
|
|
2000
|
+
--dc-slider-label-border: 1px solid var(--dc-white);
|
|
2001
|
+
--dc-slider-label-text-color: var(--dc-gray-50);
|
|
2002
|
+
--dc-slider-label-bg: var(--dc-gray-800);
|
|
1996
2003
|
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2004
|
+
/* Tick mark properties */
|
|
2005
|
+
--dc-slider-tick-mark-width: 1px;
|
|
2006
|
+
--dc-slider-tick-mark-height: 6px;
|
|
2007
|
+
--dc-slider-tick-mark-color: rgb(var(--dc-gray-900-rgb) / 0.3);
|
|
2008
|
+
--dc-slider-tick-marks-gap: 4px;
|
|
2000
2009
|
|
|
2001
|
-
|
|
2002
|
-
|
|
2010
|
+
color-scheme: light;
|
|
2011
|
+
display: inline-flex;
|
|
2012
|
+
width: 240px;
|
|
2013
|
+
min-width: 0;
|
|
2014
|
+
max-width: 100%;
|
|
2003
2015
|
}
|
|
2004
2016
|
|
|
2005
|
-
.dc-
|
|
2006
|
-
|
|
2007
|
-
-moz-appearance: none;
|
|
2008
|
-
appearance: none;
|
|
2009
|
-
height: var(--dc-slider-track-height);
|
|
2010
|
-
margin: calc((var(--dc-slider-thumb-height) - var(--dc-slider-track-height)) / 2) 0;
|
|
2017
|
+
.dc-slider_range {
|
|
2018
|
+
margin: 0;
|
|
2011
2019
|
padding: 0;
|
|
2012
|
-
border-radius: 2px;
|
|
2013
|
-
background: var(--dc-slider-track-bg);
|
|
2014
|
-
}
|
|
2015
|
-
|
|
2016
|
-
.dc-slider__input:focus {
|
|
2017
|
-
outline: none;
|
|
2018
|
-
}
|
|
2019
|
-
|
|
2020
|
-
.dc-slider__input::-webkit-slider-thumb {
|
|
2021
|
-
-webkit-appearance: none;
|
|
2022
|
-
appearance: none;
|
|
2023
|
-
cursor: pointer;
|
|
2024
|
-
box-sizing: border-box;
|
|
2025
|
-
width: var(--dc-slider-thumb-width);
|
|
2026
|
-
height: var(--dc-slider-thumb-height);
|
|
2027
2020
|
border: none;
|
|
2028
|
-
border-radius: 50%;
|
|
2029
|
-
background: var(--dc-slider-thumb-bg);
|
|
2030
|
-
box-shadow: var(--dc-slider-thumb-shadow);
|
|
2031
2021
|
}
|
|
2032
2022
|
|
|
2033
|
-
.dc-
|
|
2034
|
-
-
|
|
2035
|
-
appearance: none;
|
|
2036
|
-
cursor: pointer;
|
|
2037
|
-
box-sizing: border-box;
|
|
2038
|
-
width: var(--dc-slider-thumb-width);
|
|
2039
|
-
height: var(--dc-slider-thumb-height);
|
|
2040
|
-
border: none;
|
|
2041
|
-
border-radius: 50%;
|
|
2042
|
-
background: var(--dc-slider-thumb-bg);
|
|
2043
|
-
box-shadow: var(--dc-slider-thumb-shadow);
|
|
2044
|
-
}
|
|
2045
|
-
|
|
2046
|
-
.dc-slider__input::-ms-thumb {
|
|
2047
|
-
appearance: none;
|
|
2048
|
-
cursor: pointer;
|
|
2049
|
-
box-sizing: border-box;
|
|
2050
|
-
width: var(--dc-slider-thumb-width);
|
|
2051
|
-
height: var(--dc-slider-thumb-height);
|
|
2052
|
-
border: none;
|
|
2053
|
-
border-radius: 50%;
|
|
2054
|
-
background: var(--dc-slider-thumb-bg);
|
|
2055
|
-
box-shadow: var(--dc-slider-thumb-shadow);
|
|
2056
|
-
}
|
|
2057
|
-
|
|
2058
|
-
.dc-slider__input:disabled::-webkit-slider-thumb {
|
|
2059
|
-
cursor: default;
|
|
2060
|
-
}
|
|
2061
|
-
|
|
2062
|
-
.dc-slider__input:disabled::-moz-range-thumb {
|
|
2063
|
-
cursor: default;
|
|
2064
|
-
}
|
|
2065
|
-
|
|
2066
|
-
.dc-slider__input:disabled::-ms-thumb {
|
|
2067
|
-
cursor: default;
|
|
2068
|
-
}
|
|
2069
|
-
|
|
2070
|
-
.dc-slider__input:focus::-webkit-slider-thumb {
|
|
2071
|
-
box-shadow: var(--dc-slider-thumb-shadow-focus);
|
|
2072
|
-
}
|
|
2073
|
-
|
|
2074
|
-
.dc-slider__input:focus::-moz-range-thumb {
|
|
2075
|
-
box-shadow: var(--dc-slider-thumb-shadow-focus);
|
|
2076
|
-
}
|
|
2077
|
-
|
|
2078
|
-
.dc-slider__input:focus::-ms-thumb {
|
|
2079
|
-
box-shadow: var(--dc-slider-thumb-shadow-focus);
|
|
2080
|
-
}
|
|
2081
|
-
|
|
2082
|
-
.dc-slider_thumb_rect .dc-slider__input::-webkit-slider-thumb {
|
|
2083
|
-
border-radius: calc(var(--dc-slider-thumb-width) / 2);
|
|
2084
|
-
}
|
|
2085
|
-
|
|
2086
|
-
.dc-slider_thumb_rect .dc-slider__input::-moz-range-thumb {
|
|
2087
|
-
border-radius: calc(var(--dc-slider-thumb-width) / 2);
|
|
2088
|
-
}
|
|
2089
|
-
|
|
2090
|
-
.dc-slider_thumb_rect .dc-slider__input::-ms-thumb {
|
|
2091
|
-
border-radius: calc(var(--dc-slider-thumb-width) / 2);
|
|
2023
|
+
.dc-slider_disabled {
|
|
2024
|
+
opacity: var(--dc-disabled-state-opacity);
|
|
2092
2025
|
}
|
|
2093
2026
|
|
|
2094
|
-
.dc-
|
|
2027
|
+
.dc-slider_full-width {
|
|
2095
2028
|
display: flex;
|
|
2096
|
-
align-items: flex-start;
|
|
2097
|
-
justify-content: space-between;
|
|
2098
|
-
margin-top: 4px;
|
|
2099
|
-
}
|
|
2100
|
-
|
|
2101
|
-
.dc-slider-tick-mark {
|
|
2102
|
-
font-size: 12px;
|
|
2103
|
-
color: var(--dc-slider-tick-label-color);
|
|
2104
|
-
display: inline-flex;
|
|
2105
|
-
flex-direction: column;
|
|
2106
|
-
align-items: center;
|
|
2107
|
-
justify-content: flex-start;
|
|
2108
|
-
width: var(--dc-slider-thumb-width);
|
|
2109
|
-
text-align: center;
|
|
2110
|
-
white-space: nowrap;
|
|
2111
|
-
}
|
|
2112
|
-
|
|
2113
|
-
.dc-slider-tick-mark::before {
|
|
2114
|
-
content: "";
|
|
2115
|
-
display: inline-block;
|
|
2116
|
-
flex: none;
|
|
2117
|
-
width: 2px;
|
|
2118
|
-
height: 8px;
|
|
2119
|
-
background: var(--dc-slider-tick-color);
|
|
2120
|
-
}
|
|
2121
|
-
|
|
2122
|
-
.dc-slider-tick-mark__label {
|
|
2123
|
-
padding-top: 4px;
|
|
2124
|
-
}
|
|
2125
|
-
|
|
2126
|
-
.dc-slider-range {
|
|
2127
|
-
--dc-slider-range-active-track-left: 0%;
|
|
2128
|
-
--dc-slider-range-active-track-right: 0%;
|
|
2129
|
-
--dc-slider-range-labels-margin-bottom: 12px;
|
|
2130
|
-
--dc-slider-range-tick-marks-margin-top: 2px;
|
|
2131
|
-
|
|
2132
|
-
/* Label properties */
|
|
2133
|
-
--dc-slider-range-label-height: 24px;
|
|
2134
|
-
--dc-slider-range-label-padding-x: 8px;
|
|
2135
|
-
--dc-slider-range-label-radius: 6px;
|
|
2136
|
-
--dc-slider-range-label-text-color: var(--dc-white);
|
|
2137
|
-
--dc-slider-range-label-bg: var(--dc-gray-800);
|
|
2138
|
-
|
|
2139
|
-
/* Track properties */
|
|
2140
|
-
--dc-slider-range-track-width: 100%;
|
|
2141
|
-
--dc-slider-range-track-height: 4px;
|
|
2142
|
-
--dc-slider-range-track-radius: 0;
|
|
2143
|
-
--dc-slider-range-track-border-color: transparent;
|
|
2144
|
-
--dc-slider-range-track-bg: var(--dc-control-bg-inset);
|
|
2145
|
-
--dc-slider-range-active-track-bg: var(--dc-control-primary-color);
|
|
2146
|
-
|
|
2147
|
-
/* Thumb properties */
|
|
2148
|
-
--dc-slider-range-thumb-width: 20px;
|
|
2149
|
-
--dc-slider-range-thumb-height: 20px;
|
|
2150
|
-
--dc-slider-range-thumb-border: 4px solid var(--dc-control-primary-color);
|
|
2151
|
-
--dc-slider-range-thumb-radius: 50%;
|
|
2152
|
-
--dc-slider-range-thumb-bg: var(--dc-control-bg);
|
|
2153
|
-
--dc-slider-range-thumb-shadow: 0 0 0 transparent;
|
|
2154
|
-
--dc-slider-focus-ring:
|
|
2155
|
-
var(--dc-slider-range-thumb-shadow),
|
|
2156
|
-
0 0 0 1px white,
|
|
2157
|
-
0 0 0 4px var(--dc-focus-ring-color);
|
|
2158
|
-
|
|
2159
|
-
/* Tick mark properties */
|
|
2160
|
-
--dc-slider-range-tick-mark-font: var(--dc-text-xs);
|
|
2161
|
-
--dc-slider-range-tick-mark-gap: 4px;
|
|
2162
|
-
--dc-slider-range-tick-mark-width: 2px;
|
|
2163
|
-
--dc-slider-range-tick-mark-height: 8px;
|
|
2164
|
-
--dc-slider-range-tick-mark-color: var(--dc-control-border-color);
|
|
2165
|
-
--dc-slider-range-tick-mark-label-color: var(--dc-control-secondary-text-color);
|
|
2166
|
-
|
|
2167
|
-
color-scheme: light;
|
|
2168
|
-
font-family: var(--dc-primary-font);
|
|
2169
|
-
position: relative;
|
|
2170
|
-
}
|
|
2171
|
-
|
|
2172
|
-
.dc-slider-range__labels-container {
|
|
2173
|
-
position: relative;
|
|
2174
2029
|
width: 100%;
|
|
2175
|
-
height: var(--dc-slider-range-thumb-height);
|
|
2176
|
-
margin-bottom: var(--dc-slider-range-labels-margin-bottom);
|
|
2177
|
-
border: none;
|
|
2178
|
-
}
|
|
2179
|
-
|
|
2180
|
-
.dc-slider-range__label,
|
|
2181
|
-
.dc-slider-range__label[hidden] {
|
|
2182
|
-
display: inline-flex;
|
|
2183
2030
|
}
|
|
2184
2031
|
|
|
2185
|
-
.dc-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
top: 0;
|
|
2190
|
-
left: 0;
|
|
2032
|
+
.dc-slider__body {
|
|
2033
|
+
color: var(--dc-slider-icon-color);
|
|
2034
|
+
display: flex;
|
|
2035
|
+
gap: 8px;
|
|
2191
2036
|
align-items: center;
|
|
2192
|
-
|
|
2193
|
-
height: var(--dc-slider-
|
|
2194
|
-
max-width: 100%;
|
|
2195
|
-
padding: 0 var(--dc-slider-range-label-padding-x);
|
|
2196
|
-
text-align: center;
|
|
2197
|
-
border-radius: var(--dc-slider-range-label-radius);
|
|
2198
|
-
background: var(--dc-slider-range-label-bg);
|
|
2199
|
-
font-variant-numeric: tabular-nums;
|
|
2037
|
+
width: 100%;
|
|
2038
|
+
min-height: var(--dc-slider-thumb-height);
|
|
2200
2039
|
}
|
|
2201
2040
|
|
|
2202
|
-
.dc-
|
|
2203
|
-
|
|
2204
|
-
|
|
2041
|
+
.dc-slider__body_has_label {
|
|
2042
|
+
margin-top: calc(
|
|
2043
|
+
var(--dc-slider-label-height) +
|
|
2044
|
+
var(--dc-slider-label-gap)
|
|
2045
|
+
);
|
|
2205
2046
|
}
|
|
2206
2047
|
|
|
2207
|
-
.dc-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2048
|
+
.dc-slider__body_has_tick-marks {
|
|
2049
|
+
margin-bottom: calc(
|
|
2050
|
+
var(--dc-slider-tick-mark-height) -
|
|
2051
|
+
var(--dc-slider-thumb-height) / 2 +
|
|
2052
|
+
var(--dc-slider-track-height) / 2 +
|
|
2053
|
+
var(--dc-slider-tick-marks-gap)
|
|
2054
|
+
);
|
|
2211
2055
|
}
|
|
2212
2056
|
|
|
2213
|
-
.dc-
|
|
2057
|
+
.dc-slider__track {
|
|
2214
2058
|
position: relative;
|
|
2215
|
-
display: block;
|
|
2216
|
-
width: var(--dc-slider-range-track-width);
|
|
2217
|
-
height: max(var(--dc-slider-range-track-height), var(--dc-slider-range-thumb-height));
|
|
2218
|
-
}
|
|
2219
|
-
|
|
2220
|
-
.dc-slider-range__track::before,
|
|
2221
|
-
.dc-slider-range__track::after {
|
|
2222
|
-
content: "";
|
|
2223
|
-
position: absolute;
|
|
2224
|
-
z-index: 0;
|
|
2225
|
-
top: 50%;
|
|
2226
|
-
display: block;
|
|
2227
|
-
box-sizing: border-box;
|
|
2228
|
-
height: var(--dc-slider-range-track-height);
|
|
2229
|
-
transform: translateY(-50%);
|
|
2230
|
-
border-radius: var(--dc-slider-range-track-radius);
|
|
2231
|
-
}
|
|
2232
|
-
|
|
2233
|
-
.dc-slider-range__track::before {
|
|
2234
2059
|
width: 100%;
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
.dc-slider-range__track::after {
|
|
2240
|
-
right: var(--dc-slider-range-active-track-right);
|
|
2241
|
-
left: var(--dc-slider-range-active-track-left);
|
|
2242
|
-
background: var(--dc-slider-range-active-track-bg);
|
|
2243
|
-
}
|
|
2244
|
-
|
|
2245
|
-
.dc-slider-range_disabled .dc-slider-range__track {
|
|
2246
|
-
opacity: var(--dc-disabled-state-opacity);
|
|
2060
|
+
height: var(--dc-slider-track-height);
|
|
2061
|
+
border-radius: var(--dc-slider-track-radius);
|
|
2062
|
+
background-color: var(--dc-slider-track-bg);
|
|
2247
2063
|
}
|
|
2248
2064
|
|
|
2249
|
-
.dc-
|
|
2065
|
+
.dc-slider__input {
|
|
2250
2066
|
-webkit-appearance: none;
|
|
2251
2067
|
-moz-appearance: none;
|
|
2252
2068
|
appearance: none;
|
|
2253
2069
|
position: absolute;
|
|
2254
|
-
z-index: 1;
|
|
2255
2070
|
top: 0;
|
|
2256
2071
|
left: 0;
|
|
2257
|
-
cursor: default;
|
|
2258
2072
|
width: 100%;
|
|
2259
2073
|
height: 100%;
|
|
2260
2074
|
margin: 0;
|
|
2261
2075
|
padding: 0;
|
|
2262
|
-
|
|
2076
|
+
border: none;
|
|
2263
2077
|
background: none;
|
|
2264
2078
|
}
|
|
2265
2079
|
|
|
2266
|
-
.dc-
|
|
2267
|
-
|
|
2080
|
+
.dc-slider__input:focus {
|
|
2081
|
+
outline: none;
|
|
2268
2082
|
}
|
|
2269
2083
|
|
|
2270
|
-
.dc-
|
|
2271
|
-
|
|
2084
|
+
.dc-slider_range .dc-slider__input {
|
|
2085
|
+
pointer-events: none;
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2088
|
+
.dc-slider__input::-moz-range-track {
|
|
2089
|
+
-moz-appearance: none;
|
|
2090
|
+
appearance: none;
|
|
2091
|
+
background: none;
|
|
2272
2092
|
}
|
|
2273
2093
|
|
|
2274
|
-
.dc-
|
|
2094
|
+
.dc-slider__input::-webkit-slider-runnable-track {
|
|
2275
2095
|
-webkit-appearance: none;
|
|
2276
2096
|
appearance: none;
|
|
2277
|
-
width: 100%;
|
|
2278
|
-
height: 100%;
|
|
2279
2097
|
background: none;
|
|
2280
2098
|
}
|
|
2281
2099
|
|
|
2282
|
-
.dc-
|
|
2100
|
+
.dc-slider__input::-moz-range-thumb {
|
|
2283
2101
|
-moz-appearance: none;
|
|
2284
2102
|
appearance: none;
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2103
|
+
display: inline-flex;
|
|
2104
|
+
box-sizing: border-box;
|
|
2105
|
+
width: var(--dc-slider-thumb-width);
|
|
2106
|
+
height: var(--dc-slider-thumb-height);
|
|
2107
|
+
-moz-transition: var(--dc-slider-thumb-transition);
|
|
2108
|
+
transition: var(--dc-slider-thumb-transition);
|
|
2109
|
+
border: var(--dc-slider-thumb-border);
|
|
2110
|
+
border-radius: var(--dc-slider-thumb-radius);
|
|
2111
|
+
background: var(--dc-slider-thumb-bg);
|
|
2112
|
+
box-shadow: var(--dc-slider-thumb-shadow);
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
.dc-slider_range .dc-slider__input::-moz-range-thumb {
|
|
2116
|
+
pointer-events: all;
|
|
2288
2117
|
}
|
|
2289
2118
|
|
|
2290
|
-
.dc-
|
|
2119
|
+
.dc-slider__input:focus::-moz-range-thumb {
|
|
2120
|
+
box-shadow: var(--dc-slider-thumb-focus-ring);
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
.dc-slider__input:focus:not(:focus-visible)::-moz-range-thumb {
|
|
2124
|
+
box-shadow: var(--dc-slider-thumb-shadow);
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2127
|
+
.dc-slider__input::-webkit-slider-thumb {
|
|
2291
2128
|
-webkit-appearance: none;
|
|
2292
2129
|
appearance: none;
|
|
2293
2130
|
display: inline-block;
|
|
2294
2131
|
box-sizing: border-box;
|
|
2295
|
-
width: var(--dc-slider-
|
|
2296
|
-
height: var(--dc-slider-
|
|
2297
|
-
|
|
2298
|
-
|
|
2132
|
+
width: var(--dc-slider-thumb-width);
|
|
2133
|
+
height: var(--dc-slider-thumb-height);
|
|
2134
|
+
-webkit-transition: var(--dc-slider-thumb-transition);
|
|
2135
|
+
transition: var(--dc-slider-thumb-transition);
|
|
2136
|
+
border: var(--dc-slider-thumb-border);
|
|
2137
|
+
border-radius: var(--dc-slider-thumb-radius);
|
|
2138
|
+
background: var(--dc-slider-thumb-bg);
|
|
2139
|
+
box-shadow: var(--dc-slider-thumb-shadow);
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
.dc-slider_range .dc-slider__input::-webkit-slider-thumb {
|
|
2299
2143
|
pointer-events: all;
|
|
2300
|
-
border: var(--dc-slider-range-thumb-border);
|
|
2301
|
-
border-radius: var(--dc-slider-range-thumb-radius);
|
|
2302
|
-
background: var(--dc-slider-range-thumb-bg);
|
|
2303
|
-
box-shadow: var(--dc-slider-range-thumb-shadow);
|
|
2304
2144
|
}
|
|
2305
2145
|
|
|
2306
|
-
.dc-
|
|
2307
|
-
box-shadow: var(--dc-slider-focus-ring);
|
|
2146
|
+
.dc-slider__input:focus::-webkit-slider-thumb {
|
|
2147
|
+
box-shadow: var(--dc-slider-thumb-focus-ring);
|
|
2308
2148
|
}
|
|
2309
2149
|
|
|
2310
|
-
.dc-
|
|
2311
|
-
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2150
|
+
.dc-slider__input:focus:not(:focus-visible)::-webkit-slider-thumb {
|
|
2151
|
+
box-shadow: var(--dc-slider-thumb-shadow);
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2154
|
+
.dc-slider__input-label {
|
|
2155
|
+
font: var(--dc-text-xs);
|
|
2156
|
+
font-variant-numeric: tabular-nums;
|
|
2157
|
+
color: var(--dc-slider-label-text-color);
|
|
2158
|
+
position: absolute;
|
|
2159
|
+
bottom: calc(
|
|
2160
|
+
var(--dc-slider-thumb-height) / 2 -
|
|
2161
|
+
var(--dc-slider-track-height) / 2 +
|
|
2162
|
+
var(--dc-slider-label-gap) +
|
|
2163
|
+
var(--dc-slider-track-height)
|
|
2164
|
+
);
|
|
2165
|
+
left: 0;
|
|
2166
|
+
display: inline-flex;
|
|
2167
|
+
align-items: center;
|
|
2168
|
+
justify-content: center;
|
|
2314
2169
|
box-sizing: border-box;
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
border: var(--dc-slider-
|
|
2321
|
-
|
|
2322
|
-
background: var(--dc-slider-range-thumb-bg);
|
|
2323
|
-
box-shadow: var(--dc-slider-range-thumb-shadow);
|
|
2170
|
+
height: var(--dc-slider-label-height);
|
|
2171
|
+
min-width: var(--dc-slider-label-height);
|
|
2172
|
+
padding: 0 var(--dc-slider-label-padding-x);
|
|
2173
|
+
transform: translateX(-50%);
|
|
2174
|
+
border: var(--dc-slider-label-border);
|
|
2175
|
+
border-radius: var(--dc-slider-label-radius);
|
|
2176
|
+
background: var(--dc-slider-label-bg);
|
|
2324
2177
|
}
|
|
2325
2178
|
|
|
2326
|
-
.dc-
|
|
2327
|
-
|
|
2179
|
+
.dc-slider__input_active,
|
|
2180
|
+
.dc-slider__input-label_active {
|
|
2181
|
+
z-index: 1;
|
|
2328
2182
|
}
|
|
2329
2183
|
|
|
2330
|
-
.dc-
|
|
2331
|
-
|
|
2332
|
-
|
|
2184
|
+
.dc-slider__tick-marks {
|
|
2185
|
+
position: relative;
|
|
2186
|
+
top: calc(
|
|
2187
|
+
var(--dc-slider-track-height) +
|
|
2188
|
+
var(--dc-slider-tick-marks-gap)
|
|
2189
|
+
);
|
|
2190
|
+
left: 0;
|
|
2333
2191
|
width: 100%;
|
|
2334
|
-
|
|
2192
|
+
height: var(--dc-slider-tick-mark-height);
|
|
2193
|
+
margin: 0;
|
|
2335
2194
|
padding: 0;
|
|
2336
2195
|
list-style: none;
|
|
2337
2196
|
}
|
|
2338
2197
|
|
|
2339
|
-
.dc-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
cursor: default;
|
|
2344
|
-
-webkit-user-select: none;
|
|
2345
|
-
-moz-user-select: none;
|
|
2346
|
-
user-select: none;
|
|
2347
|
-
flex-direction: column;
|
|
2348
|
-
gap: var(--dc-slider-range-tick-mark-gap);
|
|
2349
|
-
align-items: center;
|
|
2350
|
-
width: var(--dc-slider-range-thumb-width);
|
|
2351
|
-
min-width: var(--dc-slider-range-thumb-width);
|
|
2352
|
-
white-space: nowrap;
|
|
2353
|
-
}
|
|
2354
|
-
|
|
2355
|
-
.dc-slider-range__tick-marks > li::before {
|
|
2356
|
-
content: "";
|
|
2198
|
+
.dc-slider__tick-marks > li {
|
|
2199
|
+
position: absolute;
|
|
2200
|
+
top: 0;
|
|
2201
|
+
left: 0;
|
|
2357
2202
|
display: inline-flex;
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
background: var(--dc-slider-
|
|
2203
|
+
width: var(--dc-slider-tick-mark-width);
|
|
2204
|
+
height: var(--dc-slider-tick-mark-height);
|
|
2205
|
+
transform: translateX(-50%);
|
|
2206
|
+
background: var(--dc-slider-tick-mark-color);
|
|
2362
2207
|
}
|
|
2363
2208
|
|
|
2364
2209
|
.dc-file-picker {
|
|
@@ -401,7 +401,18 @@
|
|
|
401
401
|
|
|
402
402
|
.dark .dc-slider,
|
|
403
403
|
.dark.dc-slider {
|
|
404
|
-
|
|
404
|
+
/* Thumb properties */
|
|
405
|
+
--dc-slider-thumb-border: 2px solid var(--dc-gray-200);
|
|
406
|
+
--dc-slider-thumb-focus-ring:
|
|
407
|
+
var(--dc-slider-thumb-shadow),
|
|
408
|
+
0 0 0 4px var(--dc-focus-ring-color);
|
|
409
|
+
|
|
410
|
+
/* Label properties */
|
|
411
|
+
--dc-slider-label-border: 1px solid var(--dc-gray-600);
|
|
412
|
+
--dc-slider-label-bg: var(--dc-gray-700);
|
|
413
|
+
|
|
414
|
+
/* Tick mark properties */
|
|
415
|
+
--dc-slider-tick-mark-color: rgb(var(--dc-gray-50-rgb) / 0.5);
|
|
405
416
|
}
|
|
406
417
|
|
|
407
418
|
.dark .dc-file-picker,
|
|
@@ -28,7 +28,6 @@ export * from './segmented-control/index.js';
|
|
|
28
28
|
export * from './select/index.js';
|
|
29
29
|
export * from './selection-control/index.js';
|
|
30
30
|
export * from './slide-over/index.js';
|
|
31
|
-
export * from './slider-range/index.js';
|
|
32
31
|
export * from './slider/index.js';
|
|
33
32
|
export * from './spinner/index.js';
|
|
34
33
|
export * from './switch/index.js';
|
package/dist/components/index.js
CHANGED
|
@@ -28,7 +28,6 @@ export * from './segmented-control/index.js';
|
|
|
28
28
|
export * from './select/index.js';
|
|
29
29
|
export * from './selection-control/index.js';
|
|
30
30
|
export * from './slide-over/index.js';
|
|
31
|
-
export * from './slider-range/index.js';
|
|
32
31
|
export * from './slider/index.js';
|
|
33
32
|
export * from './spinner/index.js';
|
|
34
33
|
export * from './switch/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getOffsetRelativeToThumb(position: number): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { formatNumber, formatPercent } from '../../lib/index.js';
|
|
2
|
+
export function getOffsetRelativeToThumb(position) {
|
|
3
|
+
return 'calc(' +
|
|
4
|
+
`${formatPercent(position)} - ` +
|
|
5
|
+
`var(--dc-slider-thumb-width) * ${formatNumber(position / 2)} + ` +
|
|
6
|
+
`var(--dc-slider-thumb-width) * ${formatNumber((1 - position) / 2)}` +
|
|
7
|
+
')';
|
|
8
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './slider.js';
|
|
2
|
-
export
|
|
2
|
+
export * from './range-slider.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { SliderTickMark } from './slider-track.js';
|
|
3
|
+
export type RangeSliderValue = {
|
|
4
|
+
readonly min: number;
|
|
5
|
+
readonly max: number;
|
|
6
|
+
};
|
|
7
|
+
export type RangeSliderProps = {
|
|
8
|
+
'aria-label'?: string;
|
|
9
|
+
id?: string;
|
|
10
|
+
style?: CSSProperties;
|
|
11
|
+
className?: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
fullWidth?: boolean;
|
|
14
|
+
showLabel?: boolean;
|
|
15
|
+
iconLeft?: ReactNode;
|
|
16
|
+
iconRight?: ReactNode;
|
|
17
|
+
tickMarks?: SliderTickMark[];
|
|
18
|
+
name?: string;
|
|
19
|
+
step?: number;
|
|
20
|
+
min?: number;
|
|
21
|
+
minThumbName?: string;
|
|
22
|
+
minThumbAriaLabel?: string;
|
|
23
|
+
max?: number;
|
|
24
|
+
maxThumbName?: string;
|
|
25
|
+
maxThumbAriaLabel?: string;
|
|
26
|
+
value: RangeSliderValue;
|
|
27
|
+
onChange: (value: RangeSliderValue) => void;
|
|
28
|
+
formatValue?: (value: number) => ReactNode;
|
|
29
|
+
};
|
|
30
|
+
export declare function RangeSlider({ 'aria-label': ariaLabel, id, style, className, disabled, fullWidth, showLabel, iconLeft, iconRight, tickMarks, step, min, minThumbName, minThumbAriaLabel, max, maxThumbName, maxThumbAriaLabel, name, value: range, onChange, formatValue, }: RangeSliderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useId, useState } from 'react';
|
|
3
|
+
import { SliderTrack } from './slider-track.js';
|
|
4
|
+
import { SliderThumb } from './slider-thumb.js';
|
|
5
|
+
import { classNames } from '../../lib/index.js';
|
|
6
|
+
import { SliderTickMarks } from './slider-tick-marks.js';
|
|
7
|
+
const numberFormatter = new Intl.NumberFormat();
|
|
8
|
+
export function RangeSlider({ 'aria-label': ariaLabel, id, style, className, disabled, fullWidth, showLabel = true, iconLeft, iconRight, tickMarks, step = 1, min = 0, minThumbName, minThumbAriaLabel, max = 100, maxThumbName, maxThumbAriaLabel, name, value: range, onChange, formatValue = numberFormatter.format, }) {
|
|
9
|
+
const defaultId = useId();
|
|
10
|
+
const [focusedThumb, setFocusedThumb] = useState('min');
|
|
11
|
+
const positionMin = range.min / (max - min);
|
|
12
|
+
const positionMax = range.max / (max - min);
|
|
13
|
+
let dataListId;
|
|
14
|
+
let tickMarksElement;
|
|
15
|
+
if (tickMarks && tickMarks.length > 0) {
|
|
16
|
+
dataListId = `${defaultId}slider-datalist`;
|
|
17
|
+
tickMarksElement = (_jsx(SliderTickMarks, { tickMarks: tickMarks, dataListId: dataListId, min: min, max: max }));
|
|
18
|
+
}
|
|
19
|
+
const handleChangeMin = (value) => {
|
|
20
|
+
onChange({
|
|
21
|
+
...range,
|
|
22
|
+
min: Math.min(range.max, value),
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
const handleFocusMinThumb = () => {
|
|
26
|
+
setFocusedThumb('min');
|
|
27
|
+
};
|
|
28
|
+
const handleChangeMax = (value) => {
|
|
29
|
+
onChange({
|
|
30
|
+
...range,
|
|
31
|
+
max: Math.max(range.min, value),
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
const handleFocusMaxThumb = () => {
|
|
35
|
+
setFocusedThumb('max');
|
|
36
|
+
};
|
|
37
|
+
return (_jsx("fieldset", { id: id, style: style, className: classNames(className, {
|
|
38
|
+
'dc-slider': true,
|
|
39
|
+
'dc-slider_range': true,
|
|
40
|
+
'dc-slider_disabled': disabled,
|
|
41
|
+
'dc-slider_full-width': fullWidth,
|
|
42
|
+
}), name: name, disabled: disabled, "aria-label": ariaLabel, children: _jsxs("div", { className: classNames({
|
|
43
|
+
'dc-slider__body': true,
|
|
44
|
+
'dc-slider__body_has_label': showLabel,
|
|
45
|
+
'dc-slider__body_has_tick-marks': tickMarksElement,
|
|
46
|
+
}), children: [iconLeft, _jsxs(SliderTrack, { positionStart: positionMin, positionEnd: positionMax, children: [tickMarksElement, _jsx(SliderThumb, { name: minThumbName || (name && `${name}[min]`), active: focusedThumb === 'min', "aria-label": minThumbAriaLabel, showLabel: showLabel, dataListId: dataListId, position: positionMin, step: step, min: min, max: max, value: range.min, formatValue: formatValue, onChange: handleChangeMin, onFocus: handleFocusMinThumb }), _jsx(SliderThumb, { name: maxThumbName || (name && `${name}[max]`), active: focusedThumb === 'max', "aria-label": maxThumbAriaLabel, showLabel: showLabel, dataListId: dataListId, position: positionMax, step: step, min: min, max: max, value: range.max, formatValue: formatValue, onChange: handleChangeMax, onFocus: handleFocusMaxThumb })] }), iconRight] }) }));
|
|
47
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { FocusEventHandler, ReactNode } from 'react';
|
|
2
|
+
export type SliderThumbProps = {
|
|
3
|
+
'aria-label'?: string;
|
|
4
|
+
id?: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
active?: boolean;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
showLabel?: boolean;
|
|
9
|
+
dataListId?: string;
|
|
10
|
+
position: number;
|
|
11
|
+
step: number;
|
|
12
|
+
min: number;
|
|
13
|
+
max: number;
|
|
14
|
+
value: number;
|
|
15
|
+
formatValue: (value: number) => ReactNode;
|
|
16
|
+
onChange: (value: number) => void;
|
|
17
|
+
onFocus?: FocusEventHandler<HTMLInputElement>;
|
|
18
|
+
onBlur?: FocusEventHandler<HTMLInputElement>;
|
|
19
|
+
};
|
|
20
|
+
export declare function SliderThumb({ 'aria-label': ariaLabel, id, name, active, disabled, showLabel, dataListId, position, step, min, max, value, formatValue, onChange, onFocus, onBlur, }: SliderThumbProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { getOffsetRelativeToThumb } from './get-offset-relative-to-thumb.js';
|
|
3
|
+
import { classNames } from '../../lib/index.js';
|
|
4
|
+
export function SliderThumb({ 'aria-label': ariaLabel, id, name, active, disabled, showLabel, dataListId, position, step, min, max, value, formatValue, onChange, onFocus, onBlur, }) {
|
|
5
|
+
const handleChange = (event) => {
|
|
6
|
+
onChange(event.target.valueAsNumber);
|
|
7
|
+
};
|
|
8
|
+
return (_jsxs(_Fragment, { children: [_jsx("input", { id: id, className: classNames({
|
|
9
|
+
'dc-slider__input': true,
|
|
10
|
+
'dc-slider__input_active': active,
|
|
11
|
+
}), type: "range", name: name, "aria-label": ariaLabel, list: dataListId, step: step, min: min, max: max, disabled: disabled, value: value, onChange: handleChange, onFocus: onFocus, onBlur: onBlur }), showLabel && (_jsx("output", { style: { left: getOffsetRelativeToThumb(position) }, className: classNames({
|
|
12
|
+
'dc-slider__input-label': true,
|
|
13
|
+
'dc-slider__input-label_active': active,
|
|
14
|
+
}), htmlFor: id, children: formatValue(value) }))] }));
|
|
15
|
+
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
export type
|
|
2
|
+
export type SliderTickMark = {
|
|
3
|
+
value: number;
|
|
4
|
+
label?: ReactNode;
|
|
5
|
+
};
|
|
3
6
|
export type SliderTickMarksProps = {
|
|
4
|
-
|
|
5
|
-
|
|
7
|
+
dataListId: string;
|
|
8
|
+
min: number;
|
|
9
|
+
max: number;
|
|
10
|
+
tickMarks: SliderTickMark[];
|
|
6
11
|
};
|
|
7
|
-
export declare function SliderTickMarks({
|
|
12
|
+
export declare function SliderTickMarks({ dataListId, min, max, tickMarks, }: SliderTickMarksProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { getOffsetRelativeToThumb } from './get-offset-relative-to-thumb.js';
|
|
3
|
+
export function SliderTickMarks({ dataListId, min, max, tickMarks, }) {
|
|
4
|
+
const options = [];
|
|
5
|
+
const listItems = [];
|
|
6
|
+
for (let index = 0; index < tickMarks.length; index += 1) {
|
|
7
|
+
const { value, label } = tickMarks[index];
|
|
8
|
+
const key = `tick-mark-${value}:${index}`;
|
|
9
|
+
options.push(_jsx("option", { value: value, "data-testid": "slider-data-list-option", children: label }, key));
|
|
10
|
+
listItems.push(_jsx("li", { className: "dc-slider__tick-mark", "data-value": value, style: { left: getOffsetRelativeToThumb(value / (max - min)) } }, key));
|
|
5
11
|
}
|
|
6
|
-
|
|
7
|
-
for (let index = 0; index < tickMarksCount; index += 1) {
|
|
8
|
-
const label = renderTickMarkLabel?.(index);
|
|
9
|
-
tickMarks.push((_jsx("div", { className: "dc-slider-tick-mark", "data-testid": "tick-mark", children: Boolean(label) && (_jsx("span", { className: "dc-slider-tick-mark__label", children: label })) }, index)));
|
|
10
|
-
}
|
|
11
|
-
return _jsx("div", { className: "dc-slider__tick-marks", children: tickMarks });
|
|
12
|
+
return (_jsxs(_Fragment, { children: [_jsx("datalist", { id: dataListId, children: options }), _jsx("ol", { className: "dc-slider__tick-marks", children: listItems })] }));
|
|
12
13
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type SliderTickMark = {
|
|
3
|
+
value: number;
|
|
4
|
+
label?: ReactNode;
|
|
5
|
+
};
|
|
6
|
+
export type SliderTrackProps = {
|
|
7
|
+
positionStart: number;
|
|
8
|
+
positionEnd: number;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
};
|
|
11
|
+
export declare function SliderTrack({ positionStart, positionEnd, children, }: SliderTrackProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { formatPercent } from '../../lib/index.js';
|
|
3
|
+
export function SliderTrack({ positionStart, positionEnd, children, }) {
|
|
4
|
+
const start = formatPercent(positionStart);
|
|
5
|
+
const end = formatPercent(positionEnd);
|
|
6
|
+
const background = 'linear-gradient(' +
|
|
7
|
+
'to right, ' +
|
|
8
|
+
`var(--dc-slider-track-bg) ${start}, ` +
|
|
9
|
+
`var(--dc-slider-active-track-bg) ${start}, ` +
|
|
10
|
+
`var(--dc-slider-active-track-bg) ${end}, ` +
|
|
11
|
+
`var(--dc-slider-track-bg) ${end}` +
|
|
12
|
+
')';
|
|
13
|
+
return (_jsx("div", { style: { background }, className: "dc-slider__track", children: children }));
|
|
14
|
+
}
|
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
type SliderHTMLProps = ComponentPropsWithRef<'input'>;
|
|
4
|
-
type SliderBaseProps = Omit<SliderHTMLProps, 'type' | 'min' | 'max' | 'step' | 'value' | 'defaultValue'>;
|
|
5
|
-
export type SliderThumbStyle = 'round' | 'rect';
|
|
6
|
-
export type SliderChangeValueHandler = (value: number) => void;
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { SliderTickMark } from './slider-track.js';
|
|
7
3
|
export type SliderProps = {
|
|
8
|
-
|
|
4
|
+
'aria-label'?: string;
|
|
5
|
+
id?: string;
|
|
6
|
+
style?: CSSProperties;
|
|
7
|
+
className?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
fullWidth?: boolean;
|
|
10
|
+
showLabel?: boolean;
|
|
11
|
+
iconLeft?: ReactNode;
|
|
12
|
+
iconRight?: ReactNode;
|
|
13
|
+
tickMarks?: SliderTickMark[];
|
|
14
|
+
name?: string;
|
|
9
15
|
step?: number;
|
|
10
16
|
min?: number;
|
|
11
17
|
max?: number;
|
|
12
|
-
value
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
export declare
|
|
17
|
-
export {};
|
|
18
|
+
value: number;
|
|
19
|
+
onChange: (value: number) => void;
|
|
20
|
+
formatValue?: (value: number) => ReactNode;
|
|
21
|
+
};
|
|
22
|
+
export declare function Slider({ 'aria-label': ariaLabel, id, style, className, disabled, fullWidth, showLabel, iconLeft, iconRight, tickMarks, step, min, max, name, value, onChange, formatValue, }: SliderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,36 +1,27 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { useId } from 'react';
|
|
3
|
+
import { SliderTrack } from './slider-track.js';
|
|
4
|
+
import { SliderThumb } from './slider-thumb.js';
|
|
5
|
+
import { classNames } from '../../lib/index.js';
|
|
4
6
|
import { SliderTickMarks } from './slider-tick-marks.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const numberFormatter = new Intl.NumberFormat();
|
|
8
|
+
export function Slider({ 'aria-label': ariaLabel, id, style, className, disabled, fullWidth, showLabel = true, iconLeft, iconRight, tickMarks, step = 1, min = 0, max = 100, name, value, onChange, formatValue = numberFormatter.format, }) {
|
|
9
|
+
const defaultId = useId();
|
|
10
|
+
const thumbId = id || `${defaultId}slider-thumb`;
|
|
11
|
+
const position = value / (max - min);
|
|
12
|
+
let dataListId;
|
|
13
|
+
let tickMarksElement;
|
|
14
|
+
if (tickMarks && tickMarks.length > 0) {
|
|
15
|
+
dataListId = `${defaultId}slider-datalist`;
|
|
16
|
+
tickMarksElement = (_jsx(SliderTickMarks, { tickMarks: tickMarks, dataListId: dataListId, min: min, max: max }));
|
|
17
|
+
}
|
|
18
|
+
return (_jsx("div", { style: style, className: classNames(className, {
|
|
19
|
+
'dc-slider': true,
|
|
9
20
|
'dc-slider_disabled': disabled,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}, className: "dc-slider__input", type: "range", value: value, defaultValue: defaultValue, min: min, max: max, step: step, disabled: disabled, onChange: (event) => {
|
|
17
|
-
const target = event.target;
|
|
18
|
-
const value = Number(target.value);
|
|
19
|
-
onChange?.(event);
|
|
20
|
-
onChangeValue?.(value);
|
|
21
|
-
target.style.background = getTrackBackground({ min, max, value });
|
|
22
|
-
} }), _jsx(SliderTickMarks, { tickMarksCount: tickMarksCount, renderTickMarkLabel: renderTickMarkLabel })] }));
|
|
23
|
-
});
|
|
24
|
-
function getTrackBackground(params) {
|
|
25
|
-
const value = params.value || 0;
|
|
26
|
-
const min = params.min || 0;
|
|
27
|
-
const max = params.max || 0;
|
|
28
|
-
const valuePct = ((value - min) / (max - min) * 100).toFixed(2);
|
|
29
|
-
return `linear-gradient(
|
|
30
|
-
to right,
|
|
31
|
-
var(--dc-slider-track-bg-fill) 0%,
|
|
32
|
-
var(--dc-slider-track-bg-fill) ${valuePct}%,
|
|
33
|
-
var(--dc-slider-track-bg) ${valuePct}%,
|
|
34
|
-
var(--dc-slider-track-bg) ${valuePct}%
|
|
35
|
-
)`;
|
|
21
|
+
'dc-slider_full-width': fullWidth,
|
|
22
|
+
}), children: _jsxs("div", { className: classNames({
|
|
23
|
+
'dc-slider__body': true,
|
|
24
|
+
'dc-slider__body_has_label': showLabel,
|
|
25
|
+
'dc-slider__body_has_tick-marks': tickMarksElement,
|
|
26
|
+
}), children: [iconLeft, _jsxs(SliderTrack, { positionStart: 0, positionEnd: position, children: [tickMarksElement, _jsx(SliderThumb, { id: thumbId, name: name, "aria-label": ariaLabel, disabled: disabled, showLabel: showLabel, dataListId: dataListId, position: position, step: step, min: min, max: max, value: value, onChange: onChange, formatValue: formatValue })] }), iconRight] }) }));
|
|
36
27
|
}
|
|
@@ -12,4 +12,3 @@ export type ReactElementWithRef = ReactElement & {
|
|
|
12
12
|
export declare function isReactElementWithRef(element: unknown): element is ReactElementWithRef;
|
|
13
13
|
export declare function focusElement(element: EventTarget | null | undefined): void;
|
|
14
14
|
export declare function getRefElement<T extends HTMLElement>(ref: RefObject<T> | MutableRefObject<T>, message?: string): NonNullable<T>;
|
|
15
|
-
export declare function getCustomPropertyValue(element: HTMLElement, property: string): string;
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './slider-range.js';
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
export type SliderRangeTickMarkDescriptor = {
|
|
3
|
-
value: number;
|
|
4
|
-
label?: ReactNode;
|
|
5
|
-
};
|
|
6
|
-
export declare function SliderRangeDataList({ className, id, tickMarks, }: {
|
|
7
|
-
className?: string;
|
|
8
|
-
id: string;
|
|
9
|
-
tickMarks: SliderRangeTickMarkDescriptor[];
|
|
10
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { classNames } from '../../lib/index.js';
|
|
3
|
-
export function SliderRangeDataList({ className, id, tickMarks, }) {
|
|
4
|
-
const renderedOptions = [];
|
|
5
|
-
const renderedTickMarks = [];
|
|
6
|
-
for (const { value, label } of tickMarks) {
|
|
7
|
-
const key = `${value}-tick-mark`;
|
|
8
|
-
renderedOptions.push(_jsx("option", { value: value }, key));
|
|
9
|
-
renderedTickMarks.push(_jsx("li", { children: label }, key));
|
|
10
|
-
}
|
|
11
|
-
return (_jsxs(_Fragment, { children: [_jsx("datalist", { id: id, children: renderedOptions }), _jsx("ol", { className: classNames('dc-slider-range__tick-marks', className), children: renderedTickMarks })] }));
|
|
12
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
type SliderRangeLabelProps = {
|
|
3
|
-
className?: string;
|
|
4
|
-
hidden?: boolean;
|
|
5
|
-
htmlFor: string | string[];
|
|
6
|
-
children: ReactNode;
|
|
7
|
-
};
|
|
8
|
-
export declare const SliderRangeLabel: import("react").ForwardRefExoticComponent<SliderRangeLabelProps & import("react").RefAttributes<HTMLOutputElement>>;
|
|
9
|
-
export {};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef } from 'react';
|
|
3
|
-
import { classNames } from '../../lib/index.js';
|
|
4
|
-
export const SliderRangeLabel = forwardRef(({ className, hidden, htmlFor, children, }, ref) => (_jsx("output", { ref: ref, hidden: hidden, htmlFor: Array.isArray(htmlFor) ? htmlFor.join(' ') : htmlFor, className: classNames('dc-slider-range__label', className), children: _jsx("span", { className: "dc-slider-range__label-text", children: children }) })));
|
|
5
|
-
SliderRangeLabel.displayName = 'SliderRangeLabel';
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
-
import { SliderRangeTickMarkDescriptor } from './slider-range-data-list.js';
|
|
3
|
-
export type SliderRangeValue = {
|
|
4
|
-
readonly min: number;
|
|
5
|
-
readonly max: number;
|
|
6
|
-
};
|
|
7
|
-
export type SliderRangeProps = {
|
|
8
|
-
style?: CSSProperties;
|
|
9
|
-
className?: string;
|
|
10
|
-
tickMarks?: SliderRangeTickMarkDescriptor[];
|
|
11
|
-
disabled?: boolean;
|
|
12
|
-
min?: number;
|
|
13
|
-
max?: number;
|
|
14
|
-
step?: number;
|
|
15
|
-
name?: string;
|
|
16
|
-
value: SliderRangeValue;
|
|
17
|
-
onChange: (value: SliderRangeValue) => void;
|
|
18
|
-
renderValue?: (value: number) => ReactNode;
|
|
19
|
-
};
|
|
20
|
-
export declare function SliderRange({ style, className, tickMarks, disabled, min, max, step, name, value: range, onChange: onChangeRange, renderValue, }: SliderRangeProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useId, useLayoutEffect, useRef, useState, } from 'react';
|
|
3
|
-
import { classNames, formatNumber, formatPercent, getCustomPropertyValue } from '../../lib/index.js';
|
|
4
|
-
import { SliderRangeLabel } from './slider-range-label.js';
|
|
5
|
-
import { SliderRangeDataList } from './slider-range-data-list.js';
|
|
6
|
-
const inputKeys = ['min', 'max'];
|
|
7
|
-
const numberFormatter = new Intl.NumberFormat();
|
|
8
|
-
export function SliderRange({ style, className, tickMarks, disabled, min = 0, max = 100, step = 1, name, value: range, onChange: onChangeRange, renderValue = numberFormatter.format, }) {
|
|
9
|
-
const id = useId();
|
|
10
|
-
const containerRef = useRef(null);
|
|
11
|
-
const labelsContainerRef = useRef(null);
|
|
12
|
-
const minValueLabelRef = useRef(null);
|
|
13
|
-
const maxValueLabelRef = useRef(null);
|
|
14
|
-
const rangeLabelRef = useRef(null);
|
|
15
|
-
const [focusedInputKey, setFocusedInputKey] = useState('min');
|
|
16
|
-
let dataListId;
|
|
17
|
-
let dataList;
|
|
18
|
-
if (tickMarks && tickMarks.length > 0) {
|
|
19
|
-
dataListId = `${id}data-list`;
|
|
20
|
-
dataList = _jsx(SliderRangeDataList, { id: dataListId, tickMarks: tickMarks });
|
|
21
|
-
}
|
|
22
|
-
const handleFocus = (key) => () => {
|
|
23
|
-
setFocusedInputKey(key);
|
|
24
|
-
};
|
|
25
|
-
const handleChange = (key) => (event) => {
|
|
26
|
-
const value = Number(event.target.value);
|
|
27
|
-
const { min, max } = range;
|
|
28
|
-
if (key === 'min') {
|
|
29
|
-
onChangeRange({ max, min: Math.min(max, value) });
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
onChangeRange({ min, max: Math.max(min, value) });
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
const activeTrackLeft = calcTrackOffsetInPercent(range.min, {
|
|
36
|
-
min,
|
|
37
|
-
max,
|
|
38
|
-
step,
|
|
39
|
-
});
|
|
40
|
-
const activeTrackRight = calcTrackOffsetInPercent(range.max, {
|
|
41
|
-
min,
|
|
42
|
-
max,
|
|
43
|
-
step,
|
|
44
|
-
});
|
|
45
|
-
useLayoutEffect(() => {
|
|
46
|
-
const container = containerRef.current;
|
|
47
|
-
if (!container) {
|
|
48
|
-
throw new Error('container ref is not set');
|
|
49
|
-
}
|
|
50
|
-
const labelsContainer = labelsContainerRef.current;
|
|
51
|
-
if (!labelsContainer) {
|
|
52
|
-
throw new Error('labelsContainer ref is not set');
|
|
53
|
-
}
|
|
54
|
-
const minLabel = minValueLabelRef.current;
|
|
55
|
-
if (!minLabel) {
|
|
56
|
-
throw new Error('minValueLabel ref is not set');
|
|
57
|
-
}
|
|
58
|
-
const maxLabel = maxValueLabelRef.current;
|
|
59
|
-
if (!maxLabel) {
|
|
60
|
-
throw new Error('maxValueLabel ref is not set');
|
|
61
|
-
}
|
|
62
|
-
const rangeLabel = rangeLabelRef.current;
|
|
63
|
-
if (!rangeLabel) {
|
|
64
|
-
throw new Error('rangeLabel ref is not set');
|
|
65
|
-
}
|
|
66
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
67
|
-
const thumbWidth = parseFloat(getCustomPropertyValue(container, '--dc-slider-range-thumb-width'));
|
|
68
|
-
const labelsContainerWidth = getElementWidth(labelsContainer);
|
|
69
|
-
const minLabelWidth = getElementWidth(minLabel);
|
|
70
|
-
const maxLabelWidth = getElementWidth(maxLabel);
|
|
71
|
-
const rangeLabelWidth = getElementWidth(rangeLabel);
|
|
72
|
-
const minLabelOffset = calcLabelOffsetInPixels(minLabelWidth, {
|
|
73
|
-
thumbWidth,
|
|
74
|
-
containerWidth: labelsContainerWidth,
|
|
75
|
-
offsetInPercent: activeTrackLeft,
|
|
76
|
-
});
|
|
77
|
-
setElementTranslateX(minLabel, minLabelOffset);
|
|
78
|
-
const maxLabelOffset = calcLabelOffsetInPixels(maxLabelWidth, {
|
|
79
|
-
thumbWidth,
|
|
80
|
-
containerWidth: labelsContainerWidth,
|
|
81
|
-
offsetInPercent: activeTrackRight,
|
|
82
|
-
});
|
|
83
|
-
setElementTranslateX(maxLabel, maxLabelOffset);
|
|
84
|
-
let rangeLabelOffset;
|
|
85
|
-
if (focusedInputKey === 'max') {
|
|
86
|
-
rangeLabelOffset = minLabelOffset;
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
rangeLabelOffset = (maxLabelOffset + maxLabelWidth) - rangeLabelWidth;
|
|
90
|
-
}
|
|
91
|
-
setElementTranslateX(rangeLabel, rangeLabelOffset);
|
|
92
|
-
const shouldShowRangeLabel = (minLabelOffset + minLabelWidth) >= maxLabelOffset;
|
|
93
|
-
if (shouldShowRangeLabel) {
|
|
94
|
-
minLabel.hidden = true;
|
|
95
|
-
maxLabel.hidden = true;
|
|
96
|
-
rangeLabel.hidden = false;
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
minLabel.hidden = false;
|
|
100
|
-
maxLabel.hidden = false;
|
|
101
|
-
rangeLabel.hidden = true;
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
resizeObserver.observe(labelsContainer);
|
|
105
|
-
return () => resizeObserver.unobserve(labelsContainer);
|
|
106
|
-
}, [focusedInputKey, activeTrackLeft, activeTrackRight]);
|
|
107
|
-
return (_jsxs("div", { ref: containerRef, style: {
|
|
108
|
-
...style,
|
|
109
|
-
'--dc-slider-range-active-track-left': formatPercent(activeTrackLeft),
|
|
110
|
-
'--dc-slider-range-active-track-right': formatPercent(1 - activeTrackRight),
|
|
111
|
-
}, className: classNames(className, {
|
|
112
|
-
'dc-slider-range': true,
|
|
113
|
-
'dc-slider-range_disabled': disabled,
|
|
114
|
-
}), children: [_jsxs("div", { ref: labelsContainerRef, className: "dc-slider-range__labels-container", children: [_jsx(SliderRangeLabel, { ref: minValueLabelRef, htmlFor: generateInputId(id, 'min'), children: renderValue(range.min) }), _jsx(SliderRangeLabel, { ref: maxValueLabelRef, htmlFor: generateInputId(id, 'max'), children: renderValue(range.max) }), _jsx(SliderRangeLabel, { ref: rangeLabelRef, hidden: true, htmlFor: [generateInputId(id, 'min'), generateInputId(id, 'max')], children: range.min === range.max
|
|
115
|
-
? _jsx(_Fragment, { children: renderValue(range.min) })
|
|
116
|
-
: _jsxs(_Fragment, { children: [renderValue(range.min), " - ", renderValue(range.max)] }) })] }), _jsx("div", { className: "dc-slider-range__track", children: inputKeys.map((inputKey) => (_jsx("input", { id: generateInputId(id, inputKey), className: classNames({
|
|
117
|
-
'dc-slider-range__input': true,
|
|
118
|
-
'dc-slider-range__input_active': focusedInputKey === inputKey,
|
|
119
|
-
}), type: "range", min: min, max: max, step: step, list: dataListId, name: name ? `${name}[${inputKey}]` : undefined, value: range[inputKey], disabled: disabled, onChange: handleChange(inputKey), onFocus: handleFocus(inputKey) }, inputKey))) }), dataList] }));
|
|
120
|
-
}
|
|
121
|
-
function generateInputId(id, inputKey) {
|
|
122
|
-
return `${id}input-range-${inputKey}`;
|
|
123
|
-
}
|
|
124
|
-
function calcTrackOffsetInPercent(value, opts) {
|
|
125
|
-
return Math.round(value / opts.step) * opts.step / (opts.max - opts.min);
|
|
126
|
-
}
|
|
127
|
-
function calcLabelOffsetInPixels(labelWidth, opts) {
|
|
128
|
-
let offset = ((opts.offsetInPercent * opts.containerWidth) -
|
|
129
|
-
(opts.offsetInPercent * opts.thumbWidth) -
|
|
130
|
-
((labelWidth - opts.thumbWidth) / 2));
|
|
131
|
-
const min = 0;
|
|
132
|
-
const max = opts.containerWidth - labelWidth;
|
|
133
|
-
if (offset < min) {
|
|
134
|
-
offset = min;
|
|
135
|
-
}
|
|
136
|
-
if (offset > max) {
|
|
137
|
-
offset = max;
|
|
138
|
-
}
|
|
139
|
-
return offset;
|
|
140
|
-
}
|
|
141
|
-
function getElementWidth(element) {
|
|
142
|
-
const rect = element.getBoundingClientRect();
|
|
143
|
-
return rect.width;
|
|
144
|
-
}
|
|
145
|
-
function setElementTranslateX(element, offsetX) {
|
|
146
|
-
element.style.transform = `translateX(${formatNumber(offsetX)}px)`;
|
|
147
|
-
}
|