draft-components 2.9.2 → 2.10.1

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.
Files changed (29) hide show
  1. package/css/draft-components.css +163 -310
  2. package/css/draft-components.dark.css +12 -1
  3. package/dist/components/index.d.ts +0 -1
  4. package/dist/components/index.js +0 -1
  5. package/dist/components/slider/get-offset-relative-to-thumb.d.ts +1 -0
  6. package/dist/components/slider/get-offset-relative-to-thumb.js +8 -0
  7. package/dist/components/slider/index.d.ts +2 -1
  8. package/dist/components/slider/index.js +1 -1
  9. package/dist/components/slider/range-slider.d.ts +30 -0
  10. package/dist/components/slider/range-slider.js +47 -0
  11. package/dist/components/slider/slider-thumb.d.ts +20 -0
  12. package/dist/components/slider/slider-thumb.js +15 -0
  13. package/dist/components/slider/slider-tick-marks.d.ts +9 -4
  14. package/dist/components/slider/slider-tick-marks.js +11 -10
  15. package/dist/components/slider/slider-track.d.ts +11 -0
  16. package/dist/components/slider/slider-track.js +13 -0
  17. package/dist/components/slider/slider.d.ts +18 -13
  18. package/dist/components/slider/slider.js +23 -32
  19. package/dist/lib/react-helpers.d.ts +0 -1
  20. package/dist/lib/react-helpers.js +0 -3
  21. package/package.json +1 -1
  22. package/dist/components/slider-range/index.d.ts +0 -2
  23. package/dist/components/slider-range/index.js +0 -1
  24. package/dist/components/slider-range/slider-range-data-list.d.ts +0 -10
  25. package/dist/components/slider-range/slider-range-data-list.js +0 -12
  26. package/dist/components/slider-range/slider-range-label.d.ts +0 -9
  27. package/dist/components/slider-range/slider-range-label.js +0 -5
  28. package/dist/components/slider-range/slider-range.d.ts +0 -20
  29. package/dist/components/slider-range/slider-range.js +0 -147
@@ -1969,396 +1969,249 @@
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-fill: var(--dc-control-primary-color);
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-bg: var(--dc-control-on-primary-color);
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
- 0 0 0 1px rgb(var(--dc-black-rgb) / 0.1),
1985
- 0 2px 3px rgb(var(--dc-black-rgb) / 0.2);
1986
- --dc-slider-thumb-shadow-focus:
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 3px var(--dc-slider-focus-ring-color);
1993
+ 0 0 0 4px var(--dc-focus-ring-color);
1994
+
1995
+ /* Label properties */
1996
+ --dc-slider-label-gap: 4px;
1997
+ --dc-slider-label-height: 24px;
1998
+ --dc-slider-label-max-width: 80px;
1999
+ --dc-slider-label-padding-x: 0.5em;
2000
+ --dc-slider-label-radius: 6px;
2001
+ --dc-slider-label-border: 1px solid var(--dc-white);
2002
+ --dc-slider-label-text-color: var(--dc-gray-50);
2003
+ --dc-slider-label-bg: var(--dc-gray-800);
2004
+
2005
+ /* Tick mark properties */
2006
+ --dc-slider-tick-mark-width: 1px;
2007
+ --dc-slider-tick-mark-height: 6px;
2008
+ --dc-slider-tick-mark-color: rgb(var(--dc-gray-900-rgb) / 0.3);
2009
+ --dc-slider-tick-marks-gap: 4px;
1989
2010
 
1990
2011
  color-scheme: light;
1991
- font-family: var(--dc-primary-font);
1992
- display: flex;
1993
- flex-direction: column;
1994
- width: 100%;
2012
+ display: inline-flex;
2013
+ width: 240px;
2014
+ min-width: 0;
2015
+ max-width: 100%;
2016
+ }
2017
+
2018
+ .dc-slider_range {
2019
+ margin: 0;
2020
+ padding: 0;
2021
+ border: none;
1995
2022
  }
1996
2023
 
1997
2024
  .dc-slider_disabled {
1998
2025
  opacity: var(--dc-disabled-state-opacity);
1999
2026
  }
2000
2027
 
