draft-components 2.9.1 → 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 -307
  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,392 +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
- border: none;
2028
- border-radius: 50%;
2029
- background: var(--dc-slider-thumb-bg);
2030
- box-shadow: var(--dc-slider-thumb-shadow);
2031
- }
2032
-
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
2020
  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
2021
  }
2061
2022
 
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
2030
  }
2179
2031
 
2180
- .dc-slider-range__label {
2181
- font: var(--dc-text-xs);
2182
- color: var(--dc-slider-range-label-text-color);
2183
- position: absolute;
2184
- top: 0;
2185
- left: 0;
2186
- display: inline-flex;
2032
+ .dc-slider__body {
2033
+ color: var(--dc-slider-icon-color);
2034
+ display: flex;
2035
+ gap: 8px;
2187
2036
  align-items: center;
2188
- box-sizing: border-box;
2189
- height: var(--dc-slider-range-label-height);
2190
- max-width: 100%;
2191
- padding: 0 var(--dc-slider-range-label-padding-x);
2192
- text-align: center;
2193
- border-radius: var(--dc-slider-range-label-radius);
2194
- background: var(--dc-slider-range-label-bg);
2195
- font-variant-numeric: tabular-nums;
2037
+ width: 100%;
2038
+ min-height: var(--dc-slider-thumb-height);
2196
2039
  }
2197
2040
 
2198
- .dc-slider-range__label[hidden] {
2199
- opacity: 0;
2200
- 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
+ );
2201
2046
  }
2202
2047
 
2203
- .dc-slider-range__label-text {
2204
- overflow: hidden;
2205
- white-space: nowrap;
2206
- 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
+ );
2207
2055
  }
2208
2056
 
2209
- .dc-slider-range__track {
2057
+ .dc-slider__track {
2210
2058
  position: relative;
2211
- display: block;
2212
- width: var(--dc-slider-range-track-width);
2213
- height: max(var(--dc-slider-range-track-height), var(--dc-slider-range-thumb-height));
2214
- }
2215
-
2216
- .dc-slider-range__track::before,
2217
- .dc-slider-range__track::after {
2218
- content: "";
2219
- position: absolute;
2220
- z-index: 0;
2221
- top: 50%;
2222
- display: block;
2223
- box-sizing: border-box;
2224
- height: var(--dc-slider-range-track-height);
2225
- transform: translateY(-50%);
2226
- border-radius: var(--dc-slider-range-track-radius);
2227
- }
2228
-
2229
- .dc-slider-range__track::before {
2230
2059
  width: 100%;
2231
- background: var(--dc-slider-range-track-bg);
2232
- box-shadow: inset 0 0 0 1px var(--dc-slider-range-track-border-color);
2233
- }
2234
-
2235
- .dc-slider-range__track::after {
2236
- right: var(--dc-slider-range-active-track-right);
2237
- left: var(--dc-slider-range-active-track-left);
2238
- background: var(--dc-slider-range-active-track-bg);
2239
- }
2240
-
2241
- .dc-slider-range_disabled .dc-slider-range__track {
2242
- 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);
2243
2063
  }
2244
2064
 
