@instructure/ui-source-code-editor 10.26.1-snapshot-2 → 10.26.2

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,30 +3,17 @@
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
- ## [10.26.1-snapshot-2](https://github.com/instructure/instructure-ui/compare/v10.26.0...v10.26.1-snapshot-2) (2025-10-06)
6
+ ## [10.26.2](https://github.com/instructure/instructure-ui/compare/v10.26.1...v10.26.2) (2025-10-13)
7
7
 
8
+ **Note:** Version bump only for package @instructure/ui-source-code-editor
8
9
 
9
- ### Features
10
10
 
11
- * **many:** instUI v11 release ([36f5438](https://github.com/instructure/instructure-ui/commit/36f54382669186227ba24798bbf7201ef2f5cd4c))
12
11
 
13
12
 
14
- ### BREAKING CHANGES
15
13
 
16
- * **many:** InstUI v11 contains the following breaking changes:
17
- - React 16 and 17 are no longer supported
18
- - remove `PropTypes` from all packages
19
- - remove `CodeEditor` component
20
- - remove `@instui/theme-registry` package
21
- - remove `@testable`, `@experimental`, `@hack` decorators
22
- - InstUISettingsProvider's `as` prop is removed
23
- - `canvas.use()`, `canvasHighContrast.use()` functions are removed
24
- - `canvasThemeLocal`, `canvasHighContrastThemeLocal` are removed
25
- - `variables` field on theme objects are removed
26
- - remove deprecated props from Table: Row's `isStacked`, Body's
27
- `isStacked`, `hover`, and `headers`
28
- - `Table`'s `caption` prop is now required
29
- - `ui-dom-utils`'s `getComputedStyle` can now return `undefined`
14
+ ## [10.26.1](https://github.com/instructure/instructure-ui/compare/v10.26.0...v10.26.1) (2025-10-06)
15
+
16
+ **Note:** Version bump only for package @instructure/ui-source-code-editor
30
17
 
31
18
 
32
19
 
@@ -24,12 +24,12 @@ var _IconSearchLine, _IconArrowOpenDownLin, _IconArrowOpenUpLine;
24
24
  * SOFTWARE.
25
25
  */
26
26
 
27
- import { useState } from 'react';
27
+ import { version, useState } from 'react';
28
28
  import { setSearchQuery, search, findNext, findPrevious, SearchQuery, closeSearchPanel } from '@codemirror/search';
29
29
  import { TextInput } from '@instructure/ui-text-input';
30
30
  import { IconButton } from '@instructure/ui-buttons';
31
31
  import { IconArrowOpenDownLine, IconArrowOpenUpLine, IconSearchLine } from '@instructure/ui-icons';
32
- import { createRoot } from 'react-dom/client';
32
+ import ReactDOM from 'react-dom';
33
33
  import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
34
34
  function SearchPanel({
35
35
  view,
@@ -103,13 +103,27 @@ function SearchPanel({
103
103
  export default function customSearch(searchConfig) {
104
104
  return searchConfig ? search({
105
105
  createPanel: view => {
106
+ var _SearchPanel;
106
107
  const dom = document.createElement('div');
107
108
  dom.style.padding = '8px';
108
- const root = createRoot(dom);
109
- root.render(_jsx(SearchPanel, {
110
- view: view,
111
- searchConfig: searchConfig
112
- }));
109
+ const reactVersionMajor = Number(version.split('.')[0]);
110
+ if (reactVersionMajor >= 18) {
111
+ const module = 'react-dom/client';
112
+ // webpack tries to evaluate imports compile time which would lead to an error on older react versions
113
+ // Vite errors out during build in React v16/17
114
+ import(/* webpackIgnore: true */ /* @vite-ignore */module).then(r => {
115
+ const root = r.createRoot(dom);
116
+ root.render(_SearchPanel || (_SearchPanel = _jsx(SearchPanel, {
117
+ view: view,
118
+ searchConfig: searchConfig
119
+ })));
120
+ }).catch(e => {});
121
+ } else {
122
+ ReactDOM.render(_jsx(SearchPanel, {
123
+ view: view,
124
+ searchConfig: searchConfig
125
+ }), dom);
126
+ }
113
127
  return {
114
128
  dom
115
129
  };
@@ -1,6 +1,6 @@
1
1
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
2
2
  const _excluded = ["label", "styles"];
3
- var _dec, _dec2, _dec3, _class, _SourceCodeEditor;
3
+ var _dec, _dec2, _dec3, _dec4, _class, _SourceCodeEditor;
4
4
  /*
5
5
  * The MIT License (MIT)
6
6
  *
@@ -43,6 +43,7 @@ import { shell } from '@codemirror/legacy-modes/mode/shell';
43
43
  import { yaml } from '@codemirror/legacy-modes/mode/yaml';
44
44
  // import { oneDarkTheme, oneDarkHighlightStyle } from '@codemirror/theme-one-dark'
45
45
 
46
+ import { testable } from '@instructure/ui-testable';
46
47
  import { omitProps, passthroughProps, withDeterministicId } from '@instructure/ui-react-utils';
47
48
  import { requestAnimationFrame } from '@instructure/ui-dom-utils';
48
49
  import { ScreenReaderContent } from '@instructure/ui-a11y-content';
@@ -52,14 +53,14 @@ import customSearch from './SearchPanel';
52
53
  import generateStyle from './styles';
53
54
  import generateComponentTheme from './theme';
54
55
  import { rtlHorizontalArrowKeymap } from './customKeybinding';
55
- import { allowedProps } from './props';
56
+ import { propTypes, allowedProps } from './props';
56
57
  import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
57
58
  /**
58
59
  ---
59
60
  category: components
60
61
  ---
61
62
  **/
62
- let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, generateComponentTheme), _dec3 = textDirectionContextConsumer(), _dec(_class = _dec2(_class = _dec3(_class = (_SourceCodeEditor = class SourceCodeEditor extends Component {
63
+ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, generateComponentTheme), _dec3 = textDirectionContextConsumer(), _dec4 = testable(), _dec(_class = _dec2(_class = _dec3(_class = _dec4(_class = (_SourceCodeEditor = class SourceCodeEditor extends Component {
63
64
  addAnimationFrame(callback) {
64
65
  if (typeof callback === 'function') {
65
66
  this._raf.push(requestAnimationFrame(callback));
@@ -499,7 +500,6 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
499
500
  styles = _this$props6.styles,
500
501
  restProps = _objectWithoutProperties(_this$props6, _excluded);
501
502
  return _jsx("div", {
502
- "data-cid": "SourceCodeEditor",
503
503
  ref: this.handleRef,
504
504
  css: styles === null || styles === void 0 ? void 0 : styles.codeEditor,
505
505
  ...passthroughProps(omitProps(restProps, SourceCodeEditor.allowedProps)),
@@ -515,7 +515,7 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
515
515
  })
516
516
  });
517
517
  }
518
- }, _SourceCodeEditor.displayName = "SourceCodeEditor", _SourceCodeEditor.componentId = 'SourceCodeEditor', _SourceCodeEditor.allowedProps = allowedProps, _SourceCodeEditor.defaultProps = {
518
+ }, _SourceCodeEditor.displayName = "SourceCodeEditor", _SourceCodeEditor.componentId = 'SourceCodeEditor', _SourceCodeEditor.propTypes = propTypes, _SourceCodeEditor.allowedProps = allowedProps, _SourceCodeEditor.defaultProps = {
519
519
  language: 'jsx',
520
520
  readOnly: false,
521
521
  editable: true,
@@ -531,6 +531,6 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
531
531
  indentWithTab: false,
532
532
  defaultValue: '',
533
533
  height: 'auto'
534
- }, _SourceCodeEditor)) || _class) || _class) || _class);
534
+ }, _SourceCodeEditor)) || _class) || _class) || _class) || _class);
535
535
  export default SourceCodeEditor;
536
536
  export { SourceCodeEditor };
@@ -22,7 +22,39 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
+ import PropTypes from 'prop-types';
26
+ import { controllable } from '@instructure/ui-prop-types';
27
+ const propTypes = {
28
+ label: PropTypes.string.isRequired,
29
+ language: PropTypes.oneOf(['sh', 'js', 'json', 'javascript', 'jsx', 'shell', 'css', 'html', 'markdown', 'yaml', 'yml', 'bash']),
30
+ readOnly: PropTypes.bool,
31
+ editable: PropTypes.bool,
32
+ lineNumbers: PropTypes.bool,
33
+ foldGutter: PropTypes.bool,
34
+ highlightActiveLineGutter: PropTypes.bool,
35
+ highlightActiveLine: PropTypes.bool,
36
+ lineWrapping: PropTypes.bool,
37
+ autofocus: PropTypes.bool,
38
+ spellcheck: PropTypes.bool,
39
+ direction: PropTypes.oneOf(['ltr', 'rtl']),
40
+ rtlMoveVisually: PropTypes.bool,
41
+ indentOnLoad: PropTypes.bool,
42
+ indentWithTab: PropTypes.bool,
43
+ indentUnit: PropTypes.string,
44
+ defaultValue: PropTypes.string,
45
+ value: controllable(PropTypes.string, 'onChange', 'defaultValue'),
46
+ onChange: PropTypes.func,
47
+ onFocus: PropTypes.func,
48
+ onBlur: PropTypes.func,
49
+ attachment: PropTypes.oneOf(['bottom', 'top']),
50
+ height: PropTypes.string,
51
+ width: PropTypes.string,
52
+ // darkTheme: PropTypes.bool,
53
+ elementRef: PropTypes.func,
54
+ containerRef: PropTypes.func,
55
+ searchConfig: PropTypes.object
56
+ };
25
57
  const allowedProps = ['label', 'language', 'readOnly', 'editable', 'lineNumbers', 'foldGutter', 'highlightActiveLineGutter', 'highlightActiveLine', 'lineWrapping', 'autofocus', 'spellcheck', 'direction', 'rtlMoveVisually', 'indentOnLoad', 'indentWithTab', 'indentUnit', 'defaultValue', 'value', 'onChange', 'onFocus', 'onBlur', 'attachment', 'height', 'width',
26
58
  // 'darkTheme',
27
59
  'elementRef', 'containerRef', 'searchConfig'];
28
- export { allowedProps };
60
+ export { propTypes, allowedProps };
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = customSearch;
8
+ var _interopRequireWildcard2 = _interopRequireDefault(require("@babel/runtime/helpers/interopRequireWildcard"));
8
9
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
10
  var _react = require("react");
10
11
  var _search = require("@codemirror/search");
@@ -13,7 +14,7 @@ var _IconButton = require("@instructure/ui-buttons/lib/IconButton");
13
14
  var _IconArrowOpenDownLine = require("@instructure/ui-icons/lib/IconArrowOpenDownLine.js");
14
15
  var _IconArrowOpenUpLine2 = require("@instructure/ui-icons/lib/IconArrowOpenUpLine.js");
15
16
  var _IconSearchLine2 = require("@instructure/ui-icons/lib/IconSearchLine.js");
16
- var _client = require("react-dom/client");
17
+ var _reactDom = _interopRequireDefault(require("react-dom"));
17
18
  var _jsxRuntime = require("@emotion/react/jsx-runtime");
18
19
  var _IconSearchLine, _IconArrowOpenDownLin, _IconArrowOpenUpLine;
19
20
  /*
@@ -111,13 +112,27 @@ function SearchPanel({
111
112
  function customSearch(searchConfig) {
112
113
  return searchConfig ? (0, _search.search)({
113
114
  createPanel: view => {
115
+ var _SearchPanel;
114
116
  const dom = document.createElement('div');
115
117
  dom.style.padding = '8px';
116
- const root = (0, _client.createRoot)(dom);
117
- root.render((0, _jsxRuntime.jsx)(SearchPanel, {
118
- view: view,
119
- searchConfig: searchConfig
120
- }));
118
+ const reactVersionMajor = Number(_react.version.split('.')[0]);
119
+ if (reactVersionMajor >= 18) {
120
+ const module = 'react-dom/client';
121
+ // webpack tries to evaluate imports compile time which would lead to an error on older react versions
122
+ // Vite errors out during build in React v16/17
123
+ (specifier => new Promise(r => r(`${specifier}`)).then(s => (0, _interopRequireWildcard2.default)(require(s))))(/* webpackIgnore: true */ /* @vite-ignore */module).then(r => {
124
+ const root = r.createRoot(dom);
125
+ root.render(_SearchPanel || (_SearchPanel = (0, _jsxRuntime.jsx)(SearchPanel, {
126
+ view: view,
127
+ searchConfig: searchConfig
128
+ })));
129
+ }).catch(e => {});
130
+ } else {
131
+ _reactDom.default.render((0, _jsxRuntime.jsx)(SearchPanel, {
132
+ view: view,
133
+ searchConfig: searchConfig
134
+ }), dom);
135
+ }
121
136
  return {
122
137
  dom
123
138
  };
@@ -22,6 +22,7 @@ var _langMarkdown = require("@codemirror/lang-markdown");
22
22
  var _langJson = require("@codemirror/lang-json");
23
23
  var _shell = require("@codemirror/legacy-modes/mode/shell");
24
24
  var _yaml = require("@codemirror/legacy-modes/mode/yaml");
25
+ var _testable = require("@instructure/ui-testable/lib/testable.js");
25
26
  var _omitProps = require("@instructure/ui-react-utils/lib/omitProps.js");
26
27
  var _passthroughProps = require("@instructure/ui-react-utils/lib/passthroughProps.js");
27
28
  var _withDeterministicId = require("@instructure/ui-react-utils/lib/DeterministicIdContext/withDeterministicId.js");
@@ -36,7 +37,7 @@ var _customKeybinding = require("./customKeybinding");
36
37
  var _props = require("./props");
37
38
  var _jsxRuntime = require("@emotion/react/jsx-runtime");
38
39
  const _excluded = ["label", "styles"];
39
- var _dec, _dec2, _dec3, _class, _SourceCodeEditor;
40
+ var _dec, _dec2, _dec3, _dec4, _class, _SourceCodeEditor;
40
41
  /*
41
42
  * The MIT License (MIT)
42
43
  *
@@ -66,7 +67,7 @@ var _dec, _dec2, _dec3, _class, _SourceCodeEditor;
66
67
  category: components
67
68
  ---
68
69
  **/
69
- let SourceCodeEditor = exports.SourceCodeEditor = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 = (0, _emotion.withStyle)(_styles.default, _theme.default), _dec3 = (0, _textDirectionContextConsumer.textDirectionContextConsumer)(), _dec(_class = _dec2(_class = _dec3(_class = (_SourceCodeEditor = class SourceCodeEditor extends _react.Component {
70
+ let SourceCodeEditor = exports.SourceCodeEditor = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 = (0, _emotion.withStyle)(_styles.default, _theme.default), _dec3 = (0, _textDirectionContextConsumer.textDirectionContextConsumer)(), _dec4 = (0, _testable.testable)(), _dec(_class = _dec2(_class = _dec3(_class = _dec4(_class = (_SourceCodeEditor = class SourceCodeEditor extends _react.Component {
70
71
  addAnimationFrame(callback) {
71
72
  if (typeof callback === 'function') {
72
73
  this._raf.push((0, _requestAnimationFrame.requestAnimationFrame)(callback));
@@ -506,7 +507,6 @@ let SourceCodeEditor = exports.SourceCodeEditor = (_dec = (0, _withDeterministic
506
507
  styles = _this$props6.styles,
507
508
  restProps = (0, _objectWithoutProperties2.default)(_this$props6, _excluded);
508
509
  return (0, _jsxRuntime.jsx)("div", {
509
- "data-cid": "SourceCodeEditor",
510
510
  ref: this.handleRef,
511
511
  css: styles === null || styles === void 0 ? void 0 : styles.codeEditor,
512
512
  ...(0, _passthroughProps.passthroughProps)((0, _omitProps.omitProps)(restProps, SourceCodeEditor.allowedProps)),
@@ -522,7 +522,7 @@ let SourceCodeEditor = exports.SourceCodeEditor = (_dec = (0, _withDeterministic
522
522
  })
523
523
  });
524
524
  }
525
- }, _SourceCodeEditor.displayName = "SourceCodeEditor", _SourceCodeEditor.componentId = 'SourceCodeEditor', _SourceCodeEditor.allowedProps = _props.allowedProps, _SourceCodeEditor.defaultProps = {
525
+ }, _SourceCodeEditor.displayName = "SourceCodeEditor", _SourceCodeEditor.componentId = 'SourceCodeEditor', _SourceCodeEditor.propTypes = _props.propTypes, _SourceCodeEditor.allowedProps = _props.allowedProps, _SourceCodeEditor.defaultProps = {
526
526
  language: 'jsx',
527
527
  readOnly: false,
528
528
  editable: true,
@@ -538,5 +538,5 @@ let SourceCodeEditor = exports.SourceCodeEditor = (_dec = (0, _withDeterministic
538
538
  indentWithTab: false,
539
539
  defaultValue: '',
540
540
  height: 'auto'
541
- }, _SourceCodeEditor)) || _class) || _class) || _class);
541
+ }, _SourceCodeEditor)) || _class) || _class) || _class) || _class);
542
542
  var _default = exports.default = SourceCodeEditor;
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
- exports.allowedProps = void 0;
7
+ exports.propTypes = exports.allowedProps = void 0;
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+ var _controllable = require("@instructure/ui-prop-types/lib/controllable.js");
7
10
  /*
8
11
  * The MIT License (MIT)
9
12
  *
@@ -28,6 +31,36 @@ exports.allowedProps = void 0;
28
31
  * SOFTWARE.
29
32
  */
30
33
 
34
+ const propTypes = exports.propTypes = {
35
+ label: _propTypes.default.string.isRequired,
36
+ language: _propTypes.default.oneOf(['sh', 'js', 'json', 'javascript', 'jsx', 'shell', 'css', 'html', 'markdown', 'yaml', 'yml', 'bash']),
37
+ readOnly: _propTypes.default.bool,
38
+ editable: _propTypes.default.bool,
39
+ lineNumbers: _propTypes.default.bool,
40
+ foldGutter: _propTypes.default.bool,
41
+ highlightActiveLineGutter: _propTypes.default.bool,
42
+ highlightActiveLine: _propTypes.default.bool,
43
+ lineWrapping: _propTypes.default.bool,
44
+ autofocus: _propTypes.default.bool,
45
+ spellcheck: _propTypes.default.bool,
46
+ direction: _propTypes.default.oneOf(['ltr', 'rtl']),
47
+ rtlMoveVisually: _propTypes.default.bool,
48
+ indentOnLoad: _propTypes.default.bool,
49
+ indentWithTab: _propTypes.default.bool,
50
+ indentUnit: _propTypes.default.string,
51
+ defaultValue: _propTypes.default.string,
52
+ value: (0, _controllable.controllable)(_propTypes.default.string, 'onChange', 'defaultValue'),
53
+ onChange: _propTypes.default.func,
54
+ onFocus: _propTypes.default.func,
55
+ onBlur: _propTypes.default.func,
56
+ attachment: _propTypes.default.oneOf(['bottom', 'top']),
57
+ height: _propTypes.default.string,
58
+ width: _propTypes.default.string,
59
+ // darkTheme: PropTypes.bool,
60
+ elementRef: _propTypes.default.func,
61
+ containerRef: _propTypes.default.func,
62
+ searchConfig: _propTypes.default.object
63
+ };
31
64
  const allowedProps = exports.allowedProps = ['label', 'language', 'readOnly', 'editable', 'lineNumbers', 'foldGutter', 'highlightActiveLineGutter', 'highlightActiveLine', 'lineWrapping', 'autofocus', 'spellcheck', 'direction', 'rtlMoveVisually', 'indentOnLoad', 'indentWithTab', 'indentUnit', 'defaultValue', 'value', 'onChange', 'onFocus', 'onBlur', 'attachment', 'height', 'width',
32
65
  // 'darkTheme',
33
66
  'elementRef', 'containerRef', 'searchConfig'];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-source-code-editor",
3
- "version": "10.26.1-snapshot-2",
3
+ "version": "10.26.2",
4
4
  "description": "A UI component library made by Instructure Inc.",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "module": "./es/index.js",
@@ -23,9 +23,9 @@
23
23
  },
24
24
  "license": "MIT",
25
25
  "devDependencies": {
26
- "@instructure/ui-babel-preset": "10.26.1-snapshot-2",
26
+ "@instructure/ui-babel-preset": "10.26.2",
27
27
  "@testing-library/jest-dom": "^6.6.3",
28
- "@testing-library/react": "15.0.7",
28
+ "@testing-library/react": "^16.0.1",
29
29
  "@testing-library/user-event": "^14.6.1",
30
30
  "vitest": "^3.2.2"
31
31
  },
@@ -44,22 +44,25 @@
44
44
  "@codemirror/search": "^6.5.6",
45
45
  "@codemirror/state": "^6.4.1",
46
46
  "@codemirror/view": "^6.34.1",
47
- "@instructure/emotion": "10.26.1-snapshot-2",
48
- "@instructure/shared-types": "10.26.1-snapshot-2",
49
- "@instructure/ui-a11y-content": "10.26.1-snapshot-2",
50
- "@instructure/ui-buttons": "10.26.1-snapshot-2",
51
- "@instructure/ui-dom-utils": "10.26.1-snapshot-2",
52
- "@instructure/ui-i18n": "10.26.1-snapshot-2",
53
- "@instructure/ui-icons": "10.26.1-snapshot-2",
54
- "@instructure/ui-react-utils": "10.26.1-snapshot-2",
55
- "@instructure/ui-text-input": "10.26.1-snapshot-2",
56
- "@instructure/ui-themes": "10.26.1-snapshot-2",
57
- "@instructure/ui-utils": "10.26.1-snapshot-2",
58
- "@lezer/highlight": "1.2.1"
47
+ "@instructure/emotion": "10.26.2",
48
+ "@instructure/shared-types": "10.26.2",
49
+ "@instructure/ui-a11y-content": "10.26.2",
50
+ "@instructure/ui-buttons": "10.26.2",
51
+ "@instructure/ui-dom-utils": "10.26.2",
52
+ "@instructure/ui-i18n": "10.26.2",
53
+ "@instructure/ui-icons": "10.26.2",
54
+ "@instructure/ui-prop-types": "10.26.2",
55
+ "@instructure/ui-react-utils": "10.26.2",
56
+ "@instructure/ui-testable": "10.26.2",
57
+ "@instructure/ui-text-input": "10.26.2",
58
+ "@instructure/ui-themes": "10.26.2",
59
+ "@instructure/ui-utils": "10.26.2",
60
+ "@lezer/highlight": "1.2.1",
61
+ "prop-types": "^15.8.1"
59
62
  },
60
63
  "peerDependencies": {
61
- "react": ">=18 <=19",
62
- "react-dom": ">=18 <=19"
64
+ "react": ">=16.14 <=18",
65
+ "react-dom": ">=16.14 <=18"
63
66
  },
64
67
  "publishConfig": {
65
68
  "access": "public"
@@ -4,6 +4,22 @@ describes: CodeEditor
4
4
 
5
5
  A wrapper around the popular [CodeMirror](https://codemirror.net/) code editor component. CodeMirror provides a text input field with features like line gutters, syntax highlighting, and autocompletion.
6
6
 
7
+ ```javascript
8
+ ---
9
+ type: embed
10
+ ---
11
+ <ToggleBlockquote
12
+ summary="Upgrade from CodeEditor!"
13
+ >
14
+ <ToggleBlockquote.Paragraph>
15
+ If you are currently using our <Link href="/#CodeEditor">CodeEditor</Link> component, we suggest upgrading to SourceCodeEditor, because it has many more features and is way more accessible.
16
+ </ToggleBlockquote.Paragraph>
17
+ <ToggleBlockquote.Paragraph>
18
+ See the <Link href="/#CodeEditor/#migration-guide">migration guide</Link> at the bottom of the CodeEditor docs page for more info.
19
+ </ToggleBlockquote.Paragraph>
20
+ </ToggleBlockquote>
21
+ ```
22
+
7
23
  ### Built-in features
8
24
 
9
25
  SourceCodeEditor has a lot of built-in features that makes editing code easier.
@@ -22,7 +22,7 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- import { useState } from 'react'
25
+ import { version, useState } from 'react'
26
26
  import {
27
27
  setSearchQuery,
28
28
  search,
@@ -39,7 +39,8 @@ import {
39
39
  IconArrowOpenUpLine,
40
40
  IconSearchLine
41
41
  } from '@instructure/ui-icons'
42
- import { createRoot } from 'react-dom/client'
42
+
43
+ import ReactDOM from 'react-dom'
43
44
 
44
45
  export type SearchConfig = {
45
46
  placeholder: string
@@ -98,7 +99,7 @@ function SearchPanel({
98
99
  return (
99
100
  <TextInput
100
101
  renderLabel=""
101
- inputRef={(r: HTMLInputElement | null) => {
102
+ inputRef={(r) => {
102
103
  setTimeout(() => r?.focus(), 0)
103
104
  }}
104
105
  size="small"
@@ -141,8 +142,27 @@ export default function customSearch(searchConfig: SearchConfig | undefined) {
141
142
  createPanel: (view) => {
142
143
  const dom = document.createElement('div')
143
144
  dom.style.padding = '8px'
144
- const root = createRoot(dom)
145
- root.render(<SearchPanel view={view} searchConfig={searchConfig} />)
145
+ const reactVersionMajor = Number(version.split('.')[0])
146
+ if (reactVersionMajor >= 18) {
147
+ const module = 'react-dom/client'
148
+ // webpack tries to evaluate imports compile time which would lead to an error on older react versions
149
+ // Vite errors out during build in React v16/17
150
+ import(/* webpackIgnore: true */ /* @vite-ignore */ module)
151
+ .then((r) => {
152
+ const root = r.createRoot(dom)
153
+ root.render(
154
+ <SearchPanel view={view} searchConfig={searchConfig} />
155
+ )
156
+ })
157
+ .catch((e) => {
158
+ console.error(e)
159
+ })
160
+ } else {
161
+ ReactDOM.render(
162
+ <SearchPanel view={view} searchConfig={searchConfig} />,
163
+ dom
164
+ )
165
+ }
146
166
  return { dom }
147
167
  }
148
168
  })
@@ -76,6 +76,7 @@ import { shell } from '@codemirror/legacy-modes/mode/shell'
76
76
  import { yaml } from '@codemirror/legacy-modes/mode/yaml'
77
77
  // import { oneDarkTheme, oneDarkHighlightStyle } from '@codemirror/theme-one-dark'
78
78
 
79
+ import { testable } from '@instructure/ui-testable'
79
80
  import {
80
81
  omitProps,
81
82
  passthroughProps,
@@ -96,7 +97,7 @@ import generateComponentTheme from './theme'
96
97
 
97
98
  import { rtlHorizontalArrowKeymap } from './customKeybinding'
98
99
 
99
- import { allowedProps } from './props'
100
+ import { propTypes, allowedProps } from './props'
100
101
  import type { SourceCodeEditorProps } from './props'
101
102
 
102
103
  /**
@@ -107,9 +108,11 @@ category: components
107
108
  @withDeterministicId()
108
109
  @withStyle(generateStyle, generateComponentTheme)
109
110
  @textDirectionContextConsumer()
111
+ @testable()
110
112
  class SourceCodeEditor extends Component<SourceCodeEditorProps> {
111
113
  static readonly componentId = 'SourceCodeEditor'
112
114
 
115
+ static propTypes = propTypes
113
116
  static allowedProps = allowedProps
114
117
  static defaultProps = {
115
118
  language: 'jsx',
@@ -663,7 +666,6 @@ class SourceCodeEditor extends Component<SourceCodeEditorProps> {
663
666
 
664
667
  return (
665
668
  <div
666
- data-cid="SourceCodeEditor"
667
669
  ref={this.handleRef}
668
670
  css={styles?.codeEditor}
669
671
  {...passthroughProps(
@@ -22,9 +22,14 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
+ import PropTypes from 'prop-types'
26
+
25
27
  import type { TagStyle } from '@codemirror/language'
26
28
 
29
+ import { controllable } from '@instructure/ui-prop-types'
30
+
27
31
  import type {
32
+ PropValidators,
28
33
  CodeEditorTheme,
29
34
  OtherHTMLAttributes
30
35
  } from '@instructure/shared-types'
@@ -228,6 +233,51 @@ type SourceCodeEditorStyle = ComponentStyle<
228
233
  theme: StyleObject
229
234
  highlightStyle: TagStyle[]
230
235
  }
236
+
237
+ const propTypes: PropValidators<PropKeys> = {
238
+ label: PropTypes.string.isRequired,
239
+ language: PropTypes.oneOf([
240
+ 'sh',
241
+ 'js',
242
+ 'json',
243
+ 'javascript',
244
+ 'jsx',
245
+ 'shell',
246
+ 'css',
247
+ 'html',
248
+ 'markdown',
249
+ 'yaml',
250
+ 'yml',
251
+ 'bash'
252
+ ]),
253
+ readOnly: PropTypes.bool,
254
+ editable: PropTypes.bool,
255
+ lineNumbers: PropTypes.bool,
256
+ foldGutter: PropTypes.bool,
257
+ highlightActiveLineGutter: PropTypes.bool,
258
+ highlightActiveLine: PropTypes.bool,
259
+ lineWrapping: PropTypes.bool,
260
+ autofocus: PropTypes.bool,
261
+ spellcheck: PropTypes.bool,
262
+ direction: PropTypes.oneOf(['ltr', 'rtl']),
263
+ rtlMoveVisually: PropTypes.bool,
264
+ indentOnLoad: PropTypes.bool,
265
+ indentWithTab: PropTypes.bool,
266
+ indentUnit: PropTypes.string,
267
+ defaultValue: PropTypes.string,
268
+ value: controllable(PropTypes.string, 'onChange', 'defaultValue'),
269
+ onChange: PropTypes.func,
270
+ onFocus: PropTypes.func,
271
+ onBlur: PropTypes.func,
272
+ attachment: PropTypes.oneOf(['bottom', 'top']),
273
+ height: PropTypes.string,
274
+ width: PropTypes.string,
275
+ // darkTheme: PropTypes.bool,
276
+ elementRef: PropTypes.func,
277
+ containerRef: PropTypes.func,
278
+ searchConfig: PropTypes.object
279
+ }
280
+
231
281
  const allowedProps: AllowedPropKeys = [
232
282
  'label',
233
283
  'language',
@@ -260,4 +310,4 @@ const allowedProps: AllowedPropKeys = [
260
310
  ]
261
311
 
262
312
  export type { SourceCodeEditorProps, SourceCodeEditorStyle }
263
- export { allowedProps }
313
+ export { propTypes, allowedProps }
@@ -17,7 +17,9 @@
17
17
  { "path": "../ui-a11y-content/tsconfig.build.json" },
18
18
  { "path": "../ui-dom-utils/tsconfig.build.json" },
19
19
  { "path": "../ui-i18n/tsconfig.build.json" },
20
+ { "path": "../ui-prop-types/tsconfig.build.json" },
20
21
  { "path": "../ui-react-utils/tsconfig.build.json" },
22
+ { "path": "../ui-testable/tsconfig.build.json" },
21
23
  { "path": "../ui-utils/tsconfig.build.json" }
22
24
  ]
23
25
  }