@instructure/ui-options 8.19.1-snapshot.8 → 8.20.1-snapshot.18

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 (39) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/es/Options/Item/__examples__/Item.examples.js +5 -0
  3. package/es/Options/Item/index.js +16 -9
  4. package/es/Options/Item/props.js +3 -2
  5. package/es/Options/Item/styles.js +18 -1
  6. package/es/Options/Item/theme.js +1 -1
  7. package/es/Options/index.js +2 -2
  8. package/es/Options/theme.js +3 -5
  9. package/es/index.js +1 -1
  10. package/lib/Options/Item/__examples__/Item.examples.js +5 -0
  11. package/lib/Options/Item/index.js +15 -8
  12. package/lib/Options/Item/props.js +3 -2
  13. package/lib/Options/Item/styles.js +18 -1
  14. package/lib/Options/Item/theme.js +1 -1
  15. package/lib/Options/index.js +2 -2
  16. package/lib/Options/theme.js +3 -7
  17. package/lib/index.js +0 -6
  18. package/package.json +14 -14
  19. package/src/Options/Item/__examples__/Item.examples.ts +10 -0
  20. package/src/Options/Item/index.tsx +31 -4
  21. package/src/Options/Item/props.ts +22 -3
  22. package/src/Options/Item/styles.ts +17 -1
  23. package/src/Options/Item/theme.ts +1 -1
  24. package/src/Options/README.md +61 -0
  25. package/src/Options/index.tsx +8 -2
  26. package/src/Options/theme.ts +1 -10
  27. package/src/index.ts +1 -1
  28. package/tsconfig.build.tsbuildinfo +1 -1
  29. package/types/Options/Item/__examples__/Item.examples.d.ts.map +1 -1
  30. package/types/Options/Item/index.d.ts +6 -4
  31. package/types/Options/Item/index.d.ts.map +1 -1
  32. package/types/Options/Item/props.d.ts +8 -3
  33. package/types/Options/Item/props.d.ts.map +1 -1
  34. package/types/Options/Item/styles.d.ts.map +1 -1
  35. package/types/Options/index.d.ts.map +1 -1
  36. package/types/Options/theme.d.ts +1 -2
  37. package/types/Options/theme.d.ts.map +1 -1
  38. package/types/index.d.ts +1 -1
  39. package/types/index.d.ts.map +1 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,13 @@
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.20.0](https://github.com/instructure/instructure-ui/compare/v8.19.0...v8.20.0) (2022-03-22)
7
+
8
+ ### Features
9
+
10
+ - **ui-options:** add `href` prop to Options.Item ([49bf28c](https://github.com/instructure/instructure-ui/commit/49bf28c637f395f7ae5d23c0f676d83a15c2ee43))
11
+ - **ui-options:** modify default nested Options padding to have no extra padding ([bfc4f7c](https://github.com/instructure/instructure-ui/commit/bfc4f7cb094d91d25b58a87a24a473363c90796b))
12
+
6
13
  # [8.19.0](https://github.com/instructure/instructure-ui/compare/v8.18.0...v8.19.0) (2022-03-16)
7
14
 
8
15
  ### Bug Fixes
@@ -27,6 +27,7 @@ export default {
27
27
  propValues: {
28
28
  renderAfterLabel: [null, IconArrowOpenEndSolid],
29
29
  renderBeforeLabel: [null, IconCheckSolid],
30
+ href: [void 0, '/hello'],
30
31
  description: [null, 'Curabitur fringilla, urna ut efficitur molestie, nibh lacus tincidunt elit, ut tempor ipsum nunc sit amet massa. Integer sit amet ante vitae lectus gravida pulvinar.']
31
32
  },
32
33
  getComponentProps: props => {
@@ -60,6 +61,10 @@ export default {
60
61
  }
61
62
  }
62
63
 
64
+ if (props.href && (props.beforeLabelContentVAlign !== 'center' || props.afterLabelContentVAlign !== 'center' || props.description)) {
65
+ return true;
66
+ }
67
+
63
68
  return false;
64
69
  }
65
70
  };
@@ -1,4 +1,4 @@
1
- var _dec, _dec2, _class, _class2, _temp;
1
+ var _dec, _dec2, _dec3, _class, _class2, _temp;
2
2
 
3
3
  /*
4
4
  * The MIT License (MIT)
@@ -26,7 +26,7 @@ var _dec, _dec2, _class, _class2, _temp;
26
26
 
27
27
  /** @jsx jsx */
28
28
  import { Component } from 'react';
29
- import { omitProps, getElementType, callRenderProp } from '@instructure/ui-react-utils';
29
+ import { omitProps, getElementType, callRenderProp, withDeterministicId } from '@instructure/ui-react-utils';
30
30
  import { testable } from '@instructure/ui-testable';
31
31
  import { withStyle, jsx } from '@instructure/emotion';
32
32
  import generateStyles from './styles';
@@ -40,10 +40,12 @@ id: Options.Item
40
40
  @tsProps
41
41
  **/
42
42
 
43
- let Item = (_dec = withStyle(generateStyles, generateComponentTheme), _dec2 = testable(), _dec(_class = _dec2(_class = (_temp = _class2 = class Item extends Component {
44
- constructor() {
45
- super(...arguments);
43
+ let Item = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyles, generateComponentTheme), _dec3 = testable(), _dec(_class = _dec2(_class = _dec3(_class = (_temp = _class2 = class Item extends Component {
44
+ constructor(props) {
45
+ super(props);
46
46
  this.ref = null;
47
+ this._descriptionId = void 0;
48
+ this._descriptionId = props.deterministicId('OptionsItem-description');
47
49
  }
48
50
 
49
51
  componentDidMount() {
@@ -80,6 +82,7 @@ let Item = (_dec = withStyle(generateStyles, generateComponentTheme), _dec2 = te
80
82
  render() {
81
83
  const _this$props4 = this.props,
82
84
  as = _this$props4.as,
85
+ href = _this$props4.href,
83
86
  role = _this$props4.role,
84
87
  styles = _this$props4.styles,
85
88
  description = _this$props4.description,
@@ -89,6 +92,7 @@ let Item = (_dec = withStyle(generateStyles, generateComponentTheme), _dec2 = te
89
92
  elementRef = _this$props4.elementRef,
90
93
  children = _this$props4.children;
91
94
  const ElementType = getElementType(Item, this.props, () => as);
95
+ const InnerElementType = href ? 'a' : 'span';
92
96
  const passthroughProps = omitProps(this.props, Item.allowedProps);
93
97
  const childrenContent = callRenderProp(children);
94
98
  const descriptionContent = callRenderProp(description);
@@ -102,12 +106,15 @@ let Item = (_dec = withStyle(generateStyles, generateComponentTheme), _dec2 = te
102
106
  elementRef(element);
103
107
  }
104
108
  }
105
- }, jsx("span", Object.assign({}, passthroughProps, {
109
+ }, jsx(InnerElementType, Object.assign({}, passthroughProps, {
106
110
  css: styles === null || styles === void 0 ? void 0 : styles.container,
107
- role: role
111
+ role: href ? void 0 : role,
112
+ href: href,
113
+ "aria-describedby": this.props['aria-describedby'] || (descriptionContent ? this._descriptionId : void 0)
108
114
  }), childrenContent, descriptionContent && jsx("span", {
109
115
  css: styles === null || styles === void 0 ? void 0 : styles.description,
110
- role: descriptionRole
116
+ role: descriptionRole,
117
+ id: this._descriptionId
111
118
  }, descriptionContent)), renderBeforeLabel && this.renderContent(renderBeforeLabel, styles === null || styles === void 0 ? void 0 : styles.contentBefore), renderAfterLabel && this.renderContent(renderAfterLabel, styles === null || styles === void 0 ? void 0 : styles.contentAfter));
112
119
  }
113
120
 
@@ -118,6 +125,6 @@ let Item = (_dec = withStyle(generateStyles, generateComponentTheme), _dec2 = te
118
125
  descriptionRole: 'note',
119
126
  beforeLabelContentVAlign: 'center',
120
127
  afterLabelContentVAlign: 'center'
121
- }, _temp)) || _class) || _class);
128
+ }, _temp)) || _class) || _class) || _class);
122
129
  export default Item;
123
130
  export { Item };
@@ -24,7 +24,7 @@
24
24
  import PropTypes from 'prop-types';
25
25
  const propTypes = {
26
26
  as: PropTypes.elementType,
27
- variant: PropTypes.oneOf(['default', 'highlighted', 'selected', 'disabled']),
27
+ variant: PropTypes.oneOf(['default', 'highlighted', 'selected', 'disabled', 'highlighted-disabled']),
28
28
  role: PropTypes.string,
29
29
  renderBeforeLabel: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
30
30
  renderAfterLabel: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
@@ -32,8 +32,9 @@ const propTypes = {
32
32
  afterLabelContentVAlign: PropTypes.oneOf(['start', 'center', 'end']),
33
33
  description: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
34
34
  descriptionRole: PropTypes.string,
35
+ href: PropTypes.string,
35
36
  elementRef: PropTypes.func,
36
37
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.func])
37
38
  };
38
- const allowedProps = ['as', 'variant', 'role', 'renderBeforeLabel', 'renderAfterLabel', 'beforeLabelContentVAlign', 'afterLabelContentVAlign', 'description', 'descriptionRole', 'elementRef', 'children'];
39
+ const allowedProps = ['as', 'variant', 'role', 'renderBeforeLabel', 'renderAfterLabel', 'beforeLabelContentVAlign', 'afterLabelContentVAlign', 'description', 'descriptionRole', 'href', 'elementRef', 'children'];
39
40
  export { propTypes, allowedProps };
@@ -55,6 +55,12 @@ const generateStyle = (componentTheme, props) => {
55
55
  cursor: 'not-allowed',
56
56
  opacity: 0.5
57
57
  },
58
+ ['highlighted-disabled']: {
59
+ background: componentTheme.highlightedBackground,
60
+ color: componentTheme.highlightedLabelColor,
61
+ cursor: 'not-allowed',
62
+ opacity: 0.5
63
+ },
58
64
  default: {}
59
65
  };
60
66
 
@@ -78,6 +84,10 @@ const generateStyle = (componentTheme, props) => {
78
84
  }[vAlign];
79
85
  };
80
86
 
87
+ const linkStyles = {
88
+ textDecoration: 'none',
89
+ color: 'currentColor'
90
+ };
81
91
  const transition = 'background 200ms';
82
92
  return {
83
93
  item: {
@@ -129,7 +139,14 @@ const generateStyle = (componentTheme, props) => {
129
139
  ...(hasContentBeforeLabel && hasContentAfterLabel && {
130
140
  paddingInlineEnd: `calc(${componentTheme.iconPadding} * 2 + 1em)`,
131
141
  paddingInlineStart: `calc(${componentTheme.iconPadding} * 2 + 1em)`
132
- })
142
+ }),
143
+ // NOTE: needs separate groups for `:is()` and `:-webkit-any()` because of css selector group validation (see https://www.w3.org/TR/selectors-3/#grouping)
144
+ '&:is(a)': {
145
+ '&, &:link, &:visited, &:active, &:hover, &:focus': linkStyles
146
+ },
147
+ '&:-webkit-any(a)': {
148
+ '&, &:link, &:visited, &:active, &:hover, &:focus': linkStyles
149
+ }
133
150
  },
134
151
  content: {
135
152
  label: 'optionItem__content',
@@ -51,7 +51,7 @@ const generateComponentTheme = theme => {
51
51
  selectedBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundDark,
52
52
  padding: `${spacing === null || spacing === void 0 ? void 0 : spacing.xSmall} ${spacing === null || spacing === void 0 ? void 0 : spacing.small}`,
53
53
  iconPadding: spacing === null || spacing === void 0 ? void 0 : spacing.small,
54
- nestedPadding: spacing === null || spacing === void 0 ? void 0 : spacing.medium,
54
+ nestedPadding: spacing === null || spacing === void 0 ? void 0 : spacing.small,
55
55
  beforeLabelContentVOffset: '0.625rem',
56
56
  afterLabelContentVOffset: '0.625rem',
57
57
  descriptionFontSize: typography.fontSizeSmall,
@@ -106,7 +106,7 @@ let Options = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyles, g
106
106
 
107
107
  if (matchComponentTypes(child, ['Item', 'Separator'])) {
108
108
  return safeCloneElement(child, {
109
- as: this.childAs
109
+ as: this.childAs || child.props.as
110
110
  });
111
111
  }
112
112
 
@@ -135,7 +135,7 @@ let Options = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyles, g
135
135
  margin: "none",
136
136
  padding: "none",
137
137
  background: "primary",
138
- "aria-labelledby": renderLabel ? this._labelId : void 0
138
+ "aria-labelledby": renderLabel ? this._labelId : this.props['aria-labelledby'] ? this.props['aria-labelledby'] : void 0
139
139
  }), this.renderChildren()));
140
140
  }
