@instructure/ui-menu 11.7.4-snapshot-135 → 11.7.4-snapshot-142

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,7 +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
- ## [11.7.4-snapshot-135](https://github.com/instructure/instructure-ui/compare/v11.7.3...v11.7.4-snapshot-135) (2026-07-24)
6
+ ## [11.7.4-snapshot-142](https://github.com/instructure/instructure-ui/compare/v11.7.3...v11.7.4-snapshot-142) (2026-07-24)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **many:** do not allow javascript: and data: hrefs ([4a0ac03](https://github.com/instructure/instructure-ui/commit/4a0ac038c6a4102646e04d27c1c3251f97367822))
7
12
 
8
13
 
9
14
  ### Features
@@ -27,7 +27,7 @@ import { Component } from 'react';
27
27
  import keycode from 'keycode';
28
28
  import { IconCheckSolid, IconArrowOpenEndSolid } from '@instructure/ui-icons';
29
29
  import { omitProps, getElementType, withDeterministicId, callRenderProp } from '@instructure/ui-react-utils';
30
- import { createChainedFunction } from '@instructure/ui-utils';
30
+ import { createChainedFunction, safeLinkProps } from '@instructure/ui-utils';
31
31
  import { isActiveElement, findDOMNode } from '@instructure/ui-dom-utils';
32
32
  import { withStyle } from '@instructure/emotion';
33
33
  import { MenuContext } from '../../../utils/v1/MenuContext.js';
@@ -194,17 +194,28 @@ let MenuItem = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
194
194
  onKeyDown,
195
195
  onKeyUp,
196
196
  type,
197
- href,
197
+ href: rawHref,
198
198
  target
199
199
  } = this.props;
200
200
  const props = omitProps(this.props, MenuItem.allowedProps);
201
201
  const ElementType = this.elementType;