2245
- .dc-slider-range__input {
2065
+ .dc-slider__input {
2246
2066
  -webkit-appearance: none;
2247
2067
  -moz-appearance: none;
2248
2068
  appearance: none;
2249
2069
  position: absolute;
2250
- z-index: 1;
2251
2070
  top: 0;
2252
2071
  left: 0;
2253
- cursor: default;
2254
2072
  width: 100%;
2255
2073
  height: 100%;
2256
2074
  margin: 0;
2257
2075
  padding: 0;
2258
- pointer-events: none;
2076
+ border: none;
2259
2077
  background: none;
2260
2078
  }
2261
2079
 
2262
- .dc-slider-range__input_active {
2263
- z-index: 2;
2080
+ .dc-slider__input:focus {
2081
+ outline: none;
2264
2082
  }
2265
2083
 
2266
- .dc-slider-range__input:focus {
2267
- 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;
2268
2092
  }
2269
2093
 
2270
- .dc-slider-range__input::-webkit-slider-runnable-track {
2094
+ .dc-slider__input::-webkit-slider-runnable-track {
2271
2095
  -webkit-appearance: none;
2272
2096
  appearance: none;
2273
- width: 100%;
2274
- height: 100%;
2275
2097
  background: none;
2276
2098
  }
2277
2099
 
2278
- .dc-slider-range__input::-moz-range-track {
2100
+ .dc-slider__input::-moz-range-thumb {
2279
2101
  -moz-appearance: none;
2280
2102
  appearance: none;
2281
- width: 100%;
2282
- height: 100%;
2283
- 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;
2284
2117
  }
2285
2118
 
2286
- .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 {
2287
2128
  -webkit-appearance: none;
2288
2129
  appearance: none;
2289
2130
  display: inline-block;
2290
2131
  box-sizing: border-box;
2291
- width: var(--dc-slider-range-thumb-width);
2292
- height: var(--dc-slider-range-thumb-height);
2293
- margin: 0;
2294
- 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 {
2295
2143
  pointer-events: all;
2296
- border: var(--dc-slider-range-thumb-border);
2297
- border-radius: var(--dc-slider-range-thumb-radius);
2298
- background: var(--dc-slider-range-thumb-bg);
2299
- box-shadow: var(--dc-slider-range-thumb-shadow);
2300
2144
  }
2301
2145
 
2302
- .dc-slider-range__input:focus::-webkit-slider-thumb {
2303
- box-shadow: var(--dc-slider-focus-ring);
2146
+ .dc-slider__input:focus::-webkit-slider-thumb {
2147
+ box-shadow: var(--dc-slider-thumb-focus-ring);
2304
2148
  }
2305
2149
 
2306
- .dc-slider-range input::-moz-range-thumb {
2307
- -moz-appearance: none;
2308
- appearance: none;
2309
- 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;
2310
2169
  box-sizing: border-box;
2311
- width: var(--dc-slider-range-thumb-width);
2312
- height: var(--dc-slider-range-thumb-height);
2313
- margin: 0;
2314
- padding: 0;
2315
- pointer-events: all;
2316
- border: var(--dc-slider-range-thumb-border);
2317
- border-radius: var(--dc-slider-range-thumb-radius);
2318
- background: var(--dc-slider-range-thumb-bg);
2319
- 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);
2320
2177
  }
2321
2178
 
2322
- .dc-slider-range__input:focus::-moz-range-thumb {
2323
- box-shadow: var(--dc-slider-focus-ring);
2179
+ .dc-slider__input_active,
2180
+ .dc-slider__input-label_active {
2181
+ z-index: 1;
2324
2182
  }
2325
2183
 
2326
- .dc-slider-range__tick-marks {
2327
- display: flex;
2328
- 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;
2329
2191
  width: 100%;
2330
- margin: var(--dc-slider-range-tick-marks-margin-top) 0 0;
2192
+ height: var(--dc-slider-tick-mark-height);
2193
+ margin: 0;
2331
2194
  padding: 0;
2332
2195
  list-style: none;
2333
2196
  }
2334
2197
 
2335
- .dc-slider-range__tick-marks > li {
2336
- font: var(--dc-slider-range-tick-mark-font);
2337
- color: var(--dc-slider-range-tick-mark-label-color);
2338
- display: inline-flex;
2339
- cursor: default;
2340
- -webkit-user-select: none;
2341
- -moz-user-select: none;
2342
- user-select: none;
2343
- flex-direction: column;
2344
- gap: var(--dc-slider-range-tick-mark-gap);
2345
- align-items: center;
2346
- width: var(--dc-slider-range-thumb-width);
2347
- min-width: var(--dc-slider-range-thumb-width);
2348
- white-space: nowrap;
2349
- }
2350
-
2351
- .dc-slider-range__tick-marks > li::before {
2352
- content: "";
2198
+ .dc-slider__tick-marks > li {
2199
+ position: absolute;
2200
+ top: 0;
2201
+ left: 0;
2353
2202
  display: inline-flex;
2354
- flex-shrink: 0;
2355
- width: var(--dc-slider-range-tick-mark-width);
2356
- height: var(--dc-slider-range-tick-mark-height);
2357
- 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);
2358
2207
  }
2359
2208
 
2360
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.1",
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
- }