141
141
 
@@ -21,18 +21,16 @@
21
21
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
22
  * SOFTWARE.
23
23
  */
24
- const optionsThemeKeys = ['labelFontWeight', 'background', 'labelColor', 'labelPadding', 'nestedLabelPadding'];
24
+
25
25
  /**
26
26
  * Generates the theme object for the component from the theme and provided additional information
27
27
  * @param {Object} theme The actual theme object.
28
28
  * @return {Object} The final theme object with the overrides and component variables
29
29
  */
30
-
31
30
  const generateComponentTheme = theme => {
32
31
  const colors = theme.colors,
33
32
  typography = theme.typography,
34
- spacing = theme.spacing; // TODO: if updated, update optionsThemeKeys array too
35
-
33
+ spacing = theme.spacing;
36
34
  const componentVariables = {
37
35
  labelFontWeight: typography === null || typography === void 0 ? void 0 : typography.fontWeightBold,
38
36
  background: colors === null || colors === void 0 ? void 0 : colors.backgroundLightest,
@@ -44,5 +42,5 @@ const generateComponentTheme = theme => {
44
42
  };
45
43
  };
46
44
 
47
- export { generateComponentTheme as optionsThemeGenerator, optionsThemeKeys };
45
+ export { generateComponentTheme as optionsThemeGenerator };
48
46
  export default generateComponentTheme;
package/es/index.js CHANGED
@@ -22,6 +22,6 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
  export { Options } from './Options';
25
- export { optionsThemeGenerator, optionsThemeKeys } from './Options/theme';
25
+ export { optionsThemeGenerator } from './Options/theme';
26
26
  export { optionsItemThemeGenerator } from './Options/Item/theme';
27
27
  export { optionsSeparatorThemeGenerator } from './Options/Separator/theme';
@@ -35,6 +35,7 @@ var _default = {
35
35
  propValues: {
36
36
  renderAfterLabel: [null, _uiIcons.IconArrowOpenEndSolid],
37
37
  renderBeforeLabel: [null, _uiIcons.IconCheckSolid],
38
+ href: [void 0, '/hello'],
38
39
  description: [null, 'Curabitur fringilla, urna ut efficitur molestie, nibh lacus tincidunt elit, ut tempor ipsum nunc sit amet massa. Integer sit amet ante vitae lectus gravida pulvinar.']
39
40
  },
40
41
  getComponentProps: props => {
@@ -68,6 +69,10 @@ var _default = {
68
69
  }
69
70
  }
70
71
 
72
+ if (props.href && (props.beforeLabelContentVAlign !== 'center' || props.afterLabelContentVAlign !== 'center' || props.description)) {
73
+ return true;
74
+ }
75
+
71
76
  return false;
72
77
  }
73
78
  };
