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.
Files changed (29) hide show
  1. package/css/draft-components.css +156 -311
  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 +14 -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,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-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);
1989
1994
 
1990
- color-scheme: light;
1991
- font-family: var(--dc-primary-font);
1992
- display: flex;
1993
- flex-direction: column;
1994
- width: 100%;
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
- .dc-slider_disabled {
1998
- opacity: var(--dc-disabled-state-opacity);
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
- .dc-slider_thumb_rect {
2002
- --dc-slider-thumb-width: 10px;
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-slider__input {
2006
- -webkit-appearance: none;
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-slider__input::-moz-range-thumb {
2034
- -moz-appearance: none;
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-slider__tick-marks {
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-slider-range__label {
2186
- font: var(--dc-text-xs);
2187
- color: var(--dc-slider-range-label-text-color);
2188
- position: absolute;
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
- 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;
2037
+ width: 100%;
2038
+ min-height: var(--dc-slider-thumb-height);
2200
2039
  }
2201
2040
 
2202
- .dc-slider-range__label[hidden] {
2203
- opacity: 0;
2204
- pointer-events: none;
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-slider-range__label-text {
2208
- overflow: hidden;
2209
- white-space: nowrap;
2210
- text-overflow: ellipsis;
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-slider-range__track {
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
- 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);
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-slider-range__input {
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
- pointer-events: none;
2076
+ border: none;
2263
2077
  background: none;
2264
2078
  }
2265
2079
 
2266
- .dc-slider-range__input_active {
2267
- z-index: 2;
2080
+ .dc-slider__input:focus {
2081
+ outline: none;
2268
2082
  }
2269
2083
 
2270
- .dc-slider-range__input:focus {
2271
- outline: none;
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-slider-range__input::-webkit-slider-runnable-track {
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-slider-range__input::-moz-range-track {
2100
+ .dc-slider__input::-moz-range-thumb {
2283
2101
  -moz-appearance: none;
2284
2102
  appearance: none;
2285
- width: 100%;
2286
- height: 100%;
2287
- background: none;
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-slider-range__input::-webkit-slider-thumb {
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-range-thumb-width);
2296
- height: var(--dc-slider-range-thumb-height);
2297
- margin: 0;
2298
- padding: 0;
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-slider-range__input:focus::-webkit-slider-thumb {
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-slider-range input::-moz-range-thumb {
2311
- -moz-appearance: none;
2312
- appearance: none;
2313
- display: inline-block;
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
- 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);
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-slider-range__input:focus::-moz-range-thumb {
2327
- box-shadow: var(--dc-slider-focus-ring);
2179
+ .dc-slider__input_active,
2180
+ .dc-slider__input-label_active {
2181
+ z-index: 1;
2328
2182
  }
2329
2183
 
2330
- .dc-slider-range__tick-marks {
2331
- display: flex;
2332
- justify-content: space-between;
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
- margin: var(--dc-slider-range-tick-marks-margin-top) 0 0;
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-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: "";
2198
+ .dc-slider__tick-marks > li {
2199
+ position: absolute;
2200
+ top: 0;
2201
+ left: 0;
2357
2202
  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);
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
- 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, 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,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
+ 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 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,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 { 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 = 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
- }), 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_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;
@@ -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.0",
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
- }