@react-magma/charts 13.0.2-next.1 → 14.0.0-next.3
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/dist/charts.js +154 -1
- package/dist/charts.js.map +1 -1
- package/dist/charts.modern.module.js +154 -1
- package/dist/charts.modern.module.js.map +1 -1
- package/dist/charts.umd.js +817 -404
- package/dist/charts.umd.js.map +1 -1
- package/dist/hooks/useCarbonModalFocusManagement.d.ts +2 -0
- package/package.json +10 -5
- package/src/components/CarbonChart/CarbonChart.test.js +176 -1
- package/src/components/CarbonChart/CarbonChart.tsx +17 -1
- package/src/hooks/useCarbonModalFocusManagement.ts +173 -0
package/dist/charts.js
CHANGED
|
@@ -2144,6 +2144,148 @@ function transparentize(amount, color) {
|
|
|
2144
2144
|
var curriedTransparentize = curry /* ::<number | string, string, string> */(transparentize);
|
|
2145
2145
|
var curriedTransparentize$1 = curriedTransparentize;
|
|
2146
2146
|
|
|
2147
|
+
var FOCUSABLE_SELECTOR = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
2148
|
+
function getFocusableElements(container) {
|
|
2149
|
+
return Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)).filter(function (el) {
|
|
2150
|
+
var style = window.getComputedStyle(el);
|
|
2151
|
+
return (style.display !== 'none' &&
|
|
2152
|
+
style.visibility !== 'hidden' &&
|
|
2153
|
+
!el.hasAttribute('disabled'));
|
|
2154
|
+
});
|
|
2155
|
+
}
|
|
2156
|
+
function findVisibleModal(wrapper) {
|
|
2157
|
+
var modal = wrapper.querySelector('.cds--modal');
|
|
2158
|
+
if (!modal)
|
|
2159
|
+
return null;
|
|
2160
|
+
var isVisible = modal.getAttribute('aria-modal') === 'true' ||
|
|
2161
|
+
modal.style.visibility === 'visible' ||
|
|
2162
|
+
modal.classList.contains('is-visible');
|
|
2163
|
+
return isVisible ? modal : null;
|
|
2164
|
+
}
|
|
2165
|
+
function useCarbonModalFocusManagement(wrapperRef) {
|
|
2166
|
+
var previouslyFocusedElement = React__namespace.useRef(null);
|
|
2167
|
+
var keydownHandler = React__namespace.useRef(null);
|
|
2168
|
+
var focusinHandler = React__namespace.useRef(null);
|
|
2169
|
+
var currentModal = React__namespace.useRef(null);
|
|
2170
|
+
React__namespace.useEffect(function () {
|
|
2171
|
+
var wrapper = wrapperRef.current;
|
|
2172
|
+
if (!wrapper)
|
|
2173
|
+
return;
|
|
2174
|
+
function focusModalCloseButton(modal) {
|
|
2175
|
+
var closeButton = modal.querySelector('.cds--modal-close');
|
|
2176
|
+
if (closeButton) {
|
|
2177
|
+
closeButton.focus();
|
|
2178
|
+
}
|
|
2179
|
+
else {
|
|
2180
|
+
var focusable = getFocusableElements(modal);
|
|
2181
|
+
if (focusable.length > 0) {
|
|
2182
|
+
focusable[0].focus();
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
function handleModalOpen(modal) {
|
|
2187
|
+
currentModal.current = modal;
|
|
2188
|
+
previouslyFocusedElement.current = document.activeElement;
|
|
2189
|
+
// Permanent guard: redirect focus back into modal whenever it escapes
|
|
2190
|
+
// (e.g. Carbon's overflow menu returning focus to its trigger).
|
|
2191
|
+
focusinHandler.current = function (event) {
|
|
2192
|
+
var target = event.target;
|
|
2193
|
+
if (!modal.contains(target)) {
|
|
2194
|
+
setTimeout(function () {
|
|
2195
|
+
if (currentModal.current === modal) {
|
|
2196
|
+
focusModalCloseButton(modal);
|
|
2197
|
+
}
|
|
2198
|
+
}, 0);
|
|
2199
|
+
}
|
|
2200
|
+
};
|
|
2201
|
+
document.addEventListener('focusin', focusinHandler.current);
|
|
2202
|
+
var pollAttempts = 0;
|
|
2203
|
+
var pollAndFocus = function () {
|
|
2204
|
+
if (currentModal.current !== modal)
|
|
2205
|
+
return;
|
|
2206
|
+
if (modal.contains(document.activeElement))
|
|
2207
|
+
return;
|
|
2208
|
+
var closeBtn = modal.querySelector('.cds--modal-close');
|
|
2209
|
+
if (closeBtn &&
|
|
2210
|
+
window.getComputedStyle(closeBtn).visibility !== 'hidden') {
|
|
2211
|
+
closeBtn.focus();
|
|
2212
|
+
return;
|
|
2213
|
+
}
|
|
2214
|
+
if (++pollAttempts < 30) {
|
|
2215
|
+
requestAnimationFrame(pollAndFocus);
|
|
2216
|
+
}
|
|
2217
|
+
};
|
|
2218
|
+
requestAnimationFrame(pollAndFocus);
|
|
2219
|
+
keydownHandler.current = function (event) {
|
|
2220
|
+
if (event.key !== 'Tab')
|
|
2221
|
+
return;
|
|
2222
|
+
var focusable = getFocusableElements(modal);
|
|
2223
|
+
if (focusable.length === 0) {
|
|
2224
|
+
event.preventDefault();
|
|
2225
|
+
return;
|
|
2226
|
+
}
|
|
2227
|
+
if (focusable.length === 1) {
|
|
2228
|
+
event.preventDefault();
|
|
2229
|
+
if (focusable[0] !== document.activeElement) {
|
|
2230
|
+
focusable[0].focus();
|
|
2231
|
+
}
|
|
2232
|
+
return;
|
|
2233
|
+
}
|
|
2234
|
+
var firstItem = focusable[0];
|
|
2235
|
+
var lastItem = focusable[focusable.length - 1];
|
|
2236
|
+
if (!event.shiftKey && document.activeElement === lastItem) {
|
|
2237
|
+
event.preventDefault();
|
|
2238
|
+
firstItem.focus();
|
|
2239
|
+
}
|
|
2240
|
+
else if (event.shiftKey && document.activeElement === firstItem) {
|
|
2241
|
+
event.preventDefault();
|
|
2242
|
+
lastItem.focus();
|
|
2243
|
+
}
|
|
2244
|
+
};
|
|
2245
|
+
document.addEventListener('keydown', keydownHandler.current);
|
|
2246
|
+
}
|
|
2247
|
+
function handleModalClose() {
|
|
2248
|
+
// Null out currentModal first so any pending setTimeout redirects
|
|
2249
|
+
// (scheduled by the focusin guard) see a closed modal and bail out.
|
|
2250
|
+
currentModal.current = null;
|
|
2251
|
+
if (focusinHandler.current) {
|
|
2252
|
+
document.removeEventListener('focusin', focusinHandler.current);
|
|
2253
|
+
focusinHandler.current = null;
|
|
2254
|
+
}
|
|
2255
|
+
if (keydownHandler.current) {
|
|
2256
|
+
document.removeEventListener('keydown', keydownHandler.current);
|
|
2257
|
+
keydownHandler.current = null;
|
|
2258
|
+
}
|
|
2259
|
+
if (previouslyFocusedElement.current instanceof HTMLElement) {
|
|
2260
|
+
previouslyFocusedElement.current.focus();
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2263
|
+
var observer = new MutationObserver(function () {
|
|
2264
|
+
var visibleModal = findVisibleModal(wrapper);
|
|
2265
|
+
if (visibleModal && !currentModal.current) {
|
|
2266
|
+
handleModalOpen(visibleModal);
|
|
2267
|
+
}
|
|
2268
|
+
else if (!visibleModal && currentModal.current) {
|
|
2269
|
+
handleModalClose();
|
|
2270
|
+
}
|
|
2271
|
+
});
|
|
2272
|
+
observer.observe(wrapper, {
|
|
2273
|
+
attributes: true,
|
|
2274
|
+
attributeFilter: ['class', 'style', 'aria-modal'],
|
|
2275
|
+
subtree: true,
|
|
2276
|
+
});
|
|
2277
|
+
return function () {
|
|
2278
|
+
observer.disconnect();
|
|
2279
|
+
if (keydownHandler.current) {
|
|
2280
|
+
document.removeEventListener('keydown', keydownHandler.current);
|
|
2281
|
+
}
|
|
2282
|
+
if (focusinHandler.current) {
|
|
2283
|
+
document.removeEventListener('focusin', focusinHandler.current);
|
|
2284
|
+
}
|
|
2285
|
+
};
|
|
2286
|
+
}, [wrapperRef]);
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2147
2289
|
function styleInject(css, ref) {
|
|
2148
2290
|
if ( ref === void 0 ) ref = {};
|
|
2149
2291
|
var insertAt = ref.insertAt;
|
|
@@ -2389,6 +2531,17 @@ var CarbonChart = React__namespace.forwardRef(function (props, ref) {
|
|
|
2389
2531
|
var testId = props.testId, isInverseProp = props.isInverse, type = props.type, dataSet = props.dataSet, options = props.options, ariaLabel = props.ariaLabel, rest = __rest(props, ["testId", "isInverse", "type", "dataSet", "options", "ariaLabel"]);
|
|
2390
2532
|
var theme = React__namespace.useContext(reactMagmaDom.ThemeContext);
|
|
2391
2533
|
var isInverse = reactMagmaDom.useIsInverse(isInverseProp);
|
|
2534
|
+
var internalRef = React__namespace.useRef(null);
|
|
2535
|
+
var mergedRef = React__namespace.useCallback(function (node) {
|
|
2536
|
+
internalRef.current = node;
|
|
2537
|
+
if (typeof ref === 'function') {
|
|
2538
|
+
ref(node);
|
|
2539
|
+
}
|
|
2540
|
+
else if (ref) {
|
|
2541
|
+
ref.current = node;
|
|
2542
|
+
}
|
|
2543
|
+
}, [ref]);
|
|
2544
|
+
useCarbonModalFocusManagement(internalRef);
|
|
2392
2545
|
var allCharts = {
|
|
2393
2546
|
area: chartsReact.AreaChart,
|
|
2394
2547
|
areaStacked: chartsReact.StackedAreaChart,
|
|
@@ -2443,7 +2596,7 @@ var CarbonChart = React__namespace.forwardRef(function (props, ref) {
|
|
|
2443
2596
|
}
|
|
2444
2597
|
});
|
|
2445
2598
|
var groupsLength = Object.keys(buildColors()).length;
|
|
2446
|
-
return (React__namespace.createElement(CarbonChartWrapper, __assign({ "data-testid": testId, ref:
|
|
2599
|
+
return (React__namespace.createElement(CarbonChartWrapper, __assign({ "data-testid": testId, ref: mergedRef, isInverse: isInverse, theme: theme, className: "carbon-chart-wrapper", groupsLength: groupsLength < 6 ? groupsLength : 14 }, rest),
|
|
2447
2600
|
React__namespace.createElement(ChartType, { data: dataSet, options: newOptions })));
|
|
2448
2601
|
});
|
|
2449
2602
|
var templateObject_1;
|