@@ -21,7 +21,7 @@ var _theme = _interopRequireDefault(require("./theme"));
21
21
 
22
22
  var _props = require("./props");
23
23
 
24
- var _dec, _dec2, _class, _class2, _temp;
24
+ var _dec, _dec2, _dec3, _class, _class2, _temp;
25
25
 
26
26
  /**
27
27
  ---
@@ -30,10 +30,12 @@ id: Options.Item
30
30
  ---
31
31
  @tsProps
32
32
  **/
33
- let Item = (_dec = (0, _emotion.withStyle)(_styles.default, _theme.default), _dec2 = (0, _uiTestable.testable)(), _dec(_class = _dec2(_class = (_temp = _class2 = class Item extends _react.Component {
34
- constructor() {
35
- super(...arguments);
33
+ let Item = (_dec = (0, _uiReactUtils.withDeterministicId)(), _dec2 = (0, _emotion.withStyle)(_styles.default, _theme.default), _dec3 = (0, _uiTestable.testable)(), _dec(_class = _dec2(_class = _dec3(_class = (_temp = _class2 = class Item extends _react.Component {
34
+ constructor(props) {
35
+ super(props);
36
36
  this.ref = null;
37
+ this._descriptionId = void 0;
38
+ this._descriptionId = props.deterministicId('OptionsItem-description');
37
39
  }
38
40
 
39
41
  componentDidMount() {
@@ -70,6 +72,7 @@ let Item = (_dec = (0, _emotion.withStyle)(_styles.default, _theme.default), _de
70
72
  render() {
71
73
  const _this$props4 = this.props,
72
74
  as = _this$props4.as,
75
+ href = _this$props4.href,
73
76
  role = _this$props4.role,
74
77
  styles = _this$props4.styles,
75
78
  description = _this$props4.description,
@@ -79,6 +82,7 @@ let Item = (_dec = (0, _emotion.withStyle)(_styles.default, _theme.default), _de
79
82
  elementRef = _this$props4.elementRef,
80
83
  children = _this$props4.children;
81
84
  const ElementType = (0, _uiReactUtils.getElementType)(Item, this.props, () => as);
85
+ const InnerElementType = href ? 'a' : 'span';
82
86
  const passthroughProps = (0, _uiReactUtils.omitProps)(this.props, Item.allowedProps);
83
87
  const childrenContent = (0, _uiReactUtils.callRenderProp)(children);
84
88
  const descriptionContent = (0, _uiReactUtils.callRenderProp)(description);
@@ -92,12 +96,15 @@ let Item = (_dec = (0, _emotion.withStyle)(_styles.default, _theme.default), _de
92
96
  elementRef(element);
93
97
  }
94
98
  }
95
- }, (0, _emotion.jsx)("span", Object.assign({}, passthroughProps, {
99
+ }, (0, _emotion.jsx)(InnerElementType, Object.assign({}, passthroughProps, {
96
100
  css: styles === null || styles === void 0 ? void 0 : styles.container,
97
- role: role
101
+ role: href ? void 0 : role,
102
+ href: href,
103
+ "aria-describedby": this.props['aria-describedby'] || (descriptionContent ? this._descriptionId : void 0)
98
104
  }), childrenContent, descriptionContent && (0, _emotion.jsx)("span", {
99
105
  css: styles === null || styles === void 0 ? void 0 : styles.description,
100
- role: descriptionRole
106
+ role: descriptionRole,
107
+ id: this._descriptionId
101
108
  }, descriptionContent)), renderBeforeLabel && this.renderContent(renderBeforeLabel, styles === null || styles === void 0 ? void 0 : styles.contentBefore), renderAfterLabel && this.renderContent(renderAfterLabel, styles === null || styles === void 0 ? void 0 : styles.contentAfter));
102
109
  }
103
110
 
@@ -108,7 +115,7 @@ let Item = (_dec = (0, _emotion.withStyle)(_styles.default, _theme.default), _de
108
115
  descriptionRole: 'note',
109
116
  beforeLabelContentVAlign: 'center',
110
117
  afterLabelContentVAlign: 'center'
111
- }, _temp)) || _class) || _class);
118
+ }, _temp)) || _class) || _class) || _class);
112
119
  exports.Item = Item;
113
120
  var _default = Item;
114
121
  exports.default = _default;
@@ -34,7 +34,7 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
34
34
  */
35
35
  const propTypes = {
36
36
  as: _propTypes.default.elementType,
37
- variant: _propTypes.default.oneOf(['default', 'highlighted', 'selected', 'disabled']),
37
+ variant: _propTypes.default.oneOf(['default', 'highlighted', 'selected', 'disabled', 'highlighted-disabled']),
38
38
  role: _propTypes.default.string,
39
39
  renderBeforeLabel: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]),
40
40
  renderAfterLabel: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]),
@@ -42,9 +42,10 @@ const propTypes = {
42
42
  afterLabelContentVAlign: _propTypes.default.oneOf(['start', 'center', 'end']),
43
43
  description: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]),