202
+ const {
203
+ href,
204
+ rel
205
+ } = safeLinkProps({
206
+ tag: typeof ElementType === 'string' ? ElementType : 'a',
207
+ attr: 'href',
208
+ href: rawHref,
209
+ target,
210
+ rel: this.props.rel
211
+ });
202
212
  return _jsx(ElementType, {
203
213
  tabIndex: -1 // note: tabIndex can be overridden by Menu or MenuItemGroup components
204
214
  ,
205
215
  ...props,
206
216
  href: href,
207
217
  target: target,
218
+ rel: rel,
208
219
  role: this.role,
209
220
  "aria-labelledby": this.labelId,
210
221
  "aria-disabled": disabled ? 'true' : undefined,
@@ -27,7 +27,7 @@ import { Component } from 'react';
27
27
  import keycode from 'keycode';
28
28
  import { CheckInstUIIcon, ChevronRightInstUIIcon } from '@instructure/ui-icons';
29
29
  import { omitProps, getElementType, withDeterministicId, callRenderProp } from '@instructure/ui-react-utils';
30
- import { createChainedFunction } from '@instructure/ui-utils';
30
+ import { createChainedFunction, safeLinkProps } from '@instructure/ui-utils';
31
31
  import { isActiveElement, findDOMNode } from '@instructure/ui-dom-utils';
32
32
  import { withStyleNew } from '@instructure/emotion';
33
33
  import { MenuContext } from '../../../utils/v1/MenuContext.js';
@@ -230,17 +230,28 @@ let MenuItem = (_dec = withDeterministicId(), _dec2 = withStyleNew(generateStyle
230
230
  onFocus,
231
231
  onBlur,
232
232
  type,
233
- href,
233
+ href: rawHref,
234
234
  target
235
235
  } = this.props;
236
236
  const props = omitProps(this.props, MenuItem.allowedProps);
237
237
  const ElementType = this.elementType;
238
+ const {
239
+ href,
240
+ rel
241
+ } = safeLinkProps({
242
+ tag: typeof ElementType === 'string' ? ElementType : 'a',
243
+ attr: 'href',
244
+ href: rawHref,
245
+ target,
246
+ rel: this.props.rel
247
+ });
238
248
  return _jsx(ElementType, {
239
249
  tabIndex: -1 // note: tabIndex can be overridden by Menu or MenuItemGroup components
240
250
  ,
241
251
  ...props,
242
252
  href: href,
243
253
  target: target,
254
+ rel: rel,
244
255
  role: this.role,
245
256
  "aria-labelledby": this.labelId,
246
257
  "aria-disabled": disabled ? 'true' : undefined,
@@ -14,6 +14,7 @@ var _getElementType = require("@instructure/ui-react-utils/lib/getElementType.js
14
14
  var _withDeterministicId = require("@instructure/ui-react-utils/lib/DeterministicIdContext/withDeterministicId.js");
15
15
  var _callRenderProp = require("@instructure/ui-react-utils/lib/callRenderProp.js");
16
16
  var _createChainedFunction = require("@instructure/ui-utils/lib/createChainedFunction.js");
17
+ var _safeLinkProps = require("@instructure/ui-utils/lib/safeLinkProps.js");
17
18
  var _isActiveElement = require("@instructure/ui-dom-utils/lib/isActiveElement.js");
18
19
  var _findDOMNode = require("@instructure/ui-dom-utils/lib/findDOMNode.js");
19
20
  var _emotion = require("@instructure/emotion");
@@ -205,17 +206,28 @@ let MenuItem = exports.MenuItem = (_dec = (0, _withDeterministicId.withDetermini
205
206
  onKeyDown,
206
207
  onKeyUp,
207
208
  type,
208
- href,
209
+ href: rawHref,
209
210
  target
210
211
  } = this.props;
211
212
  const props = (0, _omitProps.omitProps)(this.props, MenuItem.allowedProps);
212
213
  const ElementType = this.elementType;
214
+ const {
215
+ href,
216
+ rel
217
+ } = (0, _safeLinkProps.safeLinkProps)({
218
+ tag: typeof ElementType === 'string' ? ElementType : 'a',
219
+ attr: 'href',
220
+ href: rawHref,
221
+ target,
222
+ rel: this.props.rel
223
+ });
213
224
  return (0, _jsxRuntime.jsx)(ElementType, {
214
225
  tabIndex: -1 // note: tabIndex can be overridden by Menu or MenuItemGroup components
215
226
  ,
216
227
  ...props,
217
228
  href: href,
218
229
  target: target,
230
+ rel: rel,
219
231
  role: this.role,
220
232
  "aria-labelledby": this.labelId,
221
233
  "aria-disabled": disabled ? 'true' : undefined,
@@ -13,6 +13,7 @@ var _getElementType = require("@instructure/ui-react-utils/lib/getElementType.js
13
13
  var _withDeterministicId = require("@instructure/ui-react-utils/lib/DeterministicIdContext/withDeterministicId.js");
14
14
  var _callRenderProp = require("@instructure/ui-react-utils/lib/callRenderProp.js");
15
15
  var _createChainedFunction = require("@instructure/ui-utils/lib/createChainedFunction.js");
16
+ var _safeLinkProps = require("@instructure/ui-utils/lib/safeLinkProps.js");
16
17
  var _isActiveElement = require("@instructure/ui-dom-utils/lib/isActiveElement.js");
17
18
  var _findDOMNode = require("@instructure/ui-dom-utils/lib/findDOMNode.js");
18
19
  var _emotion = require("@instructure/emotion");
@@ -240,17 +241,28 @@ let MenuItem = exports.MenuItem = (_dec = (0, _withDeterministicId.withDetermini
240
241
  onFocus,
241
242
  onBlur,
242
243
  type,
243
- href,
244
+ href: rawHref,
244
245
  target
245
246
  } = this.props;
246
247
  const props = (0, _omitProps.omitProps)(this.props, MenuItem.allowedProps);
247
248
  const ElementType = this.elementType;
249
+ const {
250
+ href,
251
+ rel
252
+ } = (0, _safeLinkProps.safeLinkProps)({
253
+ tag: typeof ElementType === 'string' ? ElementType : 'a',
254
+ attr: 'href',
255
+ href: rawHref,
256
+ target,
257
+ rel: this.props.rel
258
+ });
248
259
  return (0, _jsxRuntime.jsx)(ElementType, {
249
260
  tabIndex: -1 // note: tabIndex can be overridden by Menu or MenuItemGroup components
250
261
  ,
251
262
  ...props,
252
263
  href: href,
253
264
  target: target,
265
+ rel: rel,
254
266
  role: this.role,
255
267
  "aria-labelledby": this.labelId,
256
268
  "aria-disabled": disabled ? 'true' : undefined,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-menu",
3
- "version": "11.7.4-snapshot-135",
3
+ "version": "11.7.4-snapshot-142",
4
4
  "description": "A dropdown menu component",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "module": "./es/index.js",
@@ -16,27 +16,27 @@
16
16
  "dependencies": {
17
17
  "@babel/runtime": "^7.29.7",
18
18
  "keycode": "^2",
19
- "@instructure/console": "11.7.4-snapshot-135",
20
- "@instructure/emotion": "11.7.4-snapshot-135",
21
- "@instructure/shared-types": "11.7.4-snapshot-135",
22
- "@instructure/ui-a11y-utils": "11.7.4-snapshot-135",
23
- "@instructure/ui-dom-utils": "11.7.4-snapshot-135",
24
- "@instructure/ui-icons": "11.7.4-snapshot-135",
25
- "@instructure/ui-position": "11.7.4-snapshot-135",
26
- "@instructure/ui-popover": "11.7.4-snapshot-135",
27
- "@instructure/ui-themes": "11.7.4-snapshot-135",
28
- "@instructure/ui-react-utils": "11.7.4-snapshot-135",
29
- "@instructure/ui-utils": "11.7.4-snapshot-135",
30
- "@instructure/ui-view": "11.7.4-snapshot-135"
19
+ "@instructure/console": "11.7.4-snapshot-142",
20
+ "@instructure/shared-types": "11.7.4-snapshot-142",
21
+ "@instructure/emotion": "11.7.4-snapshot-142",
22
+ "@instructure/ui-a11y-utils": "11.7.4-snapshot-142",
23
+ "@instructure/ui-dom-utils": "11.7.4-snapshot-142",
24
+ "@instructure/ui-icons": "11.7.4-snapshot-142",
25
+ "@instructure/ui-popover": "11.7.4-snapshot-142",
26
+ "@instructure/ui-position": "11.7.4-snapshot-142",
27
+ "@instructure/ui-themes": "11.7.4-snapshot-142",
28
+ "@instructure/ui-utils": "11.7.4-snapshot-142",
29
+ "@instructure/ui-react-utils": "11.7.4-snapshot-142",
30
+ "@instructure/ui-view": "11.7.4-snapshot-142"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@testing-library/jest-dom": "^6.9.1",
34
34
  "@testing-library/react": "16.3.2",
35
35
  "@testing-library/user-event": "^14.6.1",
36
36
  "vitest": "^4.1.9",
37
- "@instructure/ui-axe-check": "11.7.4-snapshot-135",
38
- "@instructure/ui-babel-preset": "11.7.4-snapshot-135",
39
- "@instructure/ui-color-utils": "11.7.4-snapshot-135"
37
+ "@instructure/ui-babel-preset": "11.7.4-snapshot-142",
38
+ "@instructure/ui-color-utils": "11.7.4-snapshot-142",
39
+ "@instructure/ui-axe-check": "11.7.4-snapshot-142"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "react": ">=18 <=19"
@@ -32,7 +32,7 @@ import {
32
32
  withDeterministicId,
33
33
  callRenderProp
34
34
  } from '@instructure/ui-react-utils'
35
- import { createChainedFunction } from '@instructure/ui-utils'
35
+ import { createChainedFunction, safeLinkProps } from '@instructure/ui-utils'
36
36
  import { isActiveElement, findDOMNode } from '@instructure/ui-dom-utils'
37
37
  import { withStyle } from '@instructure/emotion'
38
38
 
@@ -235,18 +235,34 @@ class MenuItem extends Component<MenuItemProps, MenuItemState> {
235
235
  }
236
236
 
237
237
  render() {
238
- const { disabled, controls, onKeyDown, onKeyUp, type, href, target } =
239
- this.props
238
+ const {
239
+ disabled,
240
+ controls,
241
+ onKeyDown,
242
+ onKeyUp,
243
+ type,
244
+ href: rawHref,
245
+ target
246
+ } = this.props
240
247
 
241
248
  const props = omitProps(this.props, MenuItem.allowedProps)
242
249
  const ElementType = this.elementType
243
250
 
251
+ const { href, rel } = safeLinkProps({
252
+ tag: typeof ElementType === 'string' ? ElementType : 'a',
253
+ attr: 'href',
254
+ href: rawHref,
255
+ target,
256
+ rel: (this.props as { rel?: string }).rel
257
+ })
258
+
244
259
  return (
245
260
  <ElementType
246
261
  tabIndex={-1} // note: tabIndex can be overridden by Menu or MenuItemGroup components
247
262
  {...props}
248
263
  href={href}
249
264
  target={target}
265
+ rel={rel}
250
266
  role={this.role}
251
267
  aria-labelledby={this.labelId}
252
268
  aria-disabled={disabled ? 'true' : undefined}
@@ -32,7 +32,7 @@ import {
32
32
  withDeterministicId,
33
33
  callRenderProp
34
34
  } from '@instructure/ui-react-utils'
35
- import { createChainedFunction } from '@instructure/ui-utils'
35
+ import { createChainedFunction, safeLinkProps } from '@instructure/ui-utils'
36
36
  import { isActiveElement, findDOMNode } from '@instructure/ui-dom-utils'
37
37
  import { withStyleNew } from '@instructure/emotion'
38
38
 
@@ -265,12 +265,19 @@ class MenuItem extends Component<MenuItemProps, MenuItemState> {
265
265
  onFocus,
266
266
  onBlur,
267
267
  type,
268
- href,
268
+ href: rawHref,
269
269
  target
270
270
  } = this.props
271
271
 
272
272
  const props = omitProps(this.props, MenuItem.allowedProps)
273
273
  const ElementType = this.elementType
274
+ const { href, rel } = safeLinkProps({
275
+ tag: typeof ElementType === 'string' ? ElementType : 'a',
276
+ attr: 'href',
277
+ href: rawHref,
278
+ target,
279
+ rel: (this.props as { rel?: string }).rel
280
+ })
274
281
 
275
282
  return (
276
283
  <ElementType
@@ -278,6 +285,7 @@ class MenuItem extends Component<MenuItemProps, MenuItemState> {
278
285
  {...props}
279
286
  href={href}
280
287
  target={target}
288
+ rel={rel}
281
289
  role={this.role}
282
290
  aria-labelledby={this.labelId}
283
291
  aria-disabled={disabled ? 'true' : undefined}