@primer/react
Version:
An implementation of GitHub's Primer Design System using React
191 lines (188 loc) • 7.13 kB
JavaScript
import { c } from 'react-compiler-runtime';
import { announce } from '@primer/live-region-element';
import { useEffect, useRef } from 'react';
// we add a delay so that it does not interrupt default screen reader announcement and queues after it
const delayMs = 500;
const useFirstRender = () => {
const firstRender = useRef(true);
useEffect(() => {
firstRender.current = false;
}, []);
// eslint-disable-next-line react-hooks/refs
return firstRender.current;
};
const getItemWithActiveDescendant = (listRef, items) => {
const listElement = listRef.current;
const activeItemElement = listElement === null || listElement === void 0 ? void 0 : listElement.querySelector('[data-is-active-descendant]');
if (!listElement || !(activeItemElement !== null && activeItemElement !== void 0 && activeItemElement.textContent)) return;
const optionElements = listElement.querySelectorAll('[role="option"]');
const index = Array.from(optionElements).indexOf(activeItemElement);
const activeItem = items[index];
const text = activeItem === null || activeItem === void 0 ? void 0 : activeItem.text;
const selected = activeItem === null || activeItem === void 0 ? void 0 : activeItem.selected;
return {
index,
text,
selected
};
};
const useAnnouncements = (items, listContainerRef, inputRef, t0, t1, message, focusManagement) => {
const $ = c(33);
const enabled = t0 === undefined ? true : t0;
const loading = t1 === undefined ? false : t1;
const usingRovingTabindex = focusManagement === "roving-tabindex";
let t2;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t2 = document.querySelector("live-region");
$[0] = t2;
} else {
t2 = $[0];
}
const liveRegion = t2;
let t3;
if ($[1] !== items) {
t3 = items.filter(_temp);
$[1] = items;
$[2] = t3;
} else {
t3 = $[2];
}
const selectedItems = t3.length;
let t4;
if ($[3] !== enabled) {
t4 = (...t5) => {
const args = t5;
if (enabled) {
return announce(...args);
}
};
$[3] = enabled;
$[4] = t4;
} else {
t4 = $[4];
}
const announce$1 = t4;
let t5;
let t6;
if ($[5] !== announce$1 || $[6] !== inputRef || $[7] !== items || $[8] !== listContainerRef || $[9] !== selectedItems || $[10] !== usingRovingTabindex) {
t5 = function announceInitialFocus() {
const focusHandler = () => {
if (usingRovingTabindex) {
const announcementText = `${items.length} item${items.length > 1 ? "s" : ""} available, ${selectedItems} selected.`;
announce$1(announcementText, {
delayMs,
from: liveRegion ? liveRegion : undefined
});
} else {
window.requestAnimationFrame(() => {
const activeItem = getItemWithActiveDescendant(listContainerRef, items);
if (!activeItem) {
return;
}
const {
index,
text,
selected
} = activeItem;
const announcementText_0 = ["Focus on filter text box and list of items", `Focused item: ${text}`, `${selected ? "selected" : "not selected"}`, `${index + 1} of ${items.length}`].join(", ");
announce$1(announcementText_0, {
delayMs,
from: liveRegion ? liveRegion : undefined
});
});
}
};
const inputElement = inputRef.current;
inputElement === null || inputElement === void 0 ? void 0 : inputElement.addEventListener("focus", focusHandler);
return () => inputElement === null || inputElement === void 0 ? void 0 : inputElement.removeEventListener("focus", focusHandler);
};
t6 = [listContainerRef, inputRef, items, liveRegion, announce$1, usingRovingTabindex, selectedItems];
$[5] = announce$1;
$[6] = inputRef;
$[7] = items;
$[8] = listContainerRef;
$[9] = selectedItems;
$[10] = usingRovingTabindex;
$[11] = t5;
$[12] = t6;
} else {
t5 = $[11];
t6 = $[12];
}
useEffect(t5, t6);
const isFirstRender = useFirstRender();
let t7;
if ($[13] !== announce$1 || $[14] !== isFirstRender || $[15] !== items || $[16] !== listContainerRef || $[17] !== loading || $[18] !== (message === null || message === void 0 ? void 0 : message.description) || $[19] !== (message === null || message === void 0 ? void 0 : message.title) || $[20] !== selectedItems || $[21] !== usingRovingTabindex) {
t7 = function announceListUpdates() {
if (isFirstRender) {
return;
}
liveRegion === null || liveRegion === void 0 ? void 0 : liveRegion.clear();
if (items.length === 0 && !loading) {
announce$1(`${message === null || message === void 0 ? void 0 : message.title}. ${message === null || message === void 0 ? void 0 : message.description}`, {
delayMs
});
return;
}
if (usingRovingTabindex) {
const announcementText_1 = `${items.length} item${items.length > 1 ? "s" : ""} available, ${selectedItems} selected.`;
announce$1(announcementText_1, {
delayMs,
from: liveRegion ? liveRegion : undefined
});
} else {
window.requestAnimationFrame(() => {
const activeItem_0 = getItemWithActiveDescendant(listContainerRef, items);
if (!activeItem_0) {
return;
}
const {
index: index_0,
text: text_0,
selected: selected_0
} = activeItem_0;
const announcementText_2 = ["List updated", `Focused item: ${text_0}`, `${selected_0 ? "selected" : "not selected"}`, `${index_0 + 1} of ${items.length}`].join(", ");
announce$1(announcementText_2, {
delayMs,
from: liveRegion ? liveRegion : undefined
});
});
}
};
$[13] = announce$1;
$[14] = isFirstRender;
$[15] = items;
$[16] = listContainerRef;
$[17] = loading;
$[18] = message === null || message === void 0 ? void 0 : message.description;
$[19] = message === null || message === void 0 ? void 0 : message.title;
$[20] = selectedItems;
$[21] = usingRovingTabindex;
$[22] = t7;
} else {
t7 = $[22];
}
const t8 = message === null || message === void 0 ? void 0 : message.title;
const t9 = message === null || message === void 0 ? void 0 : message.description;
let t10;
if ($[23] !== announce$1 || $[24] !== isFirstRender || $[25] !== items || $[26] !== listContainerRef || $[27] !== loading || $[28] !== selectedItems || $[29] !== t8 || $[30] !== t9 || $[31] !== usingRovingTabindex) {
t10 = [announce$1, isFirstRender, items, listContainerRef, liveRegion, usingRovingTabindex, t8, t9, loading, selectedItems];
$[23] = announce$1;
$[24] = isFirstRender;
$[25] = items;
$[26] = listContainerRef;
$[27] = loading;
$[28] = selectedItems;
$[29] = t8;
$[30] = t9;
$[31] = usingRovingTabindex;
$[32] = t10;
} else {
t10 = $[32];
}
useEffect(t7, t10);
};
function _temp(item) {
return item.selected;
}
export { useAnnouncements };