2001
- .dc-slider_thumb_rect {
2002
- --dc-slider-thumb-width: 10px;
2028
+ .dc-slider_full-width {
2029
+ display: flex;
2030
+ width: 100%;
2031
+ }
2032
+
2033
+ .dc-slider__body {
2034
+ color: var(--dc-slider-icon-color);
2035
+ display: flex;
2036
+ gap: 8px;
2037
+ align-items: center;
2038
+ width: 100%;
2039
+ min-height: var(--dc-slider-thumb-height);
2040
+ }
2041
+
2042
+ .dc-slider__body_has_labels {
2043
+ margin-top: calc(
2044
+ var(--dc-slider-label-height) +
2045
+ var(--dc-slider-label-gap)
2046
+ );
2047
+ }
2048
+
2049
+ .dc-slider__body_has_tick-marks {
2050
+ margin-bottom: calc(
2051
+ var(--dc-slider-tick-mark-height) -
2052
+ var(--dc-slider-thumb-height) / 2 +
2053
+ var(--dc-slider-track-height) / 2 +
2054
+ var(--dc-slider-tick-marks-gap)
2055
+ );
2056
+ }
2057
+
2058
+ .dc-slider__track {
2059
+ position: relative;
2060
+ width: 100%;
2061
+ height: var(--dc-slider-track-height);
2062
+ border-radius: var(--dc-slider-track-radius);
2063
+ background-color: var(--dc-slider-track-bg);
2003
2064
  }
2004
2065
 
2005
2066
  .dc-slider__input {
2006
2067
  -webkit-appearance: none;
2007
2068
  -moz-appearance: none;
2008
2069
  appearance: none;
2009
- height: var(--dc-slider-track-height);
2010
- margin: calc((var(--dc-slider-thumb-height) - var(--dc-slider-track-height)) / 2) 0;
2070
+ position: absolute;
2071
+ top: 0;
2072
+ left: 0;
2073
+ width: 100%;
2074
+ height: 100%;
2075
+ margin: 0;
2011
2076
  padding: 0;
2012
- border-radius: 2px;
2013
- background: var(--dc-slider-track-bg);
2077
+ border: none;
2078
+ background: none;
2014
2079
  }
2015
2080
 
2016
2081
  .dc-slider__input:focus {
2017
2082
  outline: none;
2018
2083
  }
2019
2084
 
2020
- .dc-slider__input::-webkit-slider-thumb {
2085
+ .dc-slider_range .dc-slider__input {
2086
+ pointer-events: none;
2087
+ }
2088
+
2089
+ .dc-slider__input::-moz-range-track {
2090
+ -moz-appearance: none;
2091
+ appearance: none;
2092
+ background: none;
2093
+ }
2094
+
2095
+ .dc-slider__input::-webkit-slider-runnable-track {
2021
2096
  -webkit-appearance: none;
2022
2097
  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
- border: none;
2028
- border-radius: 50%;
2029
- background: var(--dc-slider-thumb-bg);
2030
- box-shadow: var(--dc-slider-thumb-shadow);
2098
+ background: none;
2031
2099
  }
2032
2100
 
2033
2101
  .dc-slider__input::-moz-range-thumb {
2034
2102
  -moz-appearance: none;
2035
2103
  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;
2104
+ display: inline-flex;
2049
2105
  box-sizing: border-box;
2050
2106
  width: var(--dc-slider-thumb-width);
2051
2107
  height: var(--dc-slider-thumb-height);
2052
- border: none;
2053
- border-radius: 50%;
2108
+ -moz-transition: var(--dc-slider-thumb-transition);
2109
+ transition: var(--dc-slider-thumb-transition);
2110
+ border: var(--dc-slider-thumb-border);
2111
+ border-radius: var(--dc-slider-thumb-radius);
2054
2112
  background: var(--dc-slider-thumb-bg);
2055
2113
  box-shadow: var(--dc-slider-thumb-shadow);
2056
2114
  }
2057
2115
 
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);
2116
+ .dc-slider_range .dc-slider__input::-moz-range-thumb {
2117
+ pointer-events: all;
2072
2118
  }
2073
2119
 
2074
2120
  .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);
2121
+ box-shadow: var(--dc-slider-thumb-focus-ring);
2084
2122
  }
