@instructure/ui-react-utils 10.16.1-snapshot-0 → 10.16.1
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 +1 -1
- package/es/DeterministicIdContext/DeterministicIdContextProvider.js +6 -4
- package/es/DeterministicIdContext/withDeterministicId.js +6 -4
- package/es/__new-tests__/DeterministicIdContext.test.js +36 -24
- package/es/__new-tests__/callRenderProp.test.js +30 -13
- package/es/__new-tests__/deprecated.test.js +30 -17
- package/es/__new-tests__/experimental.test.js +10 -7
- package/es/__new-tests__/hack.test.js +7 -4
- package/es/__new-tests__/safeCloneElement.test.js +7 -7
- package/es/ensureSingleChild.js +6 -2
- package/es/safeCloneElement.js +3 -3
- package/lib/DeterministicIdContext/DeterministicIdContextProvider.js +5 -5
- package/lib/DeterministicIdContext/withDeterministicId.js +6 -5
- package/lib/__new-tests__/DeterministicIdContext.test.js +36 -25
- package/lib/__new-tests__/callRenderProp.test.js +30 -13
- package/lib/__new-tests__/deprecated.test.js +30 -18
- package/lib/__new-tests__/experimental.test.js +10 -8
- package/lib/__new-tests__/hack.test.js +7 -5
- package/lib/__new-tests__/safeCloneElement.test.js +10 -11
- package/lib/ensureSingleChild.js +7 -5
- package/lib/safeCloneElement.js +3 -4
- package/package.json +7 -7
- package/src/DeterministicIdContext/DeterministicIdContextProvider.tsx +1 -1
- package/src/DeterministicIdContext/withDeterministicId.tsx +2 -2
- package/src/__new-tests__/DeterministicIdContext.test.tsx +3 -3
- package/src/__new-tests__/callRenderProp.test.tsx +3 -3
- package/src/__new-tests__/deprecated.test.tsx +1 -1
- package/src/__new-tests__/experimental.test.tsx +1 -1
- package/src/__new-tests__/hack.test.tsx +1 -1
- package/src/__new-tests__/safeCloneElement.test.tsx +1 -1
- package/src/ensureSingleChild.tsx +1 -1
- package/src/safeCloneElement.ts +5 -4
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/DeterministicIdContext/DeterministicIdContextProvider.d.ts +1 -2
- package/types/DeterministicIdContext/DeterministicIdContextProvider.d.ts.map +1 -1
- package/types/DeterministicIdContext/withDeterministicId.d.ts +2 -2
- package/types/DeterministicIdContext/withDeterministicId.d.ts.map +1 -1
- package/types/ensureSingleChild.d.ts +2 -2
- package/types/ensureSingleChild.d.ts.map +1 -1
- package/types/getElementType.d.ts +1 -1
- package/types/safeCloneElement.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
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.16.1
|
|
6
|
+
## [10.16.1](https://github.com/instructure/instructure-ui/compare/v10.16.0...v10.16.1) (2025-04-22)
|
|
7
7
|
|
|
8
8
|
**Note:** Version bump only for package @instructure/ui-react-utils
|
|
9
9
|
|
|
@@ -21,8 +21,9 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
import { DeterministicIdContext, defaultDeterministicIDMap } from './DeterministicIdContext';
|
|
26
|
+
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
26
27
|
/**
|
|
27
28
|
* ---
|
|
28
29
|
* category: components/utilities
|
|
@@ -39,8 +40,9 @@ const DeterministicIdContextProvider = ({
|
|
|
39
40
|
children,
|
|
40
41
|
instanceCounterMap = defaultDeterministicIDMap
|
|
41
42
|
}) => {
|
|
42
|
-
return
|
|
43
|
-
value: instanceCounterMap
|
|
44
|
-
|
|
43
|
+
return _jsx(DeterministicIdContext.Provider, {
|
|
44
|
+
value: instanceCounterMap,
|
|
45
|
+
children: children
|
|
46
|
+
});
|
|
45
47
|
};
|
|
46
48
|
export { DeterministicIdContextProvider };
|
|
@@ -21,12 +21,13 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
-
import
|
|
24
|
+
import { forwardRef, useContext } from 'react';
|
|
25
25
|
import hoistNonReactStatics from 'hoist-non-react-statics';
|
|
26
26
|
import { DeterministicIdContext } from './DeterministicIdContext';
|
|
27
27
|
import { decorator } from '@instructure/ui-decorator';
|
|
28
28
|
import { generateId } from '@instructure/ui-utils';
|
|
29
29
|
import { warn } from '@instructure/console';
|
|
30
|
+
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
30
31
|
/**
|
|
31
32
|
* This decorator is used to enable the decorated class to use the `DeterministicIdContext` which is needed
|
|
32
33
|
* for deterministic id generation.
|
|
@@ -43,10 +44,11 @@ const withDeterministicId = decorator(ComposedComponent => {
|
|
|
43
44
|
if (props.deterministicId) {
|
|
44
45
|
warn(false, `Manually passing the "deterministicId" property is not allowed on the ${componentName} component.\n`, props.deterministicId);
|
|
45
46
|
}
|
|
46
|
-
return
|
|
47
|
+
return _jsx(ComposedComponent, {
|
|
47
48
|
ref: ref,
|
|
48
|
-
deterministicId: deterministicId
|
|
49
|
-
|
|
49
|
+
deterministicId: deterministicId,
|
|
50
|
+
...props
|
|
51
|
+
});
|
|
50
52
|
});
|
|
51
53
|
hoistNonReactStatics(WithDeterministicId, ComposedComponent);
|
|
52
54
|
|
|
@@ -23,21 +23,25 @@ var _dec, _class, _TestComponent, _div, _WrapperComponent2, _div2, _div3, _div4;
|
|
|
23
23
|
* SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import
|
|
26
|
+
import { Component } from 'react';
|
|
27
27
|
import { render, screen } from '@testing-library/react';
|
|
28
28
|
import '@testing-library/jest-dom';
|
|
29
29
|
import { withDeterministicId, DeterministicIdContextProvider } from '../DeterministicIdContext';
|
|
30
|
-
|
|
30
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
31
|
+
let TestComponent = (_dec = withDeterministicId(), _dec(_class = (_TestComponent = class TestComponent extends Component {
|
|
31
32
|
render() {
|
|
32
|
-
return
|
|
33
|
+
return _jsx("div", {
|
|
33
34
|
"data-testid": "test-component",
|
|
34
|
-
id: this.props.deterministicId()
|
|
35
|
-
|
|
35
|
+
id: this.props.deterministicId(),
|
|
36
|
+
children: this.props.children
|
|
37
|
+
});
|
|
36
38
|
}
|
|
37
39
|
}, _TestComponent.displayName = "TestComponent", _TestComponent)) || _class);
|
|
38
|
-
class WrapperComponent extends
|
|
40
|
+
class WrapperComponent extends Component {
|
|
39
41
|
render() {
|
|
40
|
-
return _div || (_div =
|
|
42
|
+
return _div || (_div = _jsx("div", {
|
|
43
|
+
children: _jsx(TestComponent, {})
|
|
44
|
+
}));
|
|
41
45
|
}
|
|
42
46
|
}
|
|
43
47
|
WrapperComponent.displayName = "WrapperComponent";
|
|
@@ -47,22 +51,26 @@ const uniqueIds = el => {
|
|
|
47
51
|
};
|
|
48
52
|
describe('DeterministicIdContext', () => {
|
|
49
53
|
it('can be found and tested with ReactTestUtils', () => {
|
|
50
|
-
render(_WrapperComponent2 || (_WrapperComponent2 =
|
|
54
|
+
render(_WrapperComponent2 || (_WrapperComponent2 = _jsx(WrapperComponent, {})));
|
|
51
55
|
const testComponent = screen.getByTestId('test-component');
|
|
52
56
|
expect(testComponent).toBeInTheDocument();
|
|
53
57
|
expect(testComponent.id).toBeDefined();
|
|
54
58
|
});
|
|
55
59
|
it('should generate unique ids without Provider wrapper', () => {
|
|
56
|
-
render(_div2 || (_div2 =
|
|
57
|
-
"data-testid": "test-components"
|
|
58
|
-
|
|
60
|
+
render(_div2 || (_div2 = _jsxs("div", {
|
|
61
|
+
"data-testid": "test-components",
|
|
62
|
+
children: [_jsx(TestComponent, {}), _jsx(TestComponent, {}), _jsx(TestComponent, {}), _jsx(TestComponent, {}), _jsx(TestComponent, {})]
|
|
63
|
+
})));
|
|
59
64
|
const el = screen.getByTestId('test-components');
|
|
60
65
|
expect(uniqueIds(el)).toBe(true);
|
|
61
66
|
});
|
|
62
67
|
it('should generate unique ids when components are rendered both out and inside of provider', () => {
|
|
63
|
-
render(_div3 || (_div3 =
|
|
64
|
-
"data-testid": "test-components"
|
|
65
|
-
|
|
68
|
+
render(_div3 || (_div3 = _jsxs("div", {
|
|
69
|
+
"data-testid": "test-components",
|
|
70
|
+
children: [_jsxs(DeterministicIdContextProvider, {
|
|
71
|
+
children: [_jsx(TestComponent, {}), _jsx(TestComponent, {}), _jsx(TestComponent, {})]
|
|
72
|
+
}), _jsx(TestComponent, {}), _jsx(TestComponent, {})]
|
|
73
|
+
})));
|
|
66
74
|
const el = screen.getByTestId('test-components');
|
|
67
75
|
expect(uniqueIds(el)).toBe(true);
|
|
68
76
|
});
|
|
@@ -70,17 +78,20 @@ describe('DeterministicIdContext', () => {
|
|
|
70
78
|
const Wrapper = ({
|
|
71
79
|
children
|
|
72
80
|
}) => {
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
return _jsx(DeterministicIdContextProvider, {
|
|
82
|
+
children: _jsx("div", {
|
|
83
|
+
"data-testid": "wrapper",
|
|
84
|
+
children: children
|
|
85
|
+
})
|
|
86
|
+
});
|
|
76
87
|
};
|
|
77
88
|
const children = [];
|
|
78
89
|
for (let i = 0; i < 10; i++) {
|
|
79
|
-
children.push(
|
|
80
|
-
key: i
|
|
81
|
-
}));
|
|
90
|
+
children.push(_jsx(TestComponent, {}, i));
|
|
82
91
|
}
|
|
83
|
-
render(
|
|
92
|
+
render(_jsx(Wrapper, {
|
|
93
|
+
children: children
|
|
94
|
+
}));
|
|
84
95
|
const el = screen.getByTestId('wrapper');
|
|
85
96
|
expect(uniqueIds(el)).toBe(true);
|
|
86
97
|
});
|
|
@@ -88,9 +99,10 @@ describe('DeterministicIdContext', () => {
|
|
|
88
99
|
const instUIInstanceCounter = '__INSTUI_GLOBAL_INSTANCE_COUNTER__';
|
|
89
100
|
const counterValue = 345;
|
|
90
101
|
globalThis[instUIInstanceCounter].set('TestComponent', counterValue);
|
|
91
|
-
render(_div4 || (_div4 =
|
|
92
|
-
"data-testid": "test-components"
|
|
93
|
-
|
|
102
|
+
render(_div4 || (_div4 = _jsxs("div", {
|
|
103
|
+
"data-testid": "test-components",
|
|
104
|
+
children: [_jsx(TestComponent, {}), _jsx(TestComponent, {}), _jsx(TestComponent, {}), _jsx(TestComponent, {}), _jsx(TestComponent, {})]
|
|
105
|
+
})));
|
|
94
106
|
const instanceCounter = globalThis[instUIInstanceCounter];
|
|
95
107
|
expect(instanceCounter.get('TestComponent')).toBe(counterValue + 5);
|
|
96
108
|
});
|
|
@@ -23,11 +23,12 @@ var _div, _div2;
|
|
|
23
23
|
* SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import
|
|
26
|
+
import { Component } from 'react';
|
|
27
27
|
import PropTypes from 'prop-types';
|
|
28
28
|
import { render } from '@testing-library/react';
|
|
29
29
|
import '@testing-library/jest-dom';
|
|
30
30
|
import { callRenderProp } from '../callRenderProp';
|
|
31
|
+
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
31
32
|
describe('callRenderProp', () => {
|
|
32
33
|
it('strings', () => {
|
|
33
34
|
expect(callRenderProp('foo')).toEqual('foo');
|
|
@@ -44,18 +45,22 @@ describe('callRenderProp', () => {
|
|
|
44
45
|
expect(callRenderProp(false)).toEqual(false);
|
|
45
46
|
});
|
|
46
47
|
it('JSX literals', () => {
|
|
47
|
-
const Foo = () => _div || (_div =
|
|
48
|
-
|
|
48
|
+
const Foo = () => _div || (_div = _jsx("div", {
|
|
49
|
+
children: "hello"
|
|
50
|
+
}));
|
|
51
|
+
expect(callRenderProp(_jsx(Foo, {}))).toStrictEqual(_jsx(Foo, {}));
|
|
49
52
|
});
|
|
50
53
|
it('React classes', () => {
|
|
51
|
-
class Foo extends
|
|
54
|
+
class Foo extends Component {
|
|
52
55
|
render() {
|
|
53
|
-
return _div2 || (_div2 =
|
|
56
|
+
return _div2 || (_div2 = _jsx("div", {
|
|
57
|
+
children: "hello"
|
|
58
|
+
}));
|
|
54
59
|
}
|
|
55
60
|
}
|
|
56
61
|
Foo.displayName = "Foo";
|
|
57
62
|
const Result = callRenderProp(Foo);
|
|
58
|
-
expect(Result).toStrictEqual(
|
|
63
|
+
expect(Result).toStrictEqual(_jsx(Foo, {}));
|
|
59
64
|
const _render = render(Result),
|
|
60
65
|
getByText = _render.getByText;
|
|
61
66
|
expect(getByText('hello')).toBeInTheDocument();
|
|
@@ -65,7 +70,9 @@ describe('callRenderProp', () => {
|
|
|
65
70
|
return 'some text';
|
|
66
71
|
};
|
|
67
72
|
const result = callRenderProp(Baz);
|
|
68
|
-
const _render2 = render(
|
|
73
|
+
const _render2 = render(_jsx("div", {
|
|
74
|
+
children: result
|
|
75
|
+
})),
|
|
69
76
|
getByText = _render2.getByText;
|
|
70
77
|
expect(getByText('some text')).toBeInTheDocument();
|
|
71
78
|
});
|
|
@@ -81,7 +88,9 @@ describe('callRenderProp', () => {
|
|
|
81
88
|
// if it was a real untranspiled fat arrow function.
|
|
82
89
|
if (Baz.prototype) Baz.prototype = void 0;
|
|
83
90
|
const result = callRenderProp(Baz);
|
|
84
|
-
const _render3 = render(
|
|
91
|
+
const _render3 = render(_jsx("div", {
|
|
92
|
+
children: result
|
|
93
|
+
})),
|
|
85
94
|
getByText = _render3.getByText;
|
|
86
95
|
expect(getByText('some text')).toBeInTheDocument();
|
|
87
96
|
});
|
|
@@ -89,18 +98,24 @@ describe('callRenderProp', () => {
|
|
|
89
98
|
it('should pass props correctly to functions', () => {
|
|
90
99
|
const someFunc = ({
|
|
91
100
|
shape
|
|
92
|
-
}) =>
|
|
101
|
+
}) => _jsx("div", {
|
|
102
|
+
children: shape
|
|
103
|
+
});
|
|
93
104
|
const result = callRenderProp(someFunc, {
|
|
94
105
|
shape: 'rectangle'
|
|
95
106
|
});
|
|
96
|
-
const _render4 = render(
|
|
107
|
+
const _render4 = render(_jsx("div", {
|
|
108
|
+
children: result
|
|
109
|
+
})),
|
|
97
110
|
getByText = _render4.getByText;
|
|
98
111
|
expect(getByText('rectangle')).toBeInTheDocument();
|
|
99
112
|
});
|
|
100
113
|
it('should pass props correctly to React classes', () => {
|
|
101
|
-
class Foo extends
|
|
114
|
+
class Foo extends Component {
|
|
102
115
|
render() {
|
|
103
|
-
return
|
|
116
|
+
return _jsx("div", {
|
|
117
|
+
children: this.props.shape
|
|
118
|
+
});
|
|
104
119
|
}
|
|
105
120
|
}
|
|
106
121
|
Foo.displayName = "Foo";
|
|
@@ -113,7 +128,9 @@ describe('callRenderProp', () => {
|
|
|
113
128
|
const result = callRenderProp(Foo, {
|
|
114
129
|
shape: 'rectangle'
|
|
115
130
|
});
|
|
116
|
-
const _render5 = render(
|
|
131
|
+
const _render5 = render(_jsx("div", {
|
|
132
|
+
children: result
|
|
133
|
+
})),
|
|
117
134
|
getByText = _render5.getByText;
|
|
118
135
|
expect(getByText('rectangle')).toBeInTheDocument();
|
|
119
136
|
});
|
|
@@ -22,15 +22,18 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import
|
|
25
|
+
import { Component } from 'react';
|
|
26
26
|
import { vi } from 'vitest';
|
|
27
27
|
import PropTypes from 'prop-types';
|
|
28
28
|
import { render } from '@testing-library/react';
|
|
29
29
|
import '@testing-library/jest-dom';
|
|
30
30
|
import { deprecated } from '../deprecated';
|
|
31
|
+
import { jsxs as _jsxs, jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
31
32
|
class TestComponent extends Component {
|
|
32
33
|
render() {
|
|
33
|
-
return
|
|
34
|
+
return _jsxs("div", {
|
|
35
|
+
children: [this.props.qux, " ", this.props.bar]
|
|
36
|
+
});
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
TestComponent.displayName = "TestComponent";
|
|
@@ -51,7 +54,7 @@ describe('@deprecated', () => {
|
|
|
51
54
|
})(TestComponent);
|
|
52
55
|
it('should warn when suggesting new prop when using old prop', () => {
|
|
53
56
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
54
|
-
render(_DeprecatedComponent || (_DeprecatedComponent =
|
|
57
|
+
render(_DeprecatedComponent || (_DeprecatedComponent = _jsx(DeprecatedComponent, {
|
|
55
58
|
foo: "Jane"
|
|
56
59
|
})));
|
|
57
60
|
const expectedWarningMessage = 'Warning: [TestComponent] `foo` is deprecated and will be removed in version 2.1.0. Use `bar` instead. ';
|
|
@@ -60,7 +63,7 @@ describe('@deprecated', () => {
|
|
|
60
63
|
});
|
|
61
64
|
it('should warn when using old prop with no new prop', () => {
|
|
62
65
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
63
|
-
render(_DeprecatedComponent2 || (_DeprecatedComponent2 =
|
|
66
|
+
render(_DeprecatedComponent2 || (_DeprecatedComponent2 = _jsx(DeprecatedComponent, {
|
|
64
67
|
baz: "Goodbye"
|
|
65
68
|
})));
|
|
66
69
|
const expectedWarningMessage = 'Warning: [TestComponent] `baz` is deprecated and will be removed in version 2.1.0.';
|
|
@@ -69,7 +72,7 @@ describe('@deprecated', () => {
|
|
|
69
72
|
});
|
|
70
73
|
it('should not output a warning using new prop', () => {
|
|
71
74
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
72
|
-
render(_DeprecatedComponent3 || (_DeprecatedComponent3 =
|
|
75
|
+
render(_DeprecatedComponent3 || (_DeprecatedComponent3 = _jsx(DeprecatedComponent, {
|
|
73
76
|
bar: "Jane"
|
|
74
77
|
})));
|
|
75
78
|
expect(consoleWarningSpy).not.toHaveBeenCalled();
|
|
@@ -81,7 +84,7 @@ describe('@deprecated', () => {
|
|
|
81
84
|
const DeprecatedComponent = deprecated('3.4.0')(TestComponent);
|
|
82
85
|
it('should warn that the entire component is deprecated if no old props are supplied', () => {
|
|
83
86
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
84
|
-
render(_DeprecatedComponent4 || (_DeprecatedComponent4 =
|
|
87
|
+
render(_DeprecatedComponent4 || (_DeprecatedComponent4 = _jsx(DeprecatedComponent, {})));
|
|
85
88
|
const expectedWarningMessage = 'Warning: [TestComponent] is deprecated and will be removed in version 3.4.0.';
|
|
86
89
|
expect(consoleWarningSpy).toHaveBeenCalledWith(expect.stringContaining(expectedWarningMessage), expect.any(String));
|
|
87
90
|
consoleWarningSpy.mockRestore();
|
|
@@ -93,7 +96,7 @@ describe('@deprecated', () => {
|
|
|
93
96
|
it('should warn that the component is deprecated and output a warning that the package changed', () => {
|
|
94
97
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
95
98
|
const expectedWarningMessage = 'Warning: [TestComponent] is deprecated and will be removed in version 5.0.0. It has been moved from @instructure/ui-forms to @instructure/ui-number-input.';
|
|
96
|
-
render(_DeprecatedComponent5 || (_DeprecatedComponent5 =
|
|
99
|
+
render(_DeprecatedComponent5 || (_DeprecatedComponent5 = _jsx(DeprecatedComponent, {})));
|
|
97
100
|
expect(consoleWarningSpy).toHaveBeenCalledWith(expect.stringContaining(expectedWarningMessage), expect.any(String));
|
|
98
101
|
consoleWarningSpy.mockRestore();
|
|
99
102
|
});
|
|
@@ -103,7 +106,9 @@ describe('@deprecated', () => {
|
|
|
103
106
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
104
107
|
class DeprecatedPropValueComponent extends Component {
|
|
105
108
|
render() {
|
|
106
|
-
return
|
|
109
|
+
return _jsx("div", {
|
|
110
|
+
children: this.props.color
|
|
111
|
+
});
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
114
|
DeprecatedPropValueComponent.displayName = "DeprecatedPropValueComponent";
|
|
@@ -113,7 +118,7 @@ describe('@deprecated', () => {
|
|
|
113
118
|
DeprecatedPropValueComponent.defaultProps = {
|
|
114
119
|
color: 'red'
|
|
115
120
|
};
|
|
116
|
-
render(
|
|
121
|
+
render(_jsx(DeprecatedPropValueComponent, {
|
|
117
122
|
color: "yellow"
|
|
118
123
|
}));
|
|
119
124
|
expect(consoleWarningSpy).not.toHaveBeenCalled();
|
|
@@ -124,7 +129,9 @@ describe('@deprecated', () => {
|
|
|
124
129
|
const color = 'orange';
|
|
125
130
|
class DeprecatedPropValueComponent extends Component {
|
|
126
131
|
render() {
|
|
127
|
-
return
|
|
132
|
+
return _jsx("div", {
|
|
133
|
+
children: this.props.color
|
|
134
|
+
});
|
|
128
135
|
}
|
|
129
136
|
}
|
|
130
137
|
DeprecatedPropValueComponent.displayName = "DeprecatedPropValueComponent";
|
|
@@ -134,7 +141,7 @@ describe('@deprecated', () => {
|
|
|
134
141
|
DeprecatedPropValueComponent.defaultProps = {
|
|
135
142
|
color: 'red'
|
|
136
143
|
};
|
|
137
|
-
render(
|
|
144
|
+
render(_jsx(DeprecatedPropValueComponent, {
|
|
138
145
|
color: color
|
|
139
146
|
}));
|
|
140
147
|
const expectedWarningMessage = `The '${color}' value for the \`color\` prop is deprecated.`;
|
|
@@ -147,7 +154,9 @@ describe('@deprecated', () => {
|
|
|
147
154
|
const message = 'It will be removed in v8.0.0.';
|
|
148
155
|
class DeprecatedPropValueComponent extends Component {
|
|
149
156
|
render() {
|
|
150
|
-
return
|
|
157
|
+
return _jsx("div", {
|
|
158
|
+
children: this.props.color
|
|
159
|
+
});
|
|
151
160
|
}
|
|
152
161
|
}
|
|
153
162
|
DeprecatedPropValueComponent.displayName = "DeprecatedPropValueComponent";
|
|
@@ -157,7 +166,7 @@ describe('@deprecated', () => {
|
|
|
157
166
|
DeprecatedPropValueComponent.defaultProps = {
|
|
158
167
|
color: 'red'
|
|
159
168
|
};
|
|
160
|
-
render(
|
|
169
|
+
render(_jsx(DeprecatedPropValueComponent, {
|
|
161
170
|
color: color
|
|
162
171
|
}));
|
|
163
172
|
const expectedWarningMessage = `The '${color}' value for the \`color\` prop is deprecated. ${message}`;
|
|
@@ -170,7 +179,9 @@ describe('@deprecated', () => {
|
|
|
170
179
|
const color = 'gold';
|
|
171
180
|
class DeprecatedPropValueComponent extends Component {
|
|
172
181
|
render() {
|
|
173
|
-
return
|
|
182
|
+
return _jsx("div", {
|
|
183
|
+
children: this.props.color
|
|
184
|
+
});
|
|
174
185
|
}
|
|
175
186
|
}
|
|
176
187
|
DeprecatedPropValueComponent.displayName = "DeprecatedPropValueComponent";
|
|
@@ -180,7 +191,7 @@ describe('@deprecated', () => {
|
|
|
180
191
|
DeprecatedPropValueComponent.defaultProps = {
|
|
181
192
|
color: 'red'
|
|
182
193
|
};
|
|
183
|
-
render(
|
|
194
|
+
render(_jsx(DeprecatedPropValueComponent, {
|
|
184
195
|
color: color
|
|
185
196
|
}));
|
|
186
197
|
const _messageMock$mock$cal = messageMock.mock.calls[0][0],
|
|
@@ -200,7 +211,9 @@ describe('@deprecated', () => {
|
|
|
200
211
|
const color = 'gold';
|
|
201
212
|
class DeprecatedPropValueComponent extends Component {
|
|
202
213
|
render() {
|
|
203
|
-
return
|
|
214
|
+
return _jsx("div", {
|
|
215
|
+
children: this.props.color
|
|
216
|
+
});
|
|
204
217
|
}
|
|
205
218
|
}
|
|
206
219
|
DeprecatedPropValueComponent.displayName = "DeprecatedPropValueComponent";
|
|
@@ -213,7 +226,7 @@ describe('@deprecated', () => {
|
|
|
213
226
|
DeprecatedPropValueComponent.defaultProps = {
|
|
214
227
|
color: 'red'
|
|
215
228
|
};
|
|
216
|
-
render(
|
|
229
|
+
render(_jsx(DeprecatedPropValueComponent, {
|
|
217
230
|
color: color
|
|
218
231
|
}));
|
|
219
232
|
const expectedWarningMessage = `The ${color} value for color has been deprecated. Use the FooBar component with the 'baz' prop set instead.`;
|
|
@@ -22,15 +22,18 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import
|
|
25
|
+
import { Component } from 'react';
|
|
26
26
|
import { vi } from 'vitest';
|
|
27
27
|
import PropTypes from 'prop-types';
|
|
28
28
|
import { render } from '@testing-library/react';
|
|
29
29
|
import '@testing-library/jest-dom';
|
|
30
30
|
import { experimental } from '../experimental';
|
|
31
|
+
import { jsxs as _jsxs, jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
31
32
|
class TestComponent extends Component {
|
|
32
33
|
render() {
|
|
33
|
-
return
|
|
34
|
+
return _jsxs("div", {
|
|
35
|
+
children: [this.props.qux, " ", this.props.bar]
|
|
36
|
+
});
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
TestComponent.displayName = "TestComponent";
|
|
@@ -48,7 +51,7 @@ describe('@experimental', () => {
|
|
|
48
51
|
const ExperimentalComponent = experimental(['bar'])(TestComponent);
|
|
49
52
|
it('should warn when using an experimental prop', () => {
|
|
50
53
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
51
|
-
render(_ExperimentalComponen || (_ExperimentalComponen =
|
|
54
|
+
render(_ExperimentalComponen || (_ExperimentalComponen = _jsx(ExperimentalComponent, {
|
|
52
55
|
bar: "Jane"
|
|
53
56
|
})));
|
|
54
57
|
const expectedWarningMessage = 'Warning: [TestComponent] The `bar` prop is experimental and its API could change significantly in a future release.';
|
|
@@ -57,7 +60,7 @@ describe('@experimental', () => {
|
|
|
57
60
|
});
|
|
58
61
|
it('should not output a warning using a non-experimental prop', () => {
|
|
59
62
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
60
|
-
render(_ExperimentalComponen2 || (_ExperimentalComponen2 =
|
|
63
|
+
render(_ExperimentalComponen2 || (_ExperimentalComponen2 = _jsx(ExperimentalComponent, {
|
|
61
64
|
qux: "Jane"
|
|
62
65
|
})));
|
|
63
66
|
expect(consoleWarningSpy).not.toHaveBeenCalled();
|
|
@@ -65,7 +68,7 @@ describe('@experimental', () => {
|
|
|
65
68
|
});
|
|
66
69
|
it('should not output a warning for an experimental prop when dangerously ignored', () => {
|
|
67
70
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
68
|
-
render(_ExperimentalComponen3 || (_ExperimentalComponen3 =
|
|
71
|
+
render(_ExperimentalComponen3 || (_ExperimentalComponen3 = _jsx(ExperimentalComponent, {
|
|
69
72
|
qux: "Jane",
|
|
70
73
|
__dangerouslyIgnoreExperimentalWarnings: true
|
|
71
74
|
})));
|
|
@@ -78,14 +81,14 @@ describe('@experimental', () => {
|
|
|
78
81
|
const ExperimentalComponent = experimental()(TestComponent);
|
|
79
82
|
it('should warn that the entire component is experimental if no props are supplied', () => {
|
|
80
83
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
81
|
-
render(_ExperimentalComponen4 || (_ExperimentalComponen4 =
|
|
84
|
+
render(_ExperimentalComponen4 || (_ExperimentalComponen4 = _jsx(ExperimentalComponent, {})));
|
|
82
85
|
const expectedWarningMessage = 'Warning: [TestComponent] is experimental and its API could change significantly in a future release.';
|
|
83
86
|
expect(consoleWarningSpy).toHaveBeenCalledWith(expect.stringContaining(expectedWarningMessage), expect.any(String));
|
|
84
87
|
consoleWarningSpy.mockRestore();
|
|
85
88
|
});
|
|
86
89
|
it('should not output a warning for a component when dangerously ignored', () => {
|
|
87
90
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
88
|
-
render(_ExperimentalComponen5 || (_ExperimentalComponen5 =
|
|
91
|
+
render(_ExperimentalComponen5 || (_ExperimentalComponen5 = _jsx(ExperimentalComponent, {
|
|
89
92
|
__dangerouslyIgnoreExperimentalWarnings: true
|
|
90
93
|
})));
|
|
91
94
|
expect(consoleWarningSpy).not.toHaveBeenCalled();
|
|
@@ -22,15 +22,18 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import
|
|
25
|
+
import { Component } from 'react';
|
|
26
26
|
import { vi } from 'vitest';
|
|
27
27
|
import PropTypes from 'prop-types';
|
|
28
28
|
import { render } from '@testing-library/react';
|
|
29
29
|
import '@testing-library/jest-dom';
|
|
30
30
|
import { hack } from '../hack';
|
|
31
|
+
import { jsxs as _jsxs, jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
31
32
|
class TestComponent extends Component {
|
|
32
33
|
render() {
|
|
33
|
-
return
|
|
34
|
+
return _jsxs("div", {
|
|
35
|
+
children: [this.props.qux, " ", this.props.bar]
|
|
36
|
+
});
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
TestComponent.displayName = "TestComponent";
|
|
@@ -48,7 +51,7 @@ describe('@hack', () => {
|
|
|
48
51
|
const HackComponent = hack(['bar'])(TestComponent);
|
|
49
52
|
it('should warn when using an hack prop', () => {
|
|
50
53
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
51
|
-
render(_HackComponent || (_HackComponent =
|
|
54
|
+
render(_HackComponent || (_HackComponent = _jsx(HackComponent, {
|
|
52
55
|
bar: "Jane"
|
|
53
56
|
})));
|
|
54
57
|
const expectedWarningMessage = 'Warning: [TestComponent] The `bar` prop is a temporary hack and will be removed in a future release.';
|
|
@@ -57,7 +60,7 @@ describe('@hack', () => {
|
|
|
57
60
|
});
|
|
58
61
|
it('should not output a warning using a non-hack prop', () => {
|
|
59
62
|
const consoleWarningSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
60
|
-
render(_HackComponent2 || (_HackComponent2 =
|
|
63
|
+
render(_HackComponent2 || (_HackComponent2 = _jsx(HackComponent, {
|
|
61
64
|
qux: "Jane"
|
|
62
65
|
})));
|
|
63
66
|
expect(consoleWarningSpy).not.toHaveBeenCalled();
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import React from 'react';
|
|
26
25
|
import { vi } from 'vitest';
|
|
27
26
|
import { createChainedFunction } from '@instructure/ui-utils';
|
|
28
27
|
import { render, screen } from '@testing-library/react';
|
|
29
28
|
import '@testing-library/jest-dom';
|
|
30
29
|
import { safeCloneElement } from '../safeCloneElement';
|
|
30
|
+
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
31
31
|
describe('safeCloneElement', () => {
|
|
32
32
|
const SafeClone = function ({
|
|
33
33
|
element,
|
|
@@ -39,8 +39,8 @@ describe('safeCloneElement', () => {
|
|
|
39
39
|
it('should preserve refs', () => {
|
|
40
40
|
const origRef = vi.fn();
|
|
41
41
|
const cloneRef = vi.fn();
|
|
42
|
-
render(
|
|
43
|
-
element:
|
|
42
|
+
render(_jsx(SafeClone, {
|
|
43
|
+
element: _jsx("div", {
|
|
44
44
|
ref: origRef
|
|
45
45
|
}),
|
|
46
46
|
props: {
|
|
@@ -53,8 +53,8 @@ describe('safeCloneElement', () => {
|
|
|
53
53
|
it('should preserve event handlers', () => {
|
|
54
54
|
const onClickA = vi.fn();
|
|
55
55
|
const onClickB = vi.fn();
|
|
56
|
-
render(
|
|
57
|
-
element:
|
|
56
|
+
render(_jsx(SafeClone, {
|
|
57
|
+
element: _jsx("button", {
|
|
58
58
|
onClick: onClickA
|
|
59
59
|
}),
|
|
60
60
|
props: {
|
|
@@ -70,8 +70,8 @@ describe('safeCloneElement', () => {
|
|
|
70
70
|
const onClickA = vi.fn();
|
|
71
71
|
const onClickB = vi.fn();
|
|
72
72
|
const onClickC = vi.fn();
|
|
73
|
-
render(
|
|
74
|
-
element:
|
|
73
|
+
render(_jsx(SafeClone, {
|
|
74
|
+
element: _jsx("button", {
|
|
75
75
|
onClick: onClickA
|
|
76
76
|
}),
|
|
77
77
|
props: {
|
package/es/ensureSingleChild.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import
|
|
25
|
+
import { Children } from 'react';
|
|
26
26
|
import { safeCloneElement } from './safeCloneElement';
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -39,12 +39,16 @@ import { safeCloneElement } from './safeCloneElement';
|
|
|
39
39
|
* @param {Object} props - props for child
|
|
40
40
|
* @returns {ReactElement|null} cloned instance for a single child, or children wrapped in a span
|
|
41
41
|
*/
|
|
42
|
+
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
42
43
|
function ensureSingleChild(child, props = {}) {
|
|
43
44
|
const childCount = Children.count(child);
|
|
44
45
|
if (childCount === 0) {
|
|
45
46
|
return null;
|
|
46
47
|
} else if (typeof child === 'string' && child.length > 0 || childCount > 1) {
|
|
47
|
-
return
|
|
48
|
+
return _jsx("span", {
|
|
49
|
+
...props,
|
|
50
|
+
children: child
|
|
51
|
+
});
|
|
48
52
|
} else {
|
|
49
53
|
// TODO: check that we can only end up here if child is ReactElement
|
|
50
54
|
return safeCloneElement(Array.isArray(child) ? child[0] : child, props);
|
package/es/safeCloneElement.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import
|
|
25
|
+
import { cloneElement } from 'react';
|
|
26
26
|
import { logWarn as warn } from '@instructure/console';
|
|
27
27
|
import { createChainedFunction } from '@instructure/ui-utils';
|
|
28
28
|
/**
|
|
@@ -66,12 +66,12 @@ function safeCloneElement(element, props, ...children) {
|
|
|
66
66
|
}
|
|
67
67
|
});
|
|
68
68
|
if (originalRef == null || cloneRef == null) {
|
|
69
|
-
return /*#__PURE__*/
|
|
69
|
+
return /*#__PURE__*/cloneElement(element, mergedProps, ...children);
|
|
70
70
|
}
|
|
71
71
|
warn(originalRefIsAFunction, `Cloning an element with a ref that will be overwritten because the ref \
|
|
72
72
|
is not a function. Use a composable callback-style ref instead. \
|
|
73
73
|
Ignoring ref: ${originalRef}`);
|
|
74
|
-
return /*#__PURE__*/
|
|
74
|
+
return /*#__PURE__*/cloneElement(element, {
|
|
75
75
|
...mergedProps,
|
|
76
76
|
ref(component) {
|
|
77
77
|
if (cloneRefIsFunction) {
|