@instructure/ui-range-input 8.22.1-snapshot.4 → 8.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [8.23.0](https://github.com/instructure/instructure-ui/compare/v8.22.0...v8.23.0) (2022-04-07)
7
+
8
+ ### Features
9
+
10
+ - **shared-types,ui-range-input:** add accessible variant for RangeInput handle ([e71453c](https://github.com/instructure/instructure-ui/commit/e71453cd9e012b022e35f607c506174be157d8ec))
11
+
6
12
  # [8.22.0](https://github.com/instructure/instructure-ui/compare/v8.21.0...v8.22.0) (2022-03-31)
7
13
 
8
14
  **Note:** Version bump only for package @instructure/ui-range-input
@@ -204,7 +204,8 @@ let RangeInput = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
204
204
  layout: 'stacked',
205
205
  displayValue: true,
206
206
  disabled: false,
207
- readOnly: false
207
+ readOnly: false,
208
+ thumbVariant: 'deprecated'
208
209
  }, _temp)) || _class) || _class) || _class);
209
210
  export default RangeInput;
210
211
  export { RangeInput };
@@ -23,6 +23,7 @@
23
23
  */
24
24
  import PropTypes from 'prop-types';
25
25
  import { controllable } from '@instructure/ui-prop-types';
26
+ import { deprecated } from '@instructure/ui-react-utils';
26
27
  import { FormPropTypes } from '@instructure/ui-form-field';