44
44
  descriptionRole: _propTypes.default.string,
45
+ href: _propTypes.default.string,
45
46
  elementRef: _propTypes.default.func,
46
47
  children: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func])
47
48
  };
48
49
  exports.propTypes = propTypes;
49
- const allowedProps = ['as', 'variant', 'role', 'renderBeforeLabel', 'renderAfterLabel', 'beforeLabelContentVAlign', 'afterLabelContentVAlign', 'description', 'descriptionRole', 'elementRef', 'children'];
50
+ const allowedProps = ['as', 'variant', 'role', 'renderBeforeLabel', 'renderAfterLabel', 'beforeLabelContentVAlign', 'afterLabelContentVAlign', 'description', 'descriptionRole', 'href', 'elementRef', 'children'];
50
51
  exports.allowedProps = allowedProps;
@@ -63,6 +63,12 @@ const generateStyle = (componentTheme, props) => {
63
63
  cursor: 'not-allowed',
64
64
  opacity: 0.5
65
65
  },
66
+ ['highlighted-disabled']: {
67
+ background: componentTheme.highlightedBackground,
68
+ color: componentTheme.highlightedLabelColor,
69
+ cursor: 'not-allowed',
70
+ opacity: 0.5
71
+ },
66
72
  default: {}
67
73
  };
