@instructure/ui-focusable 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/Focusable/__new-tests__/Focusable.test.js +140 -76
- package/lib/Focusable/__new-tests__/Focusable.test.js +140 -77
- package/package.json +8 -8
- package/src/Focusable/__new-tests__/Focusable.test.tsx +1 -1
- package/src/Focusable/index.tsx +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Focusable/index.d.ts +6 -6
- package/types/Focusable/index.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-focusable
|
|
9
9
|
|
|
@@ -23,12 +23,13 @@ var _button, _button2, _input, _a, _a2, _button3, _button4, _span, _span2, _span
|
|
|
23
23
|
* SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import
|
|
26
|
+
import { Component } from 'react';
|
|
27
27
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
28
28
|
import userEvent from '@testing-library/user-event';
|
|
29
29
|
import { vi } from 'vitest';
|
|
30
30
|
import '@testing-library/jest-dom';
|
|
31
31
|
import { Focusable } from '../index';
|
|
32
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
32
33
|
describe('<Focusable />', () => {
|
|
33
34
|
let consoleWarningMock;
|
|
34
35
|
let consoleErrorMock;
|
|
@@ -42,18 +43,25 @@ describe('<Focusable />', () => {
|
|
|
42
43
|
consoleErrorMock.mockRestore();
|
|
43
44
|
});
|
|
44
45
|
it('should render', async () => {
|
|
45
|
-
render(
|
|
46
|
+
render(_jsx(Focusable, {
|
|
47
|
+
children: () => _button || (_button = _jsx("button", {
|
|
48
|
+
children: "hello world"
|
|
49
|
+
}))
|
|
50
|
+
}));
|
|
46
51
|
const button = screen.getByRole('button');
|
|
47
52
|
expect(button).toBeInTheDocument();
|
|
48
53
|
expect(button).toHaveTextContent('hello world');
|
|
49
54
|
});
|
|
50
55
|
it('should call children function with focused when element receives focus', async () => {
|
|
51
56
|
const renderSpy = vi.fn();
|
|
52
|
-
render(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
render(_jsx(Focusable, {
|
|
58
|
+
children: args => {
|
|
59
|
+
renderSpy(args);
|
|
60
|
+
return _button2 || (_button2 = _jsx("button", {
|
|
61
|
+
type: "button",
|
|
62
|
+
children: "foo"
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
57
65
|
}));
|
|
58
66
|
const focusable = screen.getByRole('button');
|
|
59
67
|
await waitFor(() => {
|
|
@@ -83,12 +91,15 @@ describe('<Focusable />', () => {
|
|
|
83
91
|
it('should handle conditionally rendered focus elements', async () => {
|
|
84
92
|
const renderSpy = vi.fn(({
|
|
85
93
|
focused
|
|
86
|
-
}) =>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
}) => _jsx("div", {
|
|
95
|
+
children: focused ? _input || (_input = _jsx("input", {
|
|
96
|
+
type: "text"
|
|
97
|
+
})) : _a || (_a = _jsx("a", {
|
|
98
|
+
href: "http://focus.net",
|
|
99
|
+
children: "Click"
|
|
100
|
+
}))
|
|
101
|
+
}));
|
|
102
|
+
render(_jsx(Focusable, {
|
|
92
103
|
render: renderSpy
|
|
93
104
|
}));
|
|
94
105
|
const firstFocusable = screen.getByText('Click');
|
|
@@ -119,10 +130,11 @@ describe('<Focusable />', () => {
|
|
|
119
130
|
});
|
|
120
131
|
});
|
|
121
132
|
it('should maintain focus when the focus element changes', async () => {
|
|
122
|
-
const renderSpy = vi.fn(() => _a2 || (_a2 =
|
|
123
|
-
href: "http://focus.net"
|
|
124
|
-
|
|
125
|
-
|
|
133
|
+
const renderSpy = vi.fn(() => _a2 || (_a2 = _jsx("a", {
|
|
134
|
+
href: "http://focus.net",
|
|
135
|
+
children: "Click"
|
|
136
|
+
})));
|
|
137
|
+
const _render = render(_jsx(Focusable, {
|
|
126
138
|
render: renderSpy
|
|
127
139
|
})),
|
|
128
140
|
rerender = _render.rerender;
|
|
@@ -137,8 +149,10 @@ describe('<Focusable />', () => {
|
|
|
137
149
|
});
|
|
138
150
|
|
|
139
151
|
// Set prop: render
|
|
140
|
-
const nextRenderSpy = vi.fn(() => _button3 || (_button3 =
|
|
141
|
-
|
|
152
|
+
const nextRenderSpy = vi.fn(() => _button3 || (_button3 = _jsx("button", {
|
|
153
|
+
children: "Click"
|
|
154
|
+
})));
|
|
155
|
+
rerender(_jsx(Focusable, {
|
|
142
156
|
render: nextRenderSpy
|
|
143
157
|
}));
|
|
144
158
|
const nextFocusable = screen.getByText('Click');
|
|
@@ -154,9 +168,13 @@ describe('<Focusable />', () => {
|
|
|
154
168
|
});
|
|
155
169
|
it('should update the focus element correctly', async () => {
|
|
156
170
|
const renderSpy = vi.fn();
|
|
157
|
-
const _render2 = render(
|
|
158
|
-
|
|
159
|
-
|
|
171
|
+
const _render2 = render(_jsx(Focusable, {
|
|
172
|
+
children: args => {
|
|
173
|
+
renderSpy(args);
|
|
174
|
+
return _button4 || (_button4 = _jsx("button", {
|
|
175
|
+
children: "foo"
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
160
178
|
})),
|
|
161
179
|
rerender = _render2.rerender;
|
|
162
180
|
const firstButton = screen.getByText('foo');
|
|
@@ -172,9 +190,15 @@ describe('<Focusable />', () => {
|
|
|
172
190
|
});
|
|
173
191
|
|
|
174
192
|
// Set child
|
|
175
|
-
rerender(
|
|
176
|
-
|
|
177
|
-
|
|
193
|
+
rerender(_jsx(Focusable, {
|
|
194
|
+
children: args => {
|
|
195
|
+
renderSpy(args);
|
|
196
|
+
return _span || (_span = _jsxs("span", {
|
|
197
|
+
children: ["some content text", _jsx("button", {
|
|
198
|
+
children: "bar"
|
|
199
|
+
})]
|
|
200
|
+
}));
|
|
201
|
+
}
|
|
178
202
|
}));
|
|
179
203
|
const secondButton = screen.getByText('bar');
|
|
180
204
|
await secondButton.focus();
|
|
@@ -184,24 +208,50 @@ describe('<Focusable />', () => {
|
|
|
184
208
|
});
|
|
185
209
|
});
|
|
186
210
|
it('should warn when there is more than one focusable descendant', async () => {
|
|
187
|
-
render(
|
|
188
|
-
|
|
211
|
+
render(_jsx(Focusable, {
|
|
212
|
+
children: () => {
|
|
213
|
+
return _span2 || (_span2 = _jsxs("span", {
|
|
214
|
+
children: [_jsx("button", {
|
|
215
|
+
children: "foo"
|
|
216
|
+
}), _jsx("span", {
|
|
217
|
+
children: _jsx("button", {
|
|
218
|
+
children: "bar"
|
|
219
|
+
})
|
|
220
|
+
})]
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
189
223
|
}));
|
|
190
224
|
const expectedWarningMessage = 'Warning: [Focusable] Exactly one focusable child is required (2 found).';
|
|
191
225
|
expect(consoleWarningMock).toHaveBeenCalledWith(expect.stringContaining(expectedWarningMessage), expect.any(String));
|
|
192
226
|
});
|
|
193
227
|
it('should warn when there are no focusable descendants', async () => {
|
|
194
|
-
render(
|
|
195
|
-
|
|
228
|
+
render(_jsx(Focusable, {
|
|
229
|
+
children: () => {
|
|
230
|
+
return _span3 || (_span3 = _jsx("span", {
|
|
231
|
+
children: "hello!"
|
|
232
|
+
}));
|
|
233
|
+
}
|
|
196
234
|
}));
|
|
197
235
|
const expectedWarningMessage = 'Warning: [Focusable] Exactly one focusable child is required (0 found).';
|
|
198
236
|
expect(consoleWarningMock).toHaveBeenCalledWith(expect.stringContaining(expectedWarningMessage), expect.any(String));
|
|
199
237
|
});
|
|
200
238
|
it('should attach event listener correctly even when the focusable element is not the root', async () => {
|
|
201
239
|
const renderSpy = vi.fn();
|
|
202
|
-
render(
|
|
203
|
-
|
|
204
|
-
|
|
240
|
+
render(_jsx(Focusable, {
|
|
241
|
+
children: args => {
|
|
242
|
+
renderSpy(args);
|
|
243
|
+
return _span4 || (_span4 = _jsxs("span", {
|
|
244
|
+
children: [_jsx("h1", {
|
|
245
|
+
children: "hello world"
|
|
246
|
+
}), _jsx("p", {
|
|
247
|
+
children: "some content"
|
|
248
|
+
}), _jsx("span", {
|
|
249
|
+
children: _jsx("button", {
|
|
250
|
+
children: "foo"
|
|
251
|
+
})
|
|
252
|
+
})]
|
|
253
|
+
}));
|
|
254
|
+
}
|
|
205
255
|
}));
|
|
206
256
|
const button = screen.getByRole('button');
|
|
207
257
|
await waitFor(() => {
|
|
@@ -216,11 +266,14 @@ describe('<Focusable />', () => {
|
|
|
216
266
|
});
|
|
217
267
|
it('should provide a focus method', async () => {
|
|
218
268
|
let focusable;
|
|
219
|
-
render(
|
|
269
|
+
render(_jsx(Focusable, {
|
|
220
270
|
ref: el => {
|
|
221
271
|
focusable = el;
|
|
222
|
-
}
|
|
223
|
-
|
|
272
|
+
},
|
|
273
|
+
children: () => _button5 || (_button5 = _jsx("button", {
|
|
274
|
+
children: "hello world"
|
|
275
|
+
}))
|
|
276
|
+
}));
|
|
224
277
|
await focusable.focus();
|
|
225
278
|
const button = screen.getByText('hello world');
|
|
226
279
|
expect(button).toHaveFocus();
|
|
@@ -228,9 +281,13 @@ describe('<Focusable />', () => {
|
|
|
228
281
|
it('should provide a focused getter', async () => {
|
|
229
282
|
var _focusableInstance;
|
|
230
283
|
let focusableInstance;
|
|
231
|
-
render(
|
|
232
|
-
|
|
233
|
-
|
|
284
|
+
render(_jsx(Focusable, {
|
|
285
|
+
children: args => {
|
|
286
|
+
focusableInstance = args;
|
|
287
|
+
return _button6 || (_button6 = _jsx("button", {
|
|
288
|
+
children: "Click me"
|
|
289
|
+
}));
|
|
290
|
+
}
|
|
234
291
|
}));
|
|
235
292
|
const button = screen.getByText('Click me');
|
|
236
293
|
expect((_focusableInstance = focusableInstance) === null || _focusableInstance === void 0 ? void 0 : _focusableInstance.focused).toBe(false);
|
|
@@ -246,21 +303,23 @@ describe('<Focusable />', () => {
|
|
|
246
303
|
class TestComponent extends Component {
|
|
247
304
|
render() {
|
|
248
305
|
const changeValue = this.props.changeValue;
|
|
249
|
-
return
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
306
|
+
return _jsx(Focusable, {
|
|
307
|
+
children: ({
|
|
308
|
+
focusVisible
|
|
309
|
+
}) => {
|
|
310
|
+
return _jsx("input", {
|
|
311
|
+
readOnly: true,
|
|
312
|
+
ref: el => {
|
|
313
|
+
inputRef = el;
|
|
314
|
+
},
|
|
315
|
+
value: `${focusVisible}_${changeValue}`
|
|
316
|
+
});
|
|
317
|
+
}
|
|
259
318
|
});
|
|
260
319
|
}
|
|
261
320
|
}
|
|
262
321
|
TestComponent.displayName = "TestComponent";
|
|
263
|
-
const _render3 = render(
|
|
322
|
+
const _render3 = render(_jsx(TestComponent, {
|
|
264
323
|
changeValue: "A"
|
|
265
324
|
})),
|
|
266
325
|
rerender = _render3.rerender,
|
|
@@ -271,7 +330,7 @@ describe('<Focusable />', () => {
|
|
|
271
330
|
});
|
|
272
331
|
|
|
273
332
|
// Set Prop: changeValue
|
|
274
|
-
rerender(
|
|
333
|
+
rerender(_jsx(TestComponent, {
|
|
275
334
|
changeValue: "B"
|
|
276
335
|
}));
|
|
277
336
|
await inputRef.focus();
|
|
@@ -295,40 +354,45 @@ describe('<Focusable />', () => {
|
|
|
295
354
|
const _this$state = this.state,
|
|
296
355
|
checked = _this$state.checked,
|
|
297
356
|
disabled = _this$state.disabled;
|
|
298
|
-
return
|
|
299
|
-
|
|
300
|
-
focusableRef = el;
|
|
301
|
-
}
|
|
302
|
-
}, () => {
|
|
303
|
-
return /*#__PURE__*/React.createElement("label", {
|
|
357
|
+
return _jsxs("div", {
|
|
358
|
+
children: [_jsx(Focusable, {
|
|
304
359
|
ref: el => {
|
|
305
|
-
|
|
360
|
+
focusableRef = el;
|
|
306
361
|
},
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
362
|
+
children: () => {
|
|
363
|
+
return _jsx("label", {
|
|
364
|
+
ref: el => {
|
|
365
|
+
labelRef = el;
|
|
366
|
+
},
|
|
367
|
+
"aria-label": 'test-label',
|
|
368
|
+
children: _jsx("input", {
|
|
369
|
+
checked: checked,
|
|
370
|
+
disabled: disabled,
|
|
371
|
+
onChange: () => {
|
|
372
|
+
this.setState({
|
|
373
|
+
checked: true
|
|
374
|
+
});
|
|
375
|
+
},
|
|
376
|
+
type: "checkbox"
|
|
377
|
+
})
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
}), _jsx("button", {
|
|
381
|
+
onClick: () => {
|
|
312
382
|
this.setState({
|
|
313
|
-
|
|
383
|
+
disabled: true
|
|
314
384
|
});
|
|
315
385
|
},
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
});
|
|
323
|
-
},
|
|
324
|
-
ref: el => {
|
|
325
|
-
buttonRef = el;
|
|
326
|
-
}
|
|
327
|
-
}, "hello world"));
|
|
386
|
+
ref: el => {
|
|
387
|
+
buttonRef = el;
|
|
388
|
+
},
|
|
389
|
+
children: "hello world"
|
|
390
|
+
})]
|
|
391
|
+
});
|
|
328
392
|
}
|
|
329
393
|
}
|
|
330
394
|
TestComponent.displayName = "TestComponent";
|
|
331
|
-
const _render4 = render(
|
|
395
|
+
const _render4 = render(_jsx(TestComponent, {})),
|
|
332
396
|
container = _render4.container;
|
|
333
397
|
const input = container.querySelector('input');
|
|
334
398
|
await waitFor(() => {
|