feat(frontend): add API client, layout, and routing
- Create Axios-based API client with sources, jobs, and dashboard endpoints - Add responsive Layout component with navigation sidebar - Set up React Router with Dashboard, Backups, and Settings routes - Configure TanStack Query provider with default options - Use lucide-react for navigation icons
This commit is contained in:
+188
@@ -0,0 +1,188 @@
|
||||
// https://w3c.github.io/html-aria/#document-conformance-requirements-for-use-of-aria-attributes-in-html
|
||||
|
||||
import { presentationRoles } from "./util.mjs";
|
||||
|
||||
/**
|
||||
* Safe Element.localName for all supported environments
|
||||
* @param element
|
||||
*/
|
||||
export function getLocalName(element) {
|
||||
var _element$localName;
|
||||
return (// eslint-disable-next-line no-restricted-properties -- actual guard for environments without localName
|
||||
(_element$localName = element.localName) !== null && _element$localName !== void 0 ? _element$localName :
|
||||
// eslint-disable-next-line no-restricted-properties -- required for the fallback
|
||||
element.tagName.toLowerCase()
|
||||
);
|
||||
}
|
||||
var localNameToRoleMappings = {
|
||||
article: "article",
|
||||
aside: "complementary",
|
||||
button: "button",
|
||||
datalist: "listbox",
|
||||
dd: "definition",
|
||||
details: "group",
|
||||
dialog: "dialog",
|
||||
dt: "term",
|
||||
fieldset: "group",
|
||||
figure: "figure",
|
||||
// WARNING: Only with an accessible name
|
||||
form: "form",
|
||||
footer: "contentinfo",
|
||||
h1: "heading",
|
||||
h2: "heading",
|
||||
h3: "heading",
|
||||
h4: "heading",
|
||||
h5: "heading",
|
||||
h6: "heading",
|
||||
header: "banner",
|
||||
hr: "separator",
|
||||
html: "document",
|
||||
legend: "legend",
|
||||
li: "listitem",
|
||||
math: "math",
|
||||
main: "main",
|
||||
menu: "list",
|
||||
nav: "navigation",
|
||||
ol: "list",
|
||||
optgroup: "group",
|
||||
// WARNING: Only in certain context
|
||||
option: "option",
|
||||
output: "status",
|
||||
progress: "progressbar",
|
||||
// WARNING: Only with an accessible name
|
||||
section: "region",
|
||||
summary: "button",
|
||||
table: "table",
|
||||
tbody: "rowgroup",
|
||||
textarea: "textbox",
|
||||
tfoot: "rowgroup",
|
||||
// WARNING: Only in certain context
|
||||
td: "cell",
|
||||
th: "columnheader",
|
||||
thead: "rowgroup",
|
||||
tr: "row",
|
||||
ul: "list"
|
||||
};
|
||||
var prohibitedAttributes = {
|
||||
caption: new Set(["aria-label", "aria-labelledby"]),
|
||||
code: new Set(["aria-label", "aria-labelledby"]),
|
||||
deletion: new Set(["aria-label", "aria-labelledby"]),
|
||||
emphasis: new Set(["aria-label", "aria-labelledby"]),
|
||||
generic: new Set(["aria-label", "aria-labelledby", "aria-roledescription"]),
|
||||
insertion: new Set(["aria-label", "aria-labelledby"]),
|
||||
none: new Set(["aria-label", "aria-labelledby"]),
|
||||
paragraph: new Set(["aria-label", "aria-labelledby"]),
|
||||
presentation: new Set(["aria-label", "aria-labelledby"]),
|
||||
strong: new Set(["aria-label", "aria-labelledby"]),
|
||||
subscript: new Set(["aria-label", "aria-labelledby"]),
|
||||
superscript: new Set(["aria-label", "aria-labelledby"])
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param element
|
||||
* @param role The role used for this element. This is specified to control whether you want to use the implicit or explicit role.
|
||||
*/
|
||||
function hasGlobalAriaAttributes(element, role) {
|
||||
// https://rawgit.com/w3c/aria/stable/#global_states
|
||||
// commented attributes are deprecated
|
||||
return ["aria-atomic", "aria-busy", "aria-controls", "aria-current", "aria-description", "aria-describedby", "aria-details",
|
||||
// "disabled",
|
||||
"aria-dropeffect",
|
||||
// "errormessage",
|
||||
"aria-flowto", "aria-grabbed",
|
||||
// "haspopup",
|
||||
"aria-hidden",
|
||||
// "invalid",
|
||||
"aria-keyshortcuts", "aria-label", "aria-labelledby", "aria-live", "aria-owns", "aria-relevant", "aria-roledescription"].some(function (attributeName) {
|
||||
var _prohibitedAttributes;
|
||||
return element.hasAttribute(attributeName) && !((_prohibitedAttributes = prohibitedAttributes[role]) !== null && _prohibitedAttributes !== void 0 && _prohibitedAttributes.has(attributeName));
|
||||
});
|
||||
}
|
||||
function ignorePresentationalRole(element, implicitRole) {
|
||||
// https://rawgit.com/w3c/aria/stable/#conflict_resolution_presentation_none
|
||||
return hasGlobalAriaAttributes(element, implicitRole);
|
||||
}
|
||||
export default function getRole(element) {
|
||||
var explicitRole = getExplicitRole(element);
|
||||
if (explicitRole === null || presentationRoles.indexOf(explicitRole) !== -1) {
|
||||
var implicitRole = getImplicitRole(element);
|
||||
if (presentationRoles.indexOf(explicitRole || "") === -1 || ignorePresentationalRole(element, implicitRole || "")) {
|
||||
return implicitRole;
|
||||
}
|
||||
}
|
||||
return explicitRole;
|
||||
}
|
||||
function getImplicitRole(element) {
|
||||
var mappedByTag = localNameToRoleMappings[getLocalName(element)];
|
||||
if (mappedByTag !== undefined) {
|
||||
return mappedByTag;
|
||||
}
|
||||
switch (getLocalName(element)) {
|
||||
case "a":
|
||||
case "area":
|
||||
case "link":
|
||||
if (element.hasAttribute("href")) {
|
||||
return "link";
|
||||
}
|
||||
break;
|
||||
case "img":
|
||||
if (element.getAttribute("alt") === "" && !ignorePresentationalRole(element, "img")) {
|
||||
return "presentation";
|
||||
}
|
||||
return "img";
|
||||
case "input":
|
||||
{
|
||||
var _ref = element,
|
||||
type = _ref.type;
|
||||
switch (type) {
|
||||
case "button":
|
||||
case "image":
|
||||
case "reset":
|
||||
case "submit":
|
||||
return "button";
|
||||
case "checkbox":
|
||||
case "radio":
|
||||
return type;
|
||||
case "range":
|
||||
return "slider";
|
||||
case "email":
|
||||
case "tel":
|
||||
case "text":
|
||||
case "url":
|
||||
if (element.hasAttribute("list")) {
|
||||
return "combobox";
|
||||
}
|
||||
return "textbox";
|
||||
case "search":
|
||||
if (element.hasAttribute("list")) {
|
||||
return "combobox";
|
||||
}
|
||||
return "searchbox";
|
||||
case "number":
|
||||
return "spinbutton";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case "select":
|
||||
if (element.hasAttribute("multiple") || element.size > 1) {
|
||||
return "listbox";
|
||||
}
|
||||
return "combobox";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function getExplicitRole(element) {
|
||||
var role = element.getAttribute("role");
|
||||
if (role !== null) {
|
||||
var explicitRole = role.trim().split(" ")[0];
|
||||
// String.prototype.split(sep, limit) will always return an array with at least one member
|
||||
// as long as limit is either undefined or > 0
|
||||
if (explicitRole.length > 0) {
|
||||
return explicitRole;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
//# sourceMappingURL=getRole.mjs.map
|
||||
Reference in New Issue
Block a user