68
74
 
@@ -86,6 +92,10 @@ const generateStyle = (componentTheme, props) => {
86
92
  }[vAlign];
87
93
  };
88
94
 
95
+ const linkStyles = {
96
+ textDecoration: 'none',
97
+ color: 'currentColor'
98
+ };
89
99
  const transition = 'background 200ms';
90
100
  return {
91
101
  item: {
@@ -137,7 +147,14 @@ const generateStyle = (componentTheme, props) => {
137
147
  ...(hasContentBeforeLabel && hasContentAfterLabel && {
138
148
  paddingInlineEnd: `calc(${componentTheme.iconPadding} * 2 + 1em)`,
139
149
  paddingInlineStart: `calc(${componentTheme.iconPadding} * 2 + 1em)`
140
- })
150
+ }),
151
+ // NOTE: needs separate groups for `:is()` and `:-webkit-any()` because of css selector group validation (see https://www.w3.org/TR/selectors-3/#grouping)
152
+ '&:is(a)': {
153
+ '&, &:link, &:visited, &:active, &:hover, &:focus': linkStyles
154
+ },
155
+ '&:-webkit-any(a)': {
156
+ '&, &:link, &:visited, &:active, &:hover, &:focus': linkStyles
157
+ }
141
158
  },
142
159
  content: {
143
160
  label: 'optionItem__content',
@@ -58,7 +58,7 @@ const generateComponentTheme = theme => {
58
58
  selectedBackground: colors === null || colors === void 0 ? void 0 : colors.backgroundDark,
59
59
  padding: `${spacing === null || spacing === void 0 ? void 0 : spacing.xSmall} ${spacing === null || spacing === void 0 ? void 0 : spacing.small}`,
60
60
  iconPadding: spacing === null || spacing === void 0 ? void 0 : spacing.small,
61
- nestedPadding: spacing === null || spacing === void 0 ? void 0 : spacing.medium,
61
+ nestedPadding: spacing === null || spacing === void 0 ? void 0 : spacing.small,
62
62
  beforeLabelContentVOffset: '0.625rem',
63
63
  afterLabelContentVOffset: '0.625rem',
64
64
  descriptionFontSize: typography.fontSizeSmall,
@@ -101,7 +101,7 @@ let Options = (_dec = (0, _uiReactUtils.withDeterministicId)(), _dec2 = (0, _emo
101
101
 
102
102
  if ((0, _uiReactUtils.matchComponentTypes)(child, ['Item', 'Separator'])) {
103
103
  return (0, _uiReactUtils.safeCloneElement)(child, {
104
- as: this.childAs
104
+ as: this.childAs || child.props.as
105
105
  });
106
106
  }
107
107
 
@@ -131,7 +131,7 @@ let Options = (_dec = (0, _uiReactUtils.withDeterministicId)(), _dec2 = (0, _emo
131
131
  margin: "none",
132
132
  padding: "none",
133
133
  background: "primary",
134
- "aria-labelledby": renderLabel ? this._labelId : void 0
134
+ "aria-labelledby": renderLabel ? this._labelId : this.props['aria-labelledby'] ? this.props['aria-labelledby'] : void 0
135
135
  }), this.renderChildren()));
136
136
  }
137
137
 
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.optionsThemeKeys = exports.optionsThemeGenerator = exports.default = void 0;
6
+ exports.optionsThemeGenerator = exports.default = void 0;
7
7
 
8
8
  /*
9
9
  * The MIT License (MIT)
@@ -28,20 +28,16 @@ exports.optionsThemeKeys = exports.optionsThemeGenerator = exports.default = voi
28
28
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
29
  * SOFTWARE.
30
30
  */
31
- const optionsThemeKeys = ['labelFontWeight', 'background', 'labelColor', 'labelPadding', 'nestedLabelPadding'];
31
+
32
32
  /**
33
33
  * Generates the theme object for the component from the theme and provided additional information
34
34
  * @param {Object} theme The actual theme object.
35
35
  * @return {Object} The final theme object with the overrides and component variables
36
36
  */
37
-
38
- exports.optionsThemeKeys = optionsThemeKeys;
39
-
40
37
  const generateComponentTheme = theme => {
41
38
  const colors = theme.colors,
42
39
  typography = theme.typography,
43
- spacing = theme.spacing; // TODO: if updated, update optionsThemeKeys array too
44
-
40
+ spacing = theme.spacing;
45
41
  const componentVariables = {
46
42
  labelFontWeight: typography === null || typography === void 0 ? void 0 : typography.fontWeightBold,
47
43
  background: colors === null || colors === void 0 ? void 0 : colors.backgroundLightest,
package/lib/index.js CHANGED
@@ -27,12 +27,6 @@ Object.defineProperty(exports, "optionsThemeGenerator", {
27
27
  return _theme.optionsThemeGenerator;
28
28
  }
29
29
  });
30
- Object.defineProperty(exports, "optionsThemeKeys", {
31
- enumerable: true,
32
- get: function () {
33
- return _theme.optionsThemeKeys;
34
- }
35
- });
36
30
 
37
31
  var _Options = require("./Options");
38
32
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-options",
3
- "version": "8.19.1-snapshot.8+8648faa3b",
3
+ "version": "8.20.1-snapshot.18+02b59d9da",
4
4
  "description": "A view-only component for composing interactive lists and menus.",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "module": "./es/index.js",
@@ -23,21 +23,21 @@
23
23
  },
24
24
  "license": "MIT",
25
25
  "devDependencies": {
26
- "@instructure/ui-babel-preset": "8.19.1-snapshot.8+8648faa3b",
27
- "@instructure/ui-color-utils": "8.19.1-snapshot.8+8648faa3b",
28
- "@instructure/ui-test-locator": "8.19.1-snapshot.8+8648faa3b",
29
- "@instructure/ui-test-utils": "8.19.1-snapshot.8+8648faa3b",
30
- "@instructure/ui-themes": "8.19.1-snapshot.8+8648faa3b"
26
+ "@instructure/ui-babel-preset": "8.20.1-snapshot.18+02b59d9da",
27
+ "@instructure/ui-color-utils": "8.20.1-snapshot.18+02b59d9da",
28
+ "@instructure/ui-test-locator": "8.20.1-snapshot.18+02b59d9da",
29
+ "@instructure/ui-test-utils": "8.20.1-snapshot.18+02b59d9da",
30
+ "@instructure/ui-themes": "8.20.1-snapshot.18+02b59d9da"
31
31
  },
32
32
  "dependencies": {
33
33
  "@babel/runtime": "^7.13.10",
34
- "@instructure/emotion": "8.19.1-snapshot.8+8648faa3b",
35
- "@instructure/shared-types": "8.19.1-snapshot.8+8648faa3b",
36
- "@instructure/ui-icons": "8.19.1-snapshot.8+8648faa3b",
37
- "@instructure/ui-prop-types": "8.19.1-snapshot.8+8648faa3b",
38
- "@instructure/ui-react-utils": "8.19.1-snapshot.8+8648faa3b",
39
- "@instructure/ui-testable": "8.19.1-snapshot.8+8648faa3b",
40
- "@instructure/ui-view": "8.19.1-snapshot.8+8648faa3b",
34
+ "@instructure/emotion": "8.20.1-snapshot.18+02b59d9da",
35
+ "@instructure/shared-types": "8.20.1-snapshot.18+02b59d9da",
36
+ "@instructure/ui-icons": "8.20.1-snapshot.18+02b59d9da",
37
+ "@instructure/ui-prop-types": "8.20.1-snapshot.18+02b59d9da",
38
+ "@instructure/ui-react-utils": "8.20.1-snapshot.18+02b59d9da",
39
+ "@instructure/ui-testable": "8.20.1-snapshot.18+02b59d9da",
40
+ "@instructure/ui-view": "8.20.1-snapshot.18+02b59d9da",
41
41
  "prop-types": "^15"
42
42
  },
43
43
  "peerDependencies": {
@@ -47,5 +47,5 @@
47
47
  "access": "public"
48
48
  },
49
49
  "sideEffects": false,
50
- "gitHead": "8648faa3b9f006a729a4d13195dd9c28e23d1335"
50
+ "gitHead": "02b59d9da99cac7963dbb25882a9b01057297021"
51
51
  }