27
28
  const propTypes = {
28
29
  min: PropTypes.number.isRequired,
@@ -40,7 +41,8 @@ const propTypes = {
40
41
  formatValue: PropTypes.func,
41
42
  inline: PropTypes.bool,
42
43
  disabled: PropTypes.bool,
43
- readOnly: PropTypes.bool
44
+ readOnly: PropTypes.bool,
45
+ thumbVariant: deprecated.deprecatePropValues(PropTypes.oneOf(['deprecated', 'accessible']), ['deprecated'], 'The `deprecated` variant is not fully accessible and will be removed in V9. The connected theme variables will be removed as well: `handleShadowColor`, `handleFocusOutlineColor`, `handleFocusOutlineWidth`. Please use the `accessible` variant.')
44
46
  };
45
- const allowedProps = ['min', 'max', 'defaultValue', 'value', 'onChange', 'messages', 'size', 'layout', 'id', 'label', 'displayValue', 'step', 'formatValue', 'inline', 'disabled', 'readOnly'];
47
+ const allowedProps = ['min', 'max', 'defaultValue', 'value', 'onChange', 'messages', 'size', 'layout', 'id', 'label', 'displayValue', 'step', 'formatValue', 'inline', 'disabled', 'readOnly', 'thumbVariant'];
46
48
  export { propTypes, allowedProps };
@@ -33,7 +33,8 @@
33
33
  * @return {Object} The final style object, which will be used in the component
34
34
  */
35
35
  const generateStyle = (componentTheme, props) => {
36
- const size = props.size;
36
+ const size = props.size,
37
+ thumbVariant = props.thumbVariant;
37
38
  const valueSizeVariants = {
38
39
  small: {
39
40
  fontSize: componentTheme.valueSmallFontSize,
@@ -59,21 +60,51 @@ const generateStyle = (componentTheme, props) => {
59
60
  background: componentTheme.trackBackground,
60
61
  height: `calc(${componentTheme.handleSize} / 2)`
61
62
  };
63
+ const borderedHandleSize = `calc(${componentTheme.handleSize} + (${componentTheme.handleBorderSize} * 2))`;
64
+ const thumbVariantStyle = {
65
+ deprecated: {
66
+ width: componentTheme.handleSize,
67
+ height: componentTheme.handleSize,
68
+ boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}`
69
+ },
70
+ accessible: {
71
+ width: borderedHandleSize,
72
+ height: borderedHandleSize,
73
+ borderWidth: componentTheme.handleBorderSize,
74
+ borderColor: componentTheme.handleBorderColor,
75
+ borderStyle: 'solid',
76
+ boxSizing: 'border-box',
77
+ boxShadow: componentTheme.handleShadow
78
+ }
79
+ };
62
80
  const thumbStyle = {
63
81
  appearance: 'none',
64
82
  borderRadius: '50%',
65
83
  cursor: 'pointer',
66
84
  transition: 'all 0.15s ease-in-out',
67
- width: componentTheme.handleSize,
68
- height: componentTheme.handleSize,
69
85
  background: componentTheme.handleBackground,
70
- boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}`,
86
+ ...thumbVariantStyle[thumbVariant],
71
87
  '&:hover': {
72
88
  background: componentTheme.handleHoverBackground
73
89
  }
74
90
  };
91
+ const thumbPosition = {
92
+ deprecated: {
93
+ marginTop: `calc(-1 * ${componentTheme.handleSize} / 4)`
94
+ },
95
+ accessible: {
96
+ marginTop: `calc(-1 * ${borderedHandleSize} / 4)`
97
+ }
98
+ };
75
99
  const thumbFocusActiveStyle = {
76
- boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}, 0 0 0 ${componentTheme.handleFocusOutlineWidth} ${componentTheme.handleFocusOutlineColor}`
100
+ deprecated: {
101
+ background: componentTheme.handleFocusBackground,
102
+ boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}, 0 0 0 ${componentTheme.handleFocusOutlineWidth} ${componentTheme.handleFocusOutlineColor}`
103
+ },
104
+ accessible: {
105
+ background: componentTheme.handleFocusBackground,
106
+ boxShadow: componentTheme.handleShadow + ', ' + `inset 0 0 0 ${componentTheme.handleFocusInset} ${componentTheme.handleFocusBackground}, ` + `inset 0 0 0 calc(${componentTheme.handleFocusInset} + ${componentTheme.handleFocusRingSize}) ${componentTheme.handleFocusRingColor}`
107
+ }
77
108
  };
78
109
  return {
79
110
  rangeInput: {
@@ -94,13 +125,13 @@ const generateStyle = (componentTheme, props) => {
94
125
  outline: 'none',
95
126
  margin: 0,
96
127
  '&::-webkit-slider-thumb': { ...thumbStyle,
97
- marginTop: `calc(-1 * ${componentTheme.handleSize} / 4)`
128
+ ...thumbPosition[thumbVariant]
98
129
  },
99
130
  '&::-moz-range-thumb': thumbStyle,
100
131
  '&:focus, &:active': {
101
132
  outline: 'none',
102
- '&::-webkit-slider-thumb': thumbFocusActiveStyle,
103
- '&::-moz-range-thumb': thumbFocusActiveStyle
133
+ '&::-webkit-slider-thumb': thumbFocusActiveStyle[thumbVariant],
134
+ '&::-moz-range-thumb': thumbFocusActiveStyle[thumbVariant]
104
135
  },
105
136
  // remove outline in FF
106
137
  '&::-moz-focus-inner, &::-moz-focus-outer': {
@@ -30,6 +30,7 @@ import { alpha, darken } from '@instructure/ui-color-utils';
30
30
  */
31
31
  const generateComponentTheme = theme => {
32
32
  const colors = theme.colors,
33
+ borders = theme.borders,
33
34
  typography = theme.typography,
34
35
  spacing = theme.spacing,
35
36
  forms = theme.forms,
@@ -37,19 +38,27 @@ const generateComponentTheme = theme => {
37
38
  const themeSpecificStyle = {
38
39
  canvas: {
39
40
  handleBackground: theme['ic-brand-primary'],
40
- handleShadowColor: darken(theme['ic-brand-primary'], 15),
41
- handleFocusOutlineColor: alpha(theme['ic-brand-primary'], 40),
42
41
  handleHoverBackground: theme['ic-brand-primary'],
43
- handleFocusBackground: theme['ic-brand-primary']
42
+ handleFocusBackground: theme['ic-brand-primary'],
43
+ // Deprecated, remove with "deprecated" thumbVariant
44
+ handleShadowColor: darken(theme['ic-brand-primary'], 15),
45
+ handleFocusOutlineColor: alpha(theme['ic-brand-primary'], 40)
44
46
  }
45
47
  };
46
48
  const componentVariables = {
47
49
  minWidth: '12.5rem',
48
50
  handleSize: '1.5rem',
49
51
  handleBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundBrand,
50
- handleShadowColor: darken(colors === null || colors === void 0 ? void 0 : colors.borderBrand, 15),
51
- handleHoverBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundBrand,
52
+ handleBorderColor: colors === null || colors === void 0 ? void 0 : colors.borderLightest,
53
+ handleBorderSize: borders === null || borders === void 0 ? void 0 : borders.widthMedium,
54
+ handleShadow: '0 0.0625rem 0.125rem rgba(0, 0, 0, .2), 0 0.0625rem 0.1875rem rgba(0, 0, 0, 0.1)',
55
+ handleFocusInset: borders === null || borders === void 0 ? void 0 : borders.widthSmall,
56
+ handleFocusRingSize: borders === null || borders === void 0 ? void 0 : borders.widthMedium,
57
+ handleFocusRingColor: colors === null || colors === void 0 ? void 0 : colors.backgroundLightest,
52
58
  handleFocusBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundBrand,
59
+ handleHoverBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundBrand,
60
+ // Deprecated, remove with "deprecated" thumbVariant
61
+ handleShadowColor: darken(colors === null || colors === void 0 ? void 0 : colors.borderBrand, 15),
53
62
  handleFocusOutlineColor: alpha(colors === null || colors === void 0 ? void 0 : colors.borderBrand, 40),
54
63
  handleFocusOutlineWidth: '0.75em',
55
64
  trackBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundDark,
@@ -204,7 +204,8 @@ let RangeInput = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
204
204
  layout: 'stacked',
205
205
  displayValue: true,
206
206
  disabled: false,
207
- readOnly: false
207
+ readOnly: false,
208
+ thumbVariant: 'deprecated'
208
209
  }, _temp)) || _class) || _class) || _class);
209
210
  exports.RangeInput = RangeInput;
210
211
  var _default = RangeInput;
@@ -11,6 +11,8 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
 
12
12
  var _controllable = require("@instructure/ui-prop-types/lib/controllable.js");
13
13
 
14
+ var _deprecated = require("@instructure/ui-react-utils/lib/deprecated.js");
15
+
14
16
  var _FormPropTypes = require("@instructure/ui-form-field/lib/FormPropTypes.js");
15
17
 
16
18
  /*
@@ -52,8 +54,9 @@ const propTypes = {
52
54
  formatValue: _propTypes.default.func,
53
55
  inline: _propTypes.default.bool,
54
56
  disabled: _propTypes.default.bool,
55
- readOnly: _propTypes.default.bool
57
+ readOnly: _propTypes.default.bool,
58
+ thumbVariant: _deprecated.deprecated.deprecatePropValues(_propTypes.default.oneOf(['deprecated', 'accessible']), ['deprecated'], 'The `deprecated` variant is not fully accessible and will be removed in V9. The connected theme variables will be removed as well: `handleShadowColor`, `handleFocusOutlineColor`, `handleFocusOutlineWidth`. Please use the `accessible` variant.')
56
59
  };
57
60
  exports.propTypes = propTypes;
58
- const allowedProps = ['min', 'max', 'defaultValue', 'value', 'onChange', 'messages', 'size', 'layout', 'id', 'label', 'displayValue', 'step', 'formatValue', 'inline', 'disabled', 'readOnly'];
61
+ const allowedProps = ['min', 'max', 'defaultValue', 'value', 'onChange', 'messages', 'size', 'layout', 'id', 'label', 'displayValue', 'step', 'formatValue', 'inline', 'disabled', 'readOnly', 'thumbVariant'];
59
62
  exports.allowedProps = allowedProps;
@@ -40,7 +40,8 @@ exports.default = void 0;
40
40
  * @return {Object} The final style object, which will be used in the component
41
41
  */
42
42
  const generateStyle = (componentTheme, props) => {
43
- const size = props.size;
43
+ const size = props.size,
44
+ thumbVariant = props.thumbVariant;
44
45
  const valueSizeVariants = {
45
46
  small: {
46
47
  fontSize: componentTheme.valueSmallFontSize,
@@ -66,21 +67,51 @@ const generateStyle = (componentTheme, props) => {
66
67
  background: componentTheme.trackBackground,
67
68
  height: `calc(${componentTheme.handleSize} / 2)`
68
69
  };
70
+ const borderedHandleSize = `calc(${componentTheme.handleSize} + (${componentTheme.handleBorderSize} * 2))`;
71
+ const thumbVariantStyle = {
72
+ deprecated: {
73
+ width: componentTheme.handleSize,
74
+ height: componentTheme.handleSize,
75
+ boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}`
76
+ },
77
+ accessible: {
78
+ width: borderedHandleSize,
79
+ height: borderedHandleSize,
80
+ borderWidth: componentTheme.handleBorderSize,
81
+ borderColor: componentTheme.handleBorderColor,
82
+ borderStyle: 'solid',
83
+ boxSizing: 'border-box',
84
+ boxShadow: componentTheme.handleShadow
85
+ }
86
+ };
69
87
  const thumbStyle = {
70
88
  appearance: 'none',
71
89
  borderRadius: '50%',
72
90
  cursor: 'pointer',
73
91
  transition: 'all 0.15s ease-in-out',
74
- width: componentTheme.handleSize,
75
- height: componentTheme.handleSize,
76
92
  background: componentTheme.handleBackground,
77
- boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}`,
93
+ ...thumbVariantStyle[thumbVariant],
78
94
  '&:hover': {
79
95
  background: componentTheme.handleHoverBackground
80
96
  }
81
97
  };
98
+ const thumbPosition = {
99
+ deprecated: {
100
+ marginTop: `calc(-1 * ${componentTheme.handleSize} / 4)`
101
+ },
102
+ accessible: {
103
+ marginTop: `calc(-1 * ${borderedHandleSize} / 4)`
104
+ }
105
+ };
82
106
  const thumbFocusActiveStyle = {
83
- boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}, 0 0 0 ${componentTheme.handleFocusOutlineWidth} ${componentTheme.handleFocusOutlineColor}`
107
+ deprecated: {
108
+ background: componentTheme.handleFocusBackground,
109
+ boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}, 0 0 0 ${componentTheme.handleFocusOutlineWidth} ${componentTheme.handleFocusOutlineColor}`
110
+ },
111
+ accessible: {
112
+ background: componentTheme.handleFocusBackground,
113
+ boxShadow: componentTheme.handleShadow + ', ' + `inset 0 0 0 ${componentTheme.handleFocusInset} ${componentTheme.handleFocusBackground}, ` + `inset 0 0 0 calc(${componentTheme.handleFocusInset} + ${componentTheme.handleFocusRingSize}) ${componentTheme.handleFocusRingColor}`
114
+ }
84
115
  };
85
116
  return {
86
117
  rangeInput: {
@@ -101,13 +132,13 @@ const generateStyle = (componentTheme, props) => {
101
132
  outline: 'none',
102
133
  margin: 0,
103
134
  '&::-webkit-slider-thumb': { ...thumbStyle,
104
- marginTop: `calc(-1 * ${componentTheme.handleSize} / 4)`
135
+ ...thumbPosition[thumbVariant]
105
136
  },
106
137
  '&::-moz-range-thumb': thumbStyle,
107
138
  '&:focus, &:active': {
108
139
  outline: 'none',
109
- '&::-webkit-slider-thumb': thumbFocusActiveStyle,
110
- '&::-moz-range-thumb': thumbFocusActiveStyle
140
+ '&::-webkit-slider-thumb': thumbFocusActiveStyle[thumbVariant],
141
+ '&::-moz-range-thumb': thumbFocusActiveStyle[thumbVariant]
111
142
  },
112
143
  // remove outline in FF
113
144
  '&::-moz-focus-inner, &::-moz-focus-outer': {
@@ -40,6 +40,7 @@ var _darken = require("@instructure/ui-color-utils/lib/darken.js");
40
40
  */
41
41
  const generateComponentTheme = theme => {
42
42
  const colors = theme.colors,
43
+ borders = theme.borders,
43
44
  typography = theme.typography,
44
45
  spacing = theme.spacing,
45
46
  forms = theme.forms,
@@ -47,19 +48,27 @@ const generateComponentTheme = theme => {
47
48
  const themeSpecificStyle = {
48
49
  canvas: {
49
50
  handleBackground: theme['ic-brand-primary'],
50
- handleShadowColor: (0, _darken.darken)(theme['ic-brand-primary'], 15),
51
- handleFocusOutlineColor: (0, _alpha.alpha)(theme['ic-brand-primary'], 40),
52
51
  handleHoverBackground: theme['ic-brand-primary'],
53
- handleFocusBackground: theme['ic-brand-primary']
52
+ handleFocusBackground: theme['ic-brand-primary'],
53
+ // Deprecated, remove with "deprecated" thumbVariant
54
+ handleShadowColor: (0, _darken.darken)(theme['ic-brand-primary'], 15),
55
+ handleFocusOutlineColor: (0, _alpha.alpha)(theme['ic-brand-primary'], 40)
54
56
  }
55
57
  };
56
58
  const componentVariables = {
57
59
  minWidth: '12.5rem',
58
60
  handleSize: '1.5rem',
59
61
  handleBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundBrand,
60
- handleShadowColor: (0, _darken.darken)(colors === null || colors === void 0 ? void 0 : colors.borderBrand, 15),
61
- handleHoverBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundBrand,
62
+ handleBorderColor: colors === null || colors === void 0 ? void 0 : colors.borderLightest,
63
+ handleBorderSize: borders === null || borders === void 0 ? void 0 : borders.widthMedium,
64
+ handleShadow: '0 0.0625rem 0.125rem rgba(0, 0, 0, .2), 0 0.0625rem 0.1875rem rgba(0, 0, 0, 0.1)',
65
+ handleFocusInset: borders === null || borders === void 0 ? void 0 : borders.widthSmall,
66
+ handleFocusRingSize: borders === null || borders === void 0 ? void 0 : borders.widthMedium,
67
+ handleFocusRingColor: colors === null || colors === void 0 ? void 0 : colors.backgroundLightest,
62
68
  handleFocusBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundBrand,
69
+ handleHoverBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundBrand,
70
+ // Deprecated, remove with "deprecated" thumbVariant
71
+ handleShadowColor: (0, _darken.darken)(colors === null || colors === void 0 ? void 0 : colors.borderBrand, 15),
63
72
  handleFocusOutlineColor: (0, _alpha.alpha)(colors === null || colors === void 0 ? void 0 : colors.borderBrand, 40),
64
73
  handleFocusOutlineWidth: '0.75em',
65
74
  trackBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundDark,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-range-input",
3
- "version": "8.22.1-snapshot.4+5809c01bc",
3
+ "version": "8.23.0",
4
4
  "description": "A styled HTML range input",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "module": "./es/index.js",
@@ -24,26 +24,26 @@
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
26
  "@babel/runtime": "^7.13.10",
27
- "@instructure/console": "8.22.1-snapshot.4+5809c01bc",
28
- "@instructure/emotion": "8.22.1-snapshot.4+5809c01bc",
29
- "@instructure/shared-types": "8.22.1-snapshot.4+5809c01bc",
30
- "@instructure/ui-color-utils": "8.22.1-snapshot.4+5809c01bc",
31
- "@instructure/ui-dom-utils": "8.22.1-snapshot.4+5809c01bc",
32
- "@instructure/ui-form-field": "8.22.1-snapshot.4+5809c01bc",
33
- "@instructure/ui-i18n": "8.22.1-snapshot.4+5809c01bc",
34
- "@instructure/ui-prop-types": "8.22.1-snapshot.4+5809c01bc",
35
- "@instructure/ui-react-utils": "8.22.1-snapshot.4+5809c01bc",
36
- "@instructure/ui-testable": "8.22.1-snapshot.4+5809c01bc",
37
- "@instructure/ui-utils": "8.22.1-snapshot.4+5809c01bc",
38
- "@instructure/ui-view": "8.22.1-snapshot.4+5809c01bc",
39
- "@instructure/uid": "8.22.1-snapshot.4+5809c01bc",
27
+ "@instructure/console": "8.23.0",
28
+ "@instructure/emotion": "8.23.0",
29
+ "@instructure/shared-types": "8.23.0",
30
+ "@instructure/ui-color-utils": "8.23.0",
31
+ "@instructure/ui-dom-utils": "8.23.0",
32
+ "@instructure/ui-form-field": "8.23.0",
33
+ "@instructure/ui-i18n": "8.23.0",
34
+ "@instructure/ui-prop-types": "8.23.0",
35
+ "@instructure/ui-react-utils": "8.23.0",
36
+ "@instructure/ui-testable": "8.23.0",
37
+ "@instructure/ui-utils": "8.23.0",
38
+ "@instructure/ui-view": "8.23.0",
39
+ "@instructure/uid": "8.23.0",
40
40
  "prop-types": "^15"
41
41
  },
42
42
  "devDependencies": {
43
- "@instructure/ui-babel-preset": "8.22.1-snapshot.4+5809c01bc",
44
- "@instructure/ui-test-locator": "8.22.1-snapshot.4+5809c01bc",
45
- "@instructure/ui-test-utils": "8.22.1-snapshot.4+5809c01bc",
46
- "@instructure/ui-themes": "8.22.1-snapshot.4+5809c01bc"
43
+ "@instructure/ui-babel-preset": "8.23.0",
44
+ "@instructure/ui-test-locator": "8.23.0",
45
+ "@instructure/ui-test-utils": "8.23.0",
46
+ "@instructure/ui-themes": "8.23.0"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "react": ">=16.8 <=17"
@@ -51,6 +51,5 @@
51
51
  "publishConfig": {
52
52
  "access": "public"
53
53
  },
54
- "sideEffects": false,
55
- "gitHead": "5809c01bc3fc6e7b468d18d44c22f364304561ed"
54
+ "sideEffects": false
56
55
  }
@@ -10,25 +10,67 @@ render: false
10
10
  example: true
11
11
  ---
12
12
  class Example extends React.Component {
13
- state = { size: "small" }
14
- handleModalSizeChange = (event, value) => {
13
+ state = {
14
+ size: "small",
15
+ thumbVariant: "accessible",
16
+ }
17
+
18
+ handleSizeChange = (event, value) => {
15
19
  this.setState({ size: value })
16
20
  }
21
+
22
+ handleThumbVariantChange = (event, value) => {
23
+ this.setState({ thumbVariant: value })
24
+ }
25
+
17
26
  render() {
18
27
  return (
19
28
  <div>
20
- <RangeInput label="Grading range" defaultValue={30} max={100} min={0} size={this.state.size} />
21
- <RadioInputGroup
22
- onChange={this.handleModalSizeChange}
23
- name="labelSize"
24
- defaultValue="small"
25
- description="Label size"
26
- variant="toggle"
29
+ <View
30
+ as="div"
31
+ padding="medium"
32
+ background="primary"
27
33
  >
28
- <RadioInput label="small" value="small" />
29
- <RadioInput label="medium" value="medium" />
30
- <RadioInput label="large" value="large" />
31
- </RadioInputGroup>
34
+ <RangeInput
35
+ label="Grading range"
36
+ defaultValue={30}
37
+ max={100}
38
+ min={0}
39
+ size={this.state.size}
40
+ thumbVariant={this.state.thumbVariant}
41
+ />
42
+ </View>
43
+
44
+ <View as="div" margin='medium 0 0'>
45
+ <FormFieldGroup
46
+ description={
47
+ <ScreenReaderContent>RangeInput Example Settings</ScreenReaderContent>
48
+ }
49
+ layout='columns'
50
+ vAlign='top'
51
+ >
52
+ <RadioInputGroup
53
+ onChange={this.handleSizeChange}
54
+ name="labelSize"
55
+ value={this.state.size}
56
+ description="Label size"
57
+ >
58
+ <RadioInput label="small" value="small" />
59
+ <RadioInput label="medium" value="medium" />
60
+ <RadioInput label="large" value="large" />
61
+ </RadioInputGroup>
62
+
63
+ <RadioInputGroup
64
+ onChange={this.handleThumbVariantChange}
65
+ name="thumbVariant"
66
+ value={this.state.thumbVariant}
67
+ description="Thumb variant"
68
+ >
69
+ <RadioInput label="accessible" value="accessible" />
70
+ <RadioInput label="deprecated" value="deprecated" />
71
+ </RadioInputGroup>
72
+ </FormFieldGroup>
73
+ </View>
32
74
  </div>
33
75
  )
34
76
  }
@@ -72,7 +72,8 @@ class RangeInput extends Component<RangeInputProps, RangeInputState> {
72
72
  layout: 'stacked',
73
73
  displayValue: true,
74
74
  disabled: false,
75
- readOnly: false
75
+ readOnly: false,
76
+ thumbVariant: 'deprecated'
76
77
  }
77
78
 
78
79
  ref: Element | null = null
@@ -26,6 +26,7 @@ import React from 'react'
26
26
  import PropTypes from 'prop-types'
27
27
 
28
28
  import { controllable } from '@instructure/ui-prop-types'
29
+ import { deprecated } from '@instructure/ui-react-utils'
29
30
  import { FormPropTypes } from '@instructure/ui-form-field'
30
31
 
31
32
  import type {
@@ -89,6 +90,14 @@ type RangeInputOwnProps = {
89
90
  disabled?: boolean
90
91
 
91
92
  readOnly?: boolean
93
+
94
+ /**
95
+ * The "default" variant has an outer shadow on focus.
96
+ * The "accessible" variant has better color contrast, border and inset focus ring for better accessibility.
97
+ */
98
+ thumbVariant?:
99
+ | 'deprecated' // TODO: deprecated, remove in V9.
100
+ | 'accessible'
92
101
  }
93
102
 
94
103
  type PropKeys = keyof RangeInputOwnProps
@@ -101,12 +110,13 @@ type RangeInputProps =
101
110
  FormFieldOwnProps,
102
111
  'label' | 'inline' | 'id' | 'elementRef'
103
112
  > &
104
- RangeInputOwnProps &
105
- WithStyleProps<RangeInputTheme, RangeInputStyle> &
106
- OtherHTMLAttributes<
107
- RangeInputOwnProps,
108
- InputHTMLAttributes<RangeInputOwnProps>
109
- > & WithDeterministicIdProps
113
+ RangeInputOwnProps &
114
+ WithStyleProps<RangeInputTheme, RangeInputStyle> &
115
+ OtherHTMLAttributes<
116
+ RangeInputOwnProps,
117
+ InputHTMLAttributes<RangeInputOwnProps>
118
+ > &
119
+ WithDeterministicIdProps
110
120
 
111
121
  type RangeInputStyle = ComponentStyle<
112
122
  'rangeInput' | 'rangeInputInput' | 'rangeInputInputValue'
@@ -132,7 +142,12 @@ const propTypes: PropValidators<PropKeys> = {
132
142
  formatValue: PropTypes.func,
133
143
  inline: PropTypes.bool,
134
144
  disabled: PropTypes.bool,
135
- readOnly: PropTypes.bool
145
+ readOnly: PropTypes.bool,
146
+ thumbVariant: deprecated.deprecatePropValues(
147
+ PropTypes.oneOf(['deprecated', 'accessible']),
148
+ ['deprecated'],
149
+ 'The `deprecated` variant is not fully accessible and will be removed in V9. The connected theme variables will be removed as well: `handleShadowColor`, `handleFocusOutlineColor`, `handleFocusOutlineWidth`. Please use the `accessible` variant.'
150
+ )
136
151
  }
137
152
 
138
153
  const allowedProps: AllowedPropKeys = [
@@ -151,7 +166,8 @@ const allowedProps: AllowedPropKeys = [
151
166
  'formatValue',
152
167
  'inline',
153
168
  'disabled',
154
- 'readOnly'
169
+ 'readOnly',
170
+ 'thumbVariant'
155
171
  ]
156
172
 
157
173
  export type { RangeInputProps, RangeInputState, RangeInputStyle }
@@ -39,7 +39,7 @@ const generateStyle = (
39
39
  componentTheme: RangeInputTheme,
40
40
  props: RangeInputProps
41
41
  ): RangeInputStyle => {
42
- const { size } = props
42
+ const { size, thumbVariant } = props
43
43
  const valueSizeVariants = {
44
44
  small: {
45
45
  fontSize: componentTheme.valueSmallFontSize,
@@ -57,6 +57,7 @@ const generateStyle = (
57
57
  lineHeight: componentTheme.valueLargeLineHeight
58
58
  }
59
59
  }
60
+
60
61
  const trackStyle = {
61
62
  borderRadius: '0.312em',
62
63
  borderColor: 'transparent',
@@ -65,21 +66,61 @@ const generateStyle = (
65
66
  background: componentTheme.trackBackground,
66
67
  height: `calc(${componentTheme.handleSize} / 2)`
67
68
  }
69
+
70
+ const borderedHandleSize = `calc(${componentTheme.handleSize} + (${componentTheme.handleBorderSize} * 2))`
71
+
72
+ const thumbVariantStyle = {
73
+ deprecated: {
74
+ width: componentTheme.handleSize,
75
+ height: componentTheme.handleSize,
76
+ boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}`
77
+ },
78
+ accessible: {
79
+ width: borderedHandleSize,
80
+ height: borderedHandleSize,
81
+ borderWidth: componentTheme.handleBorderSize,
82
+ borderColor: componentTheme.handleBorderColor,
83
+ borderStyle: 'solid',
84
+ boxSizing: 'border-box',
85
+ boxShadow: componentTheme.handleShadow
86
+ }
87
+ }
88
+
68
89
  const thumbStyle = {
69
90
  appearance: 'none',
70
91
  borderRadius: '50%',
71
92
  cursor: 'pointer',
72
93
  transition: 'all 0.15s ease-in-out',
73
- width: componentTheme.handleSize,
74
- height: componentTheme.handleSize,
75
94
  background: componentTheme.handleBackground,
76
- boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}`,
95
+ ...thumbVariantStyle[thumbVariant!],
96
+
77
97
  '&:hover': {
78
98
  background: componentTheme.handleHoverBackground
79
99
  }
80
100
  }
101
+
102
+ const thumbPosition = {
103
+ deprecated: {
104
+ marginTop: `calc(-1 * ${componentTheme.handleSize} / 4)`
105
+ },
106
+ accessible: {
107
+ marginTop: `calc(-1 * ${borderedHandleSize} / 4)`
108
+ }
109
+ }
110
+
81
111
  const thumbFocusActiveStyle = {
82
- boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}, 0 0 0 ${componentTheme.handleFocusOutlineWidth} ${componentTheme.handleFocusOutlineColor}`
112
+ deprecated: {
113
+ background: componentTheme.handleFocusBackground,
114
+ boxShadow: `0 0.0625rem 0 ${componentTheme.handleShadowColor}, 0 0 0 ${componentTheme.handleFocusOutlineWidth} ${componentTheme.handleFocusOutlineColor}`
115
+ },
116
+ accessible: {
117
+ background: componentTheme.handleFocusBackground,
118
+ boxShadow:
119
+ componentTheme.handleShadow +
120
+ ', ' +
121
+ `inset 0 0 0 ${componentTheme.handleFocusInset} ${componentTheme.handleFocusBackground}, ` +
122
+ `inset 0 0 0 calc(${componentTheme.handleFocusInset} + ${componentTheme.handleFocusRingSize}) ${componentTheme.handleFocusRingColor}`
123
+ }
83
124
  }
84
125
 
85
126
  return {
@@ -99,15 +140,16 @@ const generateStyle = (
99
140
  width: '100%', // for Firefox
100
141
  outline: 'none',
101
142
  margin: 0,
143
+
102
144
  '&::-webkit-slider-thumb': {
103
145
  ...thumbStyle,
104
- marginTop: `calc(-1 * ${componentTheme.handleSize} / 4)`
146
+ ...thumbPosition[thumbVariant!]
105
147
  },
106
148
  '&::-moz-range-thumb': thumbStyle,
107
149
  '&:focus, &:active': {
108
150
  outline: 'none',
109
- '&::-webkit-slider-thumb': thumbFocusActiveStyle,
110
- '&::-moz-range-thumb': thumbFocusActiveStyle
151
+ '&::-webkit-slider-thumb': thumbFocusActiveStyle[thumbVariant!],
152
+ '&::-moz-range-thumb': thumbFocusActiveStyle[thumbVariant!]
111
153
  },
112
154
  // remove outline in FF
113
155
  '&::-moz-focus-inner, &::-moz-focus-outer': {