2085
2123
 
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);
2092
- }
2093
-
2094
- .dc-slider__tick-marks {
2095
- 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;
2124
+ .dc-slider__input:focus:not(:focus-visible)::-moz-range-thumb {
2125
+ box-shadow: var(--dc-slider-thumb-shadow);
2111
2126
  }
2112
2127
 
2113
- .dc-slider-tick-mark::before {
2114
- content: "";
2128
+ .dc-slider__input::-webkit-slider-thumb {
2129
+ -webkit-appearance: none;
2130
+ appearance: none;
2115
2131
  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;
2132
+ box-sizing: border-box;
2133
+ width: var(--dc-slider-thumb-width);
2134
+ height: var(--dc-slider-thumb-height);
2135
+ -webkit-transition: var(--dc-slider-thumb-transition);
2136
+ transition: var(--dc-slider-thumb-transition);
2137
+ border: var(--dc-slider-thumb-border);
2138
+ border-radius: var(--dc-slider-thumb-radius);
2139
+ background: var(--dc-slider-thumb-bg);
2140
+ box-shadow: var(--dc-slider-thumb-shadow);
2124
2141
  }
2125
2142
 
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;
2143
+ .dc-slider_range .dc-slider__input::-webkit-slider-thumb {
2144
+ pointer-events: all;
2170
2145
  }
2171
2146
 
2172
- .dc-slider-range__labels-container {
2173
- position: relative;
2174
- width: 100%;
2175
- height: var(--dc-slider-range-thumb-height);
2176
- margin-bottom: var(--dc-slider-range-labels-margin-bottom);
2177
- border: none;
2147
+ .dc-slider__input:focus::-webkit-slider-thumb {
2148
+ box-shadow: var(--dc-slider-thumb-focus-ring);
2178
2149
  }
2179
2150
 
2180
- .dc-slider-range__label,
2181
- .dc-slider-range__label[hidden] {
2182
- display: inline-flex;
2151
+ .dc-slider__input:focus:not(:focus-visible)::-webkit-slider-thumb {
2152
+ box-shadow: var(--dc-slider-thumb-shadow);
2183
2153
  }
2184
2154
 
2185
- .dc-slider-range__label {
2155
+ .dc-slider__label {
2186
2156
  font: var(--dc-text-xs);
2187
- color: var(--dc-slider-range-label-text-color);
2157
+ font-variant-numeric: tabular-nums;
2158
+ color: var(--dc-slider-label-text-color);
2188
2159
  position: absolute;
2189
- top: 0;
2160
+ bottom: calc(
2161
+ var(--dc-slider-thumb-height) / 2 -
2162
+ var(--dc-slider-track-height) / 2 +
2163
+ var(--dc-slider-label-gap) +
2164
+ var(--dc-slider-track-height)
2165
+ );
2190
2166
  left: 0;
2167
+ display: inline-flex;
2191
2168
  align-items: center;
2169
+ justify-content: center;
2192
2170
  box-sizing: border-box;
2193
- height: var(--dc-slider-range-label-height);
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;
2171
+ height: var(--dc-slider-label-height);
2172
+ min-width: var(--dc-slider-label-height);
2173
+ max-width: var(--dc-slider-label-max-width);
2174
+ padding: 0 var(--dc-slider-label-padding-x);
2175
+ transform: translateX(-50%);
2176
+ border: var(--dc-slider-label-border);
2177
+ border-radius: var(--dc-slider-label-radius);
2178
+ background: var(--dc-slider-label-bg);
2200
2179
  }
2201
2180
 
2202
- .dc-slider-range__label[hidden] {
2203
- opacity: 0;
2204
- pointer-events: none;
2205
- }
2206
-
2207
- .dc-slider-range__label-text {
2181
+ .dc-slider__label-text {
2208
2182
  overflow: hidden;
2209
2183
  white-space: nowrap;
2210
2184
  text-overflow: ellipsis;
2211
2185
  }
2212
2186
 
2213
- .dc-slider-range__track {
2214
- 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
- width: 100%;
2235
- background: var(--dc-slider-range-track-bg);
2236
- box-shadow: inset 0 0 0 1px var(--dc-slider-range-track-border-color);
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);
2247
- }
2248
-
2249
- .dc-slider-range__input {
2250
- -webkit-appearance: none;
2251
- -moz-appearance: none;
2252
- appearance: none;
2253
- position: absolute;
2187
+ .dc-slider__input_active,
2188
+ .dc-slider__label_active {
2254
2189
  z-index: 1;
2255
- top: 0;
2256
- left: 0;
2257
- cursor: default;
2258
- width: 100%;
2259
- height: 100%;
2260
- margin: 0;
2261
- padding: 0;
2262
- pointer-events: none;
2263
- background: none;
2264
- }
2265
-
2266
- .dc-slider-range__input_active {
2267
- z-index: 2;
2268
- }
2269
-
2270
- .dc-slider-range__input:focus {
2271
- outline: none;
2272
2190
  }
2273
2191
 
2274
- .dc-slider-range__input::-webkit-slider-runnable-track {
2275
- -webkit-appearance: none;
2276
- appearance: none;
2277
- width: 100%;
2278
- height: 100%;
2279
- background: none;
2280
- }
2281
-
2282
- .dc-slider-range__input::-moz-range-track {
2283
- -moz-appearance: none;
2284
- appearance: none;
2192
+ .dc-slider__tick-marks {
2193
+ position: relative;
2194
+ top: calc(
2195
+ var(--dc-slider-track-height) +
2196
+ var(--dc-slider-tick-marks-gap)
2197
+ );
2198
+ left: 0;
2285
2199
  width: 100%;
2286
- height: 100%;
2287
- background: none;
2288
- }
2289
-
2290
- .dc-slider-range__input::-webkit-slider-thumb {
2291
- -webkit-appearance: none;
2292
- appearance: none;
2293
- display: inline-block;
2294
- box-sizing: border-box;
2295
- width: var(--dc-slider-range-thumb-width);
2296
- height: var(--dc-slider-range-thumb-height);
2200
+ height: var(--dc-slider-tick-mark-height);
2297
2201
  margin: 0;
2298
2202
  padding: 0;
2299
- 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
- }
2305
-
2306
- .dc-slider-range__input:focus::-webkit-slider-thumb {
2307
- box-shadow: var(--dc-slider-focus-ring);
2308
- }
2309
-
2310
- .dc-slider-range input::-moz-range-thumb {
2311
- -moz-appearance: none;
2312
- appearance: none;
2313
- display: inline-block;
2314
- box-sizing: border-box;
2315
- width: var(--dc-slider-range-thumb-width);
2316
- height: var(--dc-slider-range-thumb-height);
2317
- margin: 0;
2318
- padding: 0;
2319
- pointer-events: all;
2320
- border: var(--dc-slider-range-thumb-border);
2321
- border-radius: var(--dc-slider-range-thumb-radius);
2322
- background: var(--dc-slider-range-thumb-bg);
2323
- box-shadow: var(--dc-slider-range-thumb-shadow);
2324
- }
2325
-
2326
- .dc-slider-range__input:focus::-moz-range-thumb {
2327
- box-shadow: var(--dc-slider-focus-ring);
2328
- }
2329
-
2330
- .dc-slider-range__tick-marks {
2331
- display: flex;
2332
- justify-content: space-between;
2333
- width: 100%;
2334
- margin: var(--dc-slider-range-tick-marks-margin-top) 0 0;
2335
- padding: 0;
2336
2203
  list-style: none;
2337
2204
  }
2338
2205
 
2339
- .dc-slider-range__tick-marks > li {
2340
- font: var(--dc-slider-range-tick-mark-font);
2341
- color: var(--dc-slider-range-tick-mark-label-color);
2342
- display: inline-flex;
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: "";
2206
+ .dc-slider__tick-marks > li {
2207
+ position: absolute;
2208
+ top: 0;
2209
+ left: 0;
2357
2210
  display: inline-flex;
2358
- flex-shrink: 0;
2359
- width: var(--dc-slider-range-tick-mark-width);
2360
- height: var(--dc-slider-range-tick-mark-height);
2361
- background: var(--dc-slider-range-tick-mark-color);
2211
+ width: var(--dc-slider-tick-mark-width);
2212
+ height: var(--dc-slider-tick-mark-height);
2213
+ transform: translateX(-50%);
2214
+ background: var(--dc-slider-tick-mark-color);
2362
2215
  }
2363
2216
 
2364
2217
  .dc-file-picker {
@@ -401,7 +401,18 @@
401
401
 
402
402
  .dark .dc-slider,
403
403
  .dark.dc-slider {
404
- color-scheme: dark;
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';
@@ -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 } from '../../lib/index.js';
2
+ export function getOffsetRelativeToThumb(position) {
3
+ return 'calc(' +
4
+ `${Math.floor(position * 100)}% - ` +
5
+ `var(--dc-slider-thumb-width) * ${formatNumber(position / 2)} + ` +
6
+ `var(--dc-slider-thumb-width) * ${formatNumber((1 - position) / 2)}` +
7
+ ')';
8
+ }
@@ -1,2 +1,3 @@
1
+ export { type SliderTickMark } from './slider-tick-marks.js';
1
2
  export * from './slider.js';
2
- export { SliderTickMarks } from './slider-tick-marks.js';
3
+ export * from './range-slider.js';
@@ -1,2 +1,2 @@
1
1
  export * from './slider.js';
2
- export { SliderTickMarks } from './slider-tick-marks.js';
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
+ showLabels?: 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, showLabels, 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, showLabels, 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_labels': showLabels,
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: showLabels, 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: showLabels, 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__label': true,
13
+ 'dc-slider__label_active': active,
14
+ }), htmlFor: id, children: _jsx("span", { className: "dc-slider__label-text", children: formatValue(value) }) }))] }));
15
+ }
@@ -1,7 +1,12 @@
1
1
  import { ReactNode } from 'react';
2
- export type RenderTickMarkLabel = (index: number) => ReactNode;
2
+ export type SliderTickMark = {
3
+ value: number;
4
+ label?: ReactNode;
5
+ };
3
6
  export type SliderTickMarksProps = {
4
- tickMarksCount: number;
5
- renderTickMarkLabel?: RenderTickMarkLabel;
7
+ dataListId: string;
8
+ min: number;
9
+ max: number;
10
+ tickMarks: SliderTickMark[];
6
11
  };
7
- export declare function SliderTickMarks({ tickMarksCount, renderTickMarkLabel, }: SliderTickMarksProps): import("react/jsx-runtime").JSX.Element | null;
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
- export function SliderTickMarks({ tickMarksCount, renderTickMarkLabel, }) {
3
- if (tickMarksCount < 1) {
4
- return null;
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
- const tickMarks = [];
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,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export function SliderTrack({ positionStart, positionEnd, children, }) {
3
+ const start = `${Math.floor(positionStart * 100)}%`;
4
+ const end = `${Math.floor(positionEnd * 100)}%`;
5
+ const background = 'linear-gradient(' +
6
+ 'to right, ' +
7
+ `var(--dc-slider-track-bg) ${start}, ` +
8
+ `var(--dc-slider-active-track-bg) ${start}, ` +
9
+ `var(--dc-slider-active-track-bg) ${end}, ` +
10
+ `var(--dc-slider-track-bg) ${end}` +
11
+ ')';
12
+ return (_jsx("div", { style: { background }, className: "dc-slider__track", children: children }));
13
+ }
@@ -1,17 +1,22 @@
1
- import { ComponentPropsWithRef } from 'react';
2
- import { SliderTickMarksProps } from './slider-tick-marks.js';
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
- thumbStyle?: SliderThumbStyle;
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?: number;
13
- defaultValue?: number;
14
- onChangeValue?: SliderChangeValueHandler;
15
- } & SliderBaseProps & Partial<SliderTickMarksProps>;
16
- export declare const Slider: import("react").ForwardRefExoticComponent<Omit<SliderProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
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 { forwardRef } from 'react';
3
- import { classNames } from '../../lib/react-helpers.js';
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
- export const Slider = forwardRef(function Slider({ thumbStyle = 'round', tickMarksCount = 0, renderTickMarkLabel, step = 1, min = 0, max = 100, style, className, disabled, value, defaultValue, onChange, onChangeValue, ...props }, ref) {
6
- defaultValue = value == null ? defaultValue || 0 : undefined;
7
- return (_jsxs("div", { style: style, className: classNames(className, 'dc-slider', {
8
- [`dc-slider_thumb_${thumbStyle}`]: thumbStyle !== undefined,
7
+ const numberFormatter = new Intl.NumberFormat();
8
+ export function Slider({ 'aria-label': ariaLabel, id, style, className, disabled, fullWidth, showLabel, 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
- }), children: [_jsx("input", { ...props, ref: ref, style: {
11
- background: getTrackBackground({
12
- min,
13
- max,
14
- value: value ?? defaultValue,
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_labels': 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;
@@ -47,6 +47,3 @@ export function getRefElement(ref, message = 'getElementFromRef: ref value is nu
47
47
  }
48
48
  return value;
49
49
  }
50
- export function getCustomPropertyValue(element, property) {
51
- return window.getComputedStyle(element).getPropertyValue(property) || '';
52
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "draft-components",
3
- "version": "2.9.2",
3
+ "version": "2.10.1",
4
4
  "description": "The React based UI components library.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,2 +0,0 @@
1
- export * from './slider-range.js';
2
- export { type SliderRangeTickMarkDescriptor } from './slider-range-data-list.js';
@@ -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
- }