@@ -31,6 +31,7 @@ export default {
31
31
  propValues: {
32
32
  renderAfterLabel: [null, IconArrowOpenEndSolid],
33
33
  renderBeforeLabel: [null, IconCheckSolid],
34
+ href: [undefined, '/hello'],
34
35
  description: [
35
36
  null,
36
37
  'Curabitur fringilla, urna ut efficitur molestie, nibh lacus tincidunt elit, ut tempor ipsum nunc sit amet massa. Integer sit amet ante vitae lectus gravida pulvinar.'
@@ -76,6 +77,15 @@ export default {
76
77
  }
77
78
  }
78
79
 
80
+ if (
81
+ props.href &&
82
+ (props.beforeLabelContentVAlign !== 'center' ||
83
+ props.afterLabelContentVAlign !== 'center' ||
84
+ props.description)
85
+ ) {
86
+ return true
87
+ }
88
+
79
89
  return false
80
90
  }
81
91
  } as StoryConfig<OptionsItemProps>
@@ -28,7 +28,8 @@ import { Component } from 'react'
28
28
  import {
29
29
  omitProps,
30
30
  getElementType,
31
- callRenderProp
31
+ callRenderProp,
32
+ withDeterministicId
32
33
  } from '@instructure/ui-react-utils'
33
34
  import { testable } from '@instructure/ui-testable'
34
35
 
@@ -46,6 +47,7 @@ id: Options.Item
46
47
  ---
47
48
  @tsProps
48
49
  **/
50
+ @withDeterministicId()
49
51
  @withStyle(generateStyles, generateComponentTheme)
50
52
  @testable()
51
53
  class Item extends Component<OptionsItemProps> {
@@ -65,6 +67,14 @@ class Item extends Component<OptionsItemProps> {
65
67
 
66
68
  ref: Element | null = null
67
69
 
70
+ private readonly _descriptionId: string
71
+
72
+ constructor(props: OptionsItemProps) {
73
+ super(props)
74
+
75
+ this._descriptionId = props.deterministicId!('OptionsItem-description')
76
+ }
77
+
68
78
  componentDidMount() {
69
79
  this.props.makeStyles?.()
70
80
  }
@@ -102,6 +112,7 @@ class Item extends Component<OptionsItemProps> {
102
112
  render() {
103
113
  const {
104
114
  as,
115
+ href,
105
116
  role,
106
117
  styles,
107
118
  description,
@@ -113,6 +124,9 @@ class Item extends Component<OptionsItemProps> {
113
124
  } = this.props
114
125
 
115
126
  const ElementType = getElementType(Item, this.props, () => as!)
127
+
128
+ const InnerElementType = href ? 'a' : 'span'
129
+
116
130
  const passthroughProps = omitProps(this.props, Item.allowedProps)
117
131
 
118
132
  const childrenContent = callRenderProp(children)
@@ -131,14 +145,27 @@ class Item extends Component<OptionsItemProps> {
131
145
  }
132
146
  }}
133
147
  >
134
- <span {...passthroughProps} css={styles?.container} role={role}>
148
+ <InnerElementType
149
+ {...passthroughProps}
150
+ css={styles?.container}
151
+ role={href ? undefined : role}
152
+ href={href}
153
+ aria-describedby={
154
+ this.props['aria-describedby'] ||
155
+ (descriptionContent ? this._descriptionId : undefined)
156
+ }
157
+ >
135
158
  {childrenContent}
136
159
  {descriptionContent && (
137
- <span css={styles?.description} role={descriptionRole}>
160
+ <span
161
+ css={styles?.description}
162
+ role={descriptionRole}
163
+ id={this._descriptionId}
164
+ >
138
165
  {descriptionContent}
139
166
  </span>
140
167
  )}
141
- </span>
168
+ </InnerElementType>
142
169
  {renderBeforeLabel &&
143
170
  this.renderContent(renderBeforeLabel, styles?.contentBefore)}
144
171
  {renderAfterLabel &&