@vitessce/vit-s 3.1.1 → 3.1.2

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as React$6 from "react";
2
- import React__default, { Children, isValidElement, cloneElement as cloneElement$1, useReducer, useRef, useDebugValue, useEffect, useLayoutEffect, createContext as createContext$1, createElement, useContext, useMemo, useCallback, useState } from "react";
2
+ import React__default, { Children, isValidElement, cloneElement as cloneElement$1, useReducer, useRef, useDebugValue, useEffect, useLayoutEffect, createContext as createContext$1, createElement, useContext, useMemo, useCallback, useState, useId } from "react";
3
3
  import * as ReactDOM from "react-dom";
4
4
  import ReactDOM__default from "react-dom";
5
5
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
@@ -24493,6 +24493,363 @@ var z = /* @__PURE__ */ Object.freeze({
24493
24493
  quotelessJson,
24494
24494
  ZodError
24495
24495
  });
24496
+ function commonjsRequire(path) {
24497
+ throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
24498
+ }
24499
+ var pluralize = { exports: {} };
24500
+ (function(module2, exports2) {
24501
+ (function(root2, pluralize2) {
24502
+ if (typeof commonjsRequire === "function" && true && true) {
24503
+ module2.exports = pluralize2();
24504
+ } else {
24505
+ root2.pluralize = pluralize2();
24506
+ }
24507
+ })(commonjsGlobal, function() {
24508
+ var pluralRules = [];
24509
+ var singularRules = [];
24510
+ var uncountables = {};
24511
+ var irregularPlurals = {};
24512
+ var irregularSingles = {};
24513
+ function sanitizeRule(rule) {
24514
+ if (typeof rule === "string") {
24515
+ return new RegExp("^" + rule + "$", "i");
24516
+ }
24517
+ return rule;
24518
+ }
24519
+ function restoreCase(word, token) {
24520
+ if (word === token)
24521
+ return token;
24522
+ if (word === word.toLowerCase())
24523
+ return token.toLowerCase();
24524
+ if (word === word.toUpperCase())
24525
+ return token.toUpperCase();
24526
+ if (word[0] === word[0].toUpperCase()) {
24527
+ return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase();
24528
+ }
24529
+ return token.toLowerCase();
24530
+ }
24531
+ function interpolate(str, args) {
24532
+ return str.replace(/\$(\d{1,2})/g, function(match, index) {
24533
+ return args[index] || "";
24534
+ });
24535
+ }
24536
+ function replace(word, rule) {
24537
+ return word.replace(rule[0], function(match, index) {
24538
+ var result = interpolate(rule[1], arguments);
24539
+ if (match === "") {
24540
+ return restoreCase(word[index - 1], result);
24541
+ }
24542
+ return restoreCase(match, result);
24543
+ });
24544
+ }
24545
+ function sanitizeWord(token, word, rules) {
24546
+ if (!token.length || uncountables.hasOwnProperty(token)) {
24547
+ return word;
24548
+ }
24549
+ var len = rules.length;
24550
+ while (len--) {
24551
+ var rule = rules[len];
24552
+ if (rule[0].test(word))
24553
+ return replace(word, rule);
24554
+ }
24555
+ return word;
24556
+ }
24557
+ function replaceWord(replaceMap, keepMap, rules) {
24558
+ return function(word) {
24559
+ var token = word.toLowerCase();
24560
+ if (keepMap.hasOwnProperty(token)) {
24561
+ return restoreCase(word, token);
24562
+ }
24563
+ if (replaceMap.hasOwnProperty(token)) {
24564
+ return restoreCase(word, replaceMap[token]);
24565
+ }
24566
+ return sanitizeWord(token, word, rules);
24567
+ };
24568
+ }
24569
+ function checkWord(replaceMap, keepMap, rules, bool) {
24570
+ return function(word) {
24571
+ var token = word.toLowerCase();
24572
+ if (keepMap.hasOwnProperty(token))
24573
+ return true;
24574
+ if (replaceMap.hasOwnProperty(token))
24575
+ return false;
24576
+ return sanitizeWord(token, token, rules) === token;
24577
+ };
24578
+ }
24579
+ function pluralize2(word, count, inclusive) {
24580
+ var pluralized = count === 1 ? pluralize2.singular(word) : pluralize2.plural(word);
24581
+ return (inclusive ? count + " " : "") + pluralized;
24582
+ }
24583
+ pluralize2.plural = replaceWord(
24584
+ irregularSingles,
24585
+ irregularPlurals,
24586
+ pluralRules
24587
+ );
24588
+ pluralize2.isPlural = checkWord(
24589
+ irregularSingles,
24590
+ irregularPlurals,
24591
+ pluralRules
24592
+ );
24593
+ pluralize2.singular = replaceWord(
24594
+ irregularPlurals,
24595
+ irregularSingles,
24596
+ singularRules
24597
+ );
24598
+ pluralize2.isSingular = checkWord(
24599
+ irregularPlurals,
24600
+ irregularSingles,
24601
+ singularRules
24602
+ );
24603
+ pluralize2.addPluralRule = function(rule, replacement) {
24604
+ pluralRules.push([sanitizeRule(rule), replacement]);
24605
+ };
24606
+ pluralize2.addSingularRule = function(rule, replacement) {
24607
+ singularRules.push([sanitizeRule(rule), replacement]);
24608
+ };
24609
+ pluralize2.addUncountableRule = function(word) {
24610
+ if (typeof word === "string") {
24611
+ uncountables[word.toLowerCase()] = true;
24612
+ return;
24613
+ }
24614
+ pluralize2.addPluralRule(word, "$0");
24615
+ pluralize2.addSingularRule(word, "$0");
24616
+ };
24617
+ pluralize2.addIrregularRule = function(single, plural) {
24618
+ plural = plural.toLowerCase();
24619
+ single = single.toLowerCase();
24620
+ irregularSingles[single] = plural;
24621
+ irregularPlurals[plural] = single;
24622
+ };
24623
+ [
24624
+ // Pronouns.
24625
+ ["I", "we"],
24626
+ ["me", "us"],
24627
+ ["he", "they"],
24628
+ ["she", "they"],
24629
+ ["them", "them"],
24630
+ ["myself", "ourselves"],
24631
+ ["yourself", "yourselves"],
24632
+ ["itself", "themselves"],
24633
+ ["herself", "themselves"],
24634
+ ["himself", "themselves"],
24635
+ ["themself", "themselves"],
24636
+ ["is", "are"],
24637
+ ["was", "were"],
24638
+ ["has", "have"],
24639
+ ["this", "these"],
24640
+ ["that", "those"],
24641
+ // Words ending in with a consonant and `o`.
24642
+ ["echo", "echoes"],
24643
+ ["dingo", "dingoes"],
24644
+ ["volcano", "volcanoes"],
24645
+ ["tornado", "tornadoes"],
24646
+ ["torpedo", "torpedoes"],
24647
+ // Ends with `us`.
24648
+ ["genus", "genera"],
24649
+ ["viscus", "viscera"],
24650
+ // Ends with `ma`.
24651
+ ["stigma", "stigmata"],
24652
+ ["stoma", "stomata"],
24653
+ ["dogma", "dogmata"],
24654
+ ["lemma", "lemmata"],
24655
+ ["schema", "schemata"],
24656
+ ["anathema", "anathemata"],
24657
+ // Other irregular rules.
24658
+ ["ox", "oxen"],
24659
+ ["axe", "axes"],
24660
+ ["die", "dice"],
24661
+ ["yes", "yeses"],
24662
+ ["foot", "feet"],
24663
+ ["eave", "eaves"],
24664
+ ["goose", "geese"],
24665
+ ["tooth", "teeth"],
24666
+ ["quiz", "quizzes"],
24667
+ ["human", "humans"],
24668
+ ["proof", "proofs"],
24669
+ ["carve", "carves"],
24670
+ ["valve", "valves"],
24671
+ ["looey", "looies"],
24672
+ ["thief", "thieves"],
24673
+ ["groove", "grooves"],
24674
+ ["pickaxe", "pickaxes"],
24675
+ ["passerby", "passersby"]
24676
+ ].forEach(function(rule) {
24677
+ return pluralize2.addIrregularRule(rule[0], rule[1]);
24678
+ });
24679
+ [
24680
+ [/s?$/i, "s"],
24681
+ [/[^\u0000-\u007F]$/i, "$0"],
24682
+ [/([^aeiou]ese)$/i, "$1"],
24683
+ [/(ax|test)is$/i, "$1es"],
24684
+ [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, "$1es"],
24685
+ [/(e[mn]u)s?$/i, "$1s"],
24686
+ [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, "$1"],
24687
+ [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1i"],
24688
+ [/(alumn|alg|vertebr)(?:a|ae)$/i, "$1ae"],
24689
+ [/(seraph|cherub)(?:im)?$/i, "$1im"],
24690
+ [/(her|at|gr)o$/i, "$1oes"],
24691
+ [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, "$1a"],
24692
+ [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, "$1a"],
24693
+ [/sis$/i, "ses"],
24694
+ [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, "$1$2ves"],
24695
+ [/([^aeiouy]|qu)y$/i, "$1ies"],
24696
+ [/([^ch][ieo][ln])ey$/i, "$1ies"],
24697
+ [/(x|ch|ss|sh|zz)$/i, "$1es"],
24698
+ [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, "$1ices"],
24699
+ [/\b((?:tit)?m|l)(?:ice|ouse)$/i, "$1ice"],
24700
+ [/(pe)(?:rson|ople)$/i, "$1ople"],
24701
+ [/(child)(?:ren)?$/i, "$1ren"],
24702
+ [/eaux$/i, "$0"],
24703
+ [/m[ae]n$/i, "men"],
24704
+ ["thou", "you"]
24705
+ ].forEach(function(rule) {
24706
+ return pluralize2.addPluralRule(rule[0], rule[1]);
24707
+ });
24708
+ [
24709
+ [/s$/i, ""],
24710
+ [/(ss)$/i, "$1"],
24711
+ [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, "$1fe"],
24712
+ [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, "$1f"],
24713
+ [/ies$/i, "y"],
24714
+ [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, "$1ie"],
24715
+ [/\b(mon|smil)ies$/i, "$1ey"],
24716
+ [/\b((?:tit)?m|l)ice$/i, "$1ouse"],
24717
+ [/(seraph|cherub)im$/i, "$1"],
24718
+ [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, "$1"],
24719
+ [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, "$1sis"],
24720
+ [/(movie|twelve|abuse|e[mn]u)s$/i, "$1"],
24721
+ [/(test)(?:is|es)$/i, "$1is"],
24722
+ [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1us"],
24723
+ [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, "$1um"],
24724
+ [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, "$1on"],
24725
+ [/(alumn|alg|vertebr)ae$/i, "$1a"],
24726
+ [/(cod|mur|sil|vert|ind)ices$/i, "$1ex"],
24727
+ [/(matr|append)ices$/i, "$1ix"],
24728
+ [/(pe)(rson|ople)$/i, "$1rson"],
24729
+ [/(child)ren$/i, "$1"],
24730
+ [/(eau)x?$/i, "$1"],
24731
+ [/men$/i, "man"]
24732
+ ].forEach(function(rule) {
24733
+ return pluralize2.addSingularRule(rule[0], rule[1]);
24734
+ });
24735
+ [
24736
+ // Singular words with no plurals.
24737
+ "adulthood",
24738
+ "advice",
24739
+ "agenda",
24740
+ "aid",
24741
+ "aircraft",
24742
+ "alcohol",
24743
+ "ammo",
24744
+ "analytics",
24745
+ "anime",
24746
+ "athletics",
24747
+ "audio",
24748
+ "bison",
24749
+ "blood",
24750
+ "bream",
24751
+ "buffalo",
24752
+ "butter",
24753
+ "carp",
24754
+ "cash",
24755
+ "chassis",
24756
+ "chess",
24757
+ "clothing",
24758
+ "cod",
24759
+ "commerce",
24760
+ "cooperation",
24761
+ "corps",
24762
+ "debris",
24763
+ "diabetes",
24764
+ "digestion",
24765
+ "elk",
24766
+ "energy",
24767
+ "equipment",
24768
+ "excretion",
24769
+ "expertise",
24770
+ "firmware",
24771
+ "flounder",
24772
+ "fun",
24773
+ "gallows",
24774
+ "garbage",
24775
+ "graffiti",
24776
+ "hardware",
24777
+ "headquarters",
24778
+ "health",
24779
+ "herpes",
24780
+ "highjinks",
24781
+ "homework",
24782
+ "housework",
24783
+ "information",
24784
+ "jeans",
24785
+ "justice",
24786
+ "kudos",
24787
+ "labour",
24788
+ "literature",
24789
+ "machinery",
24790
+ "mackerel",
24791
+ "mail",
24792
+ "media",
24793
+ "mews",
24794
+ "moose",
24795
+ "music",
24796
+ "mud",
24797
+ "manga",
24798
+ "news",
24799
+ "only",
24800
+ "personnel",
24801
+ "pike",
24802
+ "plankton",
24803
+ "pliers",
24804
+ "police",
24805
+ "pollution",
24806
+ "premises",
24807
+ "rain",
24808
+ "research",
24809
+ "rice",
24810
+ "salmon",
24811
+ "scissors",
24812
+ "series",
24813
+ "sewage",
24814
+ "shambles",
24815
+ "shrimp",
24816
+ "software",
24817
+ "species",
24818
+ "staff",
24819
+ "swine",
24820
+ "tennis",
24821
+ "traffic",
24822
+ "transportation",
24823
+ "trout",
24824
+ "tuna",
24825
+ "wealth",
24826
+ "welfare",
24827
+ "whiting",
24828
+ "wildebeest",
24829
+ "wildlife",
24830
+ "you",
24831
+ /pok[eé]mon$/i,
24832
+ // Regexes.
24833
+ /[^aeiou]ese$/i,
24834
+ // "chinese", "japanese"
24835
+ /deer$/i,
24836
+ // "deer", "reindeer"
24837
+ /fish$/i,
24838
+ // "fish", "blowfish", "angelfish"
24839
+ /measles$/i,
24840
+ /o[iu]s$/i,
24841
+ // "carnivorous"
24842
+ /pox$/i,
24843
+ // "chickpox", "smallpox"
24844
+ /sheep$/i
24845
+ ].forEach(pluralize2.addUncountableRule);
24846
+ return pluralize2;
24847
+ });
24848
+ })(pluralize);
24849
+ var pluralizeExports = pluralize.exports;
24850
+ const plur = /* @__PURE__ */ getDefaultExportFromCjs(pluralizeExports);
24851
+ plur.addPluralRule("glomerulus", "glomeruli");
24852
+ plur.addPluralRule("interstitium", "interstitia");
24496
24853
  function fromEntries(iterable) {
24497
24854
  return [...iterable].reduce((obj, { 0: key, 1: val }) => Object.assign(obj, { [key]: val }), {});
24498
24855
  }
@@ -34851,10 +35208,10 @@ const AUTO_INDEPENDENT_COORDINATION_TYPES = [
34851
35208
  CoordinationType$1.EMBEDDING_OBS_OPACITY
34852
35209
  ];
34853
35210
  const note = "This file is autogenerated by .changeset/post-changelog.mjs.";
34854
- const version = "3.1.1";
34855
- const date = "2023-08-02";
35211
+ const version = "3.1.2";
35212
+ const date = "2023-08-31";
34856
35213
  const branch = "changeset-release/main";
34857
- const hash = "0dbc5e39";
35214
+ const hash = "21819ea1";
34858
35215
  const META_VERSION = {
34859
35216
  note,
34860
35217
  version,
@@ -43189,11 +43546,22 @@ const useStyles$3 = makeStyles(() => ({
43189
43546
  position: "absolute",
43190
43547
  width: "100%",
43191
43548
  height: "100%"
43549
+ },
43550
+ visuallyHidden: {
43551
+ position: "absolute",
43552
+ height: "1px",
43553
+ width: "1px",
43554
+ overflow: "hidden",
43555
+ clip: "rect(1px, 1px, 1px, 1px)",
43556
+ whiteSpace: "nowrap"
43192
43557
  }
43193
43558
  }));
43194
43559
  function LoadingIndicator() {
43195
43560
  const classes = useStyles$3();
43196
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: classes.loadingIndicatorBackdrop, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: classes.loadingIndicatorContainer, children: /* @__PURE__ */ jsxRuntimeExports.jsx(CircularProgress$1, {}) }) });
43561
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: classes.loadingIndicatorBackdrop, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: classes.loadingIndicatorContainer, role: "status", "aria-live": "polite", children: [
43562
+ /* @__PURE__ */ jsxRuntimeExports.jsx(CircularProgress$1, {}),
43563
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: classes.visuallyHidden, children: "Loading..." })
43564
+ ] }) });
43197
43565
  }
43198
43566
  const useStyles$2 = makeStyles(() => ({
43199
43567
  paper: {
@@ -43213,7 +43581,8 @@ function PopperMenu(props) {
43213
43581
  setOpen,
43214
43582
  children: children2,
43215
43583
  buttonClassName,
43216
- placement = "bottom-end"
43584
+ placement = "bottom-end",
43585
+ "aria-label": ariaLabel
43217
43586
  } = props;
43218
43587
  const classes = useStyles$2();
43219
43588
  const anchorRef = useRef();
@@ -43231,8 +43600,10 @@ function PopperMenu(props) {
43231
43600
  {
43232
43601
  "aria-describedby": id,
43233
43602
  onClick: handleClick,
43603
+ onTouchEnd: handleClick,
43234
43604
  size: "small",
43235
43605
  className: buttonClassName,
43606
+ "aria-label": ariaLabel,
43236
43607
  children: buttonIcon
43237
43608
  }
43238
43609
  ),
@@ -43298,6 +43669,7 @@ function PlotOptions(props) {
43298
43669
  buttonIcon: /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsIconWithArrow, { open }),
43299
43670
  buttonClassName: classes.iconButton,
43300
43671
  placement: "bottom-end",
43672
+ "aria-label": "Open plot options menu",
43301
43673
  children: options
43302
43674
  }
43303
43675
  ) : null;
@@ -43320,7 +43692,8 @@ function DownloadOptions(props) {
43320
43692
  buttonIcon: /* @__PURE__ */ jsxRuntimeExports.jsx(CloudDownloadIconWithArrow, { open }),
43321
43693
  buttonClassName: classes.iconButton,
43322
43694
  placement: "bottom-end",
43323
- children: urls.map(({ url, name }) => /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItem$1, { dense: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Link$1, { underline: "none", href: url, target: "_blank", rel: "noopener", className: classes.downloadLink, children: [
43695
+ "aria-label": "Open download options menu",
43696
+ children: urls.map(({ url, name }) => /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItem$1, { dense: true, getArialLabel: () => `Click to download ${name}`, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Link$1, { underline: "always", href: url, target: "_blank", rel: "noopener", className: classes.downloadLink, children: [
43324
43697
  "Download ",
43325
43698
  name
43326
43699
  ] }) }, `${url}_${name}`))
@@ -43337,6 +43710,7 @@ function ClosePaneButton(props) {
43337
43710
  size: "small",
43338
43711
  className: classes.iconButton,
43339
43712
  title: "close",
43713
+ "aria-label": "Close panel button",
43340
43714
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(CloseIcon, {})
43341
43715
  }
43342
43716
  );
@@ -43357,10 +43731,10 @@ function TitleInfo(props) {
43357
43731
  return (
43358
43732
  // d-flex without wrapping div is not always full height; I don't understand the root cause.
43359
43733
  /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
43360
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: classes.title, children: [
43361
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: classes.titleLeft, children: title }),
43362
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: classes.titleInfo, title: info, children: info }),
43363
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: classes.titleButtons, children: [
43734
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: classes.title, role: "banner", children: [
43735
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: classes.titleLeft, role: "heading", "aria-level": "1", children: title }),
43736
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: classes.titleInfo, title: info, role: "note", children: info }),
43737
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: classes.titleButtons, role: "toolbar", "aria-label": "Plot options and controls", children: [
43364
43738
  /* @__PURE__ */ jsxRuntimeExports.jsx(
43365
43739
  PlotOptions,
43366
43740
  {
@@ -43393,6 +43767,8 @@ function TitleInfo(props) {
43393
43767
  [classes.noScrollCard]: !isScroll && !isSpatial
43394
43768
  }
43395
43769
  ),
43770
+ "aria-busy": !isReady,
43771
+ role: "main",
43396
43772
  children: [
43397
43773
  !isReady && /* @__PURE__ */ jsxRuntimeExports.jsx(LoadingIndicator, {}),
43398
43774
  children2
@@ -43989,7 +44365,8 @@ function OptionSelect(props) {
43989
44365
  classes: {
43990
44366
  root: classes.optionSelectRoot,
43991
44367
  ...classesProp
43992
- }
44368
+ },
44369
+ "aria-label": "Select an option"
43993
44370
  }
43994
44371
  );
43995
44372
  }
@@ -44000,23 +44377,30 @@ function CellColorEncodingOption(props) {
44000
44377
  setCellColorEncoding
44001
44378
  } = props;
44002
44379
  const classes = useStyles();
44380
+ const cellColorEncodingId = useId();
44003
44381
  const observationsLabelNice = capitalize(observationsLabel);
44004
44382
  function handleColorEncodingChange(event) {
44005
44383
  setCellColorEncoding(event.target.value);
44006
44384
  }
44007
44385
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(TableRow$1, { children: [
44008
- /* @__PURE__ */ jsxRuntimeExports.jsxs(TableCell$1, { className: classes.labelCell, htmlFor: "cell-color-encoding-select", children: [
44009
- observationsLabelNice,
44010
- " Color Encoding"
44011
- ] }),
44012
- /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
44386
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
44387
+ "label",
44388
+ {
44389
+ htmlFor: `cell-color-encoding-select-${cellColorEncodingId}`,
44390
+ children: [
44391
+ observationsLabelNice,
44392
+ " Color Encoding"
44393
+ ]
44394
+ }
44395
+ ) }),
44396
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
44013
44397
  OptionSelect,
44014
44398
  {
44015
44399
  className: classes.select,
44016
44400
  value: cellColorEncoding,
44017
44401
  onChange: handleColorEncodingChange,
44018
44402
  inputProps: {
44019
- id: "cell-color-encoding-select"
44403
+ id: `cell-color-encoding-select-${cellColorEncodingId}`
44020
44404
  },
44021
44405
  children: [
44022
44406
  /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "cellSetSelection", children: "Cell Sets" }),
@@ -44031,7 +44415,15 @@ function OptionsContainer(props) {
44031
44415
  children: children2
44032
44416
  } = props;
44033
44417
  const classes = useStyles();
44034
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Box$1, { className: classes.box, children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableContainer$1, { className: classes.tableContainer, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Table$1, { className: classes.table, size: "small", children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableBody$1, { children: children2 }) }) }) });
44418
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Box$1, { className: classes.box, children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableContainer$1, { className: classes.tableContainer, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44419
+ Table$1,
44420
+ {
44421
+ className: classes.table,
44422
+ size: "small",
44423
+ "aria-label": "Menu of options available for the view",
44424
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableBody$1, { children: children2 })
44425
+ }
44426
+ ) }) });
44035
44427
  }
44036
44428
  export {
44037
44429
  AbstractLoader,
@@ -1 +1 @@
1
- {"version":3,"file":"LoadingIndicator.d.ts","sourceRoot":"","sources":["../src/LoadingIndicator.js"],"names":[],"mappings":"AAuBA,wDASC"}
1
+ {"version":3,"file":"LoadingIndicator.d.ts","sourceRoot":"","sources":["../src/LoadingIndicator.js"],"names":[],"mappings":"AA+BA,wDAUC"}
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { makeStyles, CircularProgress } from '@material-ui/core';
4
4
  const useStyles = makeStyles(() => ({
@@ -19,8 +19,16 @@ const useStyles = makeStyles(() => ({
19
19
  width: '100%',
20
20
  height: '100%',
21
21
  },
22
+ visuallyHidden: {
23
+ position: 'absolute',
24
+ height: '1px',
25
+ width: '1px',
26
+ overflow: 'hidden',
27
+ clip: 'rect(1px, 1px, 1px, 1px)',
28
+ whiteSpace: 'nowrap',
29
+ },
22
30
  }));
23
31
  export default function LoadingIndicator() {
24
32
  const classes = useStyles();
25
- return (_jsx("div", { className: classes.loadingIndicatorBackdrop, children: _jsx("div", { className: classes.loadingIndicatorContainer, children: _jsx(CircularProgress, {}) }) }));
33
+ return (_jsx("div", { className: classes.loadingIndicatorBackdrop, children: _jsxs("div", { className: classes.loadingIndicatorContainer, role: "status", "aria-live": "polite", children: [_jsx(CircularProgress, {}), _jsx("span", { className: classes.visuallyHidden, children: "Loading..." })] }) }));
26
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TitleInfo.d.ts","sourceRoot":"","sources":["../src/TitleInfo.js"],"names":[],"mappings":"AAuHA,mDA+CC"}
1
+ {"version":3,"file":"TitleInfo.d.ts","sourceRoot":"","sources":["../src/TitleInfo.js"],"names":[],"mappings":"AA0HA,mDAiDC"}
@@ -43,7 +43,7 @@ function PlotOptions(props) {
43
43
  const { options } = props;
44
44
  const [open, setOpen] = useState(false);
45
45
  const classes = useStyles();
46
- return (options ? (_jsx(PopperMenu, { open: open, setOpen: setOpen, buttonIcon: _jsx(SettingsIconWithArrow, { open: open }), buttonClassName: classes.iconButton, placement: "bottom-end", children: options })) : null);
46
+ return (options ? (_jsx(PopperMenu, { open: open, setOpen: setOpen, buttonIcon: _jsx(SettingsIconWithArrow, { open: open }), buttonClassName: classes.iconButton, placement: "bottom-end", "aria-label": "Open plot options menu", children: options })) : null);
47
47
  }
48
48
  function CloudDownloadIconWithArrow({ open }) {
49
49
  return (_jsxs(_Fragment, { children: [_jsx(CloudDownloadIcon, {}), open ? _jsx(ArrowDropUpIcon, {}) : _jsx(ArrowDropDownIcon, {})] }));
@@ -52,23 +52,23 @@ function DownloadOptions(props) {
52
52
  const { urls } = props;
53
53
  const [open, setOpen] = useState(false);
54
54
  const classes = useStyles();
55
- return (urls && urls.length ? (_jsx(PopperMenu, { open: open, setOpen: setOpen, buttonIcon: _jsx(CloudDownloadIconWithArrow, { open: open }), buttonClassName: classes.iconButton, placement: "bottom-end", children: urls.map(({ url, name }) => (_jsx(MenuItem, { dense: true, children: _jsxs(Link, { underline: "none", href: url, target: "_blank", rel: "noopener", className: classes.downloadLink, children: ["Download ", name] }) }, `${url}_${name}`))) })) : null);
55
+ return (urls && urls.length ? (_jsx(PopperMenu, { open: open, setOpen: setOpen, buttonIcon: _jsx(CloudDownloadIconWithArrow, { open: open }), buttonClassName: classes.iconButton, placement: "bottom-end", "aria-label": "Open download options menu", children: urls.map(({ url, name }) => (_jsx(MenuItem, { dense: true, getArialLabel: () => `Click to download ${name}`, children: _jsxs(Link, { underline: "always", href: url, target: "_blank", rel: "noopener", className: classes.downloadLink, children: ["Download ", name] }) }, `${url}_${name}`))) })) : null);
56
56
  }
57
57
  function ClosePaneButton(props) {
58
58
  const { removeGridComponent } = props;
59
59
  const classes = useStyles();
60
- return (_jsx(IconButton, { onClick: removeGridComponent, size: "small", className: classes.iconButton, title: "close", children: _jsx(CloseIcon, {}) }));
60
+ return (_jsx(IconButton, { onClick: removeGridComponent, size: "small", className: classes.iconButton, title: "close", "aria-label": "Close panel button", children: _jsx(CloseIcon, {}) }));
61
61
  }
62
62
  export function TitleInfo(props) {
63
63
  const { title, info, children, isScroll, isSpatial, removeGridComponent, urls, isReady, options, } = props;
64
64
  const classes = useTitleStyles();
65
65
  return (
66
66
  // d-flex without wrapping div is not always full height; I don't understand the root cause.
67
- _jsxs(_Fragment, { children: [_jsxs("div", { className: classes.title, children: [_jsx("div", { className: classes.titleLeft, children: title }), _jsx("div", { className: classes.titleInfo, title: info, children: info }), _jsxs("div", { className: classes.titleButtons, children: [_jsx(PlotOptions, { options: options }), _jsx(DownloadOptions, { urls: urls }), _jsx(ClosePaneButton, { removeGridComponent: removeGridComponent })] })] }), _jsxs("div", { className: clsx(TOOLTIP_ANCESTOR, classes.card, {
67
+ _jsxs(_Fragment, { children: [_jsxs("div", { className: classes.title, role: "banner", children: [_jsx("div", { className: classes.titleLeft, role: "heading", "aria-level": "1", children: title }), _jsx("div", { className: classes.titleInfo, title: info, role: "note", children: info }), _jsxs("div", { className: classes.titleButtons, role: "toolbar", "aria-label": "Plot options and controls", children: [_jsx(PlotOptions, { options: options }), _jsx(DownloadOptions, { urls: urls }), _jsx(ClosePaneButton, { removeGridComponent: removeGridComponent })] })] }), _jsxs("div", { className: clsx(TOOLTIP_ANCESTOR, classes.card, {
68
68
  [classes.scrollCard]: isScroll,
69
69
  [classes.spatialCard]: isSpatial,
70
70
  [classes.noScrollCard]: !isScroll && !isSpatial,
71
- }), children: [!isReady && _jsx(LoadingIndicator, {}), children] })] })
71
+ }), "aria-busy": !isReady, role: "main", children: [!isReady && _jsx(LoadingIndicator, {}), children] })] })
72
72
  // "pl-2" only matters when the window is very narrow.
73
73
  );
74
74
  }
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/shared-mui/components.js"],"names":[],"mappings":"AAwBA,oDAwDC"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/shared-mui/components.js"],"names":[],"mappings":"AAwBA,oDA2DC"}
@@ -14,7 +14,7 @@ const useStyles = makeStyles(() => ({
14
14
  },
15
15
  }));
16
16
  export function PopperMenu(props) {
17
- const { buttonIcon, open, setOpen, children, buttonClassName, placement = 'bottom-end', } = props;
17
+ const { buttonIcon, open, setOpen, children, buttonClassName, placement = 'bottom-end', 'aria-label': ariaLabel, } = props;
18
18
  const classes = useStyles();
19
19
  const anchorRef = useRef();
20
20
  const handleClick = () => {
@@ -25,5 +25,5 @@ export function PopperMenu(props) {
25
25
  };
26
26
  const id = open ? 'v-popover-menu' : undefined;
27
27
  const getTooltipContainer = useVitessceContainer(anchorRef);
28
- return (_jsxs("div", { ref: anchorRef, className: classes.container, children: [_jsx(IconButton, { "aria-describedby": id, onClick: handleClick, size: "small", className: buttonClassName, children: buttonIcon }), _jsx(Popper, { id: id, open: open, anchorEl: anchorRef && anchorRef.current, container: getTooltipContainer, onClose: handleClose, placement: placement, transition: true, children: ({ TransitionProps }) => (_jsx(ClickAwayListener, { onClickAway: handleClose, children: _jsx(Fade, { ...TransitionProps, timeout: 100, children: _jsx(Paper, { elevation: 4, className: classes.paper, children: _jsx(MenuList, { children: children }) }) }) })) })] }));
28
+ return (_jsxs("div", { ref: anchorRef, className: classes.container, children: [_jsx(IconButton, { "aria-describedby": id, onClick: handleClick, onTouchEnd: handleClick, size: "small", className: buttonClassName, "aria-label": ariaLabel, children: buttonIcon }), _jsx(Popper, { id: id, open: open, anchorEl: anchorRef && anchorRef.current, container: getTooltipContainer, onClose: handleClose, placement: placement, transition: true, children: ({ TransitionProps }) => (_jsx(ClickAwayListener, { onClickAway: handleClose, children: _jsx(Fade, { ...TransitionProps, timeout: 100, children: _jsx(Paper, { elevation: 4, className: classes.paper, children: _jsx(MenuList, { children: children }) }) }) })) })] }));
29
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CellColorEncodingOption.d.ts","sourceRoot":"","sources":["../../src/shared-plot-options/CellColorEncodingOption.js"],"names":[],"mappings":"AAMA,yEAmCC"}
1
+ {"version":3,"file":"CellColorEncodingOption.d.ts","sourceRoot":"","sources":["../../src/shared-plot-options/CellColorEncodingOption.js"],"names":[],"mappings":"AAMA,yEAyCC"}
@@ -1,5 +1,5 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import React from 'react';
2
+ import React, { useId } from 'react';
3
3
  import { TableCell, TableRow } from '@material-ui/core';
4
4
  import { capitalize } from '@vitessce/utils';
5
5
  import OptionSelect from './OptionSelect.js';
@@ -7,11 +7,12 @@ import { useStyles } from './styles.js';
7
7
  export default function CellColorEncodingOption(props) {
8
8
  const { observationsLabel, cellColorEncoding, setCellColorEncoding, } = props;
9
9
  const classes = useStyles();
10
+ const cellColorEncodingId = useId();
10
11
  const observationsLabelNice = capitalize(observationsLabel);
11
12
  function handleColorEncodingChange(event) {
12
13
  setCellColorEncoding(event.target.value);
13
14
  }
14
- return (_jsxs(TableRow, { children: [_jsxs(TableCell, { className: classes.labelCell, htmlFor: "cell-color-encoding-select", children: [observationsLabelNice, " Color Encoding"] }), _jsx(TableCell, { className: classes.inputCell, children: _jsxs(OptionSelect, { className: classes.select, value: cellColorEncoding, onChange: handleColorEncodingChange, inputProps: {
15
- id: 'cell-color-encoding-select',
15
+ return (_jsxs(TableRow, { children: [_jsx(TableCell, { className: classes.labelCell, variant: "head", scope: "row", children: _jsxs("label", { htmlFor: `cell-color-encoding-select-${cellColorEncodingId}`, children: [observationsLabelNice, " Color Encoding"] }) }), _jsx(TableCell, { className: classes.inputCell, variant: "body", children: _jsxs(OptionSelect, { className: classes.select, value: cellColorEncoding, onChange: handleColorEncodingChange, inputProps: {
16
+ id: `cell-color-encoding-select-${cellColorEncodingId}`,
16
17
  }, children: [_jsx("option", { value: "cellSetSelection", children: "Cell Sets" }), _jsx("option", { value: "geneSelection", children: "Gene Expression" })] }) })] }));
17
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"OptionSelect.d.ts","sourceRoot":"","sources":["../../src/shared-plot-options/OptionSelect.js"],"names":[],"mappings":"AAIA,8DAcC"}
1
+ {"version":3,"file":"OptionSelect.d.ts","sourceRoot":"","sources":["../../src/shared-plot-options/OptionSelect.js"],"names":[],"mappings":"AAIA,8DAeC"}
@@ -8,5 +8,5 @@ export default function OptionSelect(props) {
8
8
  return (_jsx(Select, { native: true, disableUnderline: true, ...props, classes: {
9
9
  root: classes.optionSelectRoot,
10
10
  ...classesProp,
11
- } }));
11
+ }, "aria-label": "Select an option" }));
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"OptionsContainer.d.ts","sourceRoot":"","sources":["../../src/shared-plot-options/OptionsContainer.js"],"names":[],"mappings":"AAIA,kEAkBC"}
1
+ {"version":3,"file":"OptionsContainer.d.ts","sourceRoot":"","sources":["../../src/shared-plot-options/OptionsContainer.js"],"names":[],"mappings":"AAIA,kEAsBC"}
@@ -5,5 +5,5 @@ import { useStyles } from './styles.js';
5
5
  export default function OptionsContainer(props) {
6
6
  const { children, } = props;
7
7
  const classes = useStyles();
8
- return (_jsx(Box, { className: classes.box, children: _jsx(TableContainer, { className: classes.tableContainer, children: _jsx(Table, { className: classes.table, size: "small", children: _jsx(TableBody, { children: children }) }) }) }));
8
+ return (_jsx(Box, { className: classes.box, children: _jsx(TableContainer, { className: classes.tableContainer, children: _jsx(Table, { className: classes.table, size: "small", "aria-label": "Menu of options available for the view", children: _jsx(TableBody, { children: children }) }) }) }));
9
9
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitessce/vit-s",
3
- "version": "3.1.1",
3
+ "version": "3.1.2",
4
4
  "author": "Gehlenborg Lab",
5
5
  "homepage": "http://vitessce.io",
6
6
  "repository": {
@@ -28,10 +28,10 @@
28
28
  "react-grid-layout-with-lodash": "^1.3.5",
29
29
  "uuid": "^9.0.0",
30
30
  "zustand": "^3.5.10",
31
- "@vitessce/constants-internal": "3.1.1",
32
- "@vitessce/plugins": "3.1.1",
33
- "@vitessce/schemas": "3.1.1",
34
- "@vitessce/utils": "3.1.1"
31
+ "@vitessce/constants-internal": "3.1.2",
32
+ "@vitessce/plugins": "3.1.2",
33
+ "@vitessce/schemas": "3.1.2",
34
+ "@vitessce/utils": "3.1.2"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@testing-library/jest-dom": "^5.16.4",
@@ -19,14 +19,23 @@ const useStyles = makeStyles(() => ({
19
19
  width: '100%',
20
20
  height: '100%',
21
21
  },
22
+ visuallyHidden: {
23
+ position: 'absolute',
24
+ height: '1px',
25
+ width: '1px',
26
+ overflow: 'hidden',
27
+ clip: 'rect(1px, 1px, 1px, 1px)',
28
+ whiteSpace: 'nowrap',
29
+ },
22
30
  }));
23
31
 
24
32
  export default function LoadingIndicator() {
25
33
  const classes = useStyles();
26
34
  return (
27
35
  <div className={classes.loadingIndicatorBackdrop}>
28
- <div className={classes.loadingIndicatorContainer}>
36
+ <div className={classes.loadingIndicatorContainer} role="status" aria-live="polite">
29
37
  <CircularProgress />
38
+ <span className={classes.visuallyHidden}>Loading...</span>
30
39
  </div>
31
40
  </div>
32
41
  );
package/src/TitleInfo.js CHANGED
@@ -64,6 +64,7 @@ function PlotOptions(props) {
64
64
  buttonIcon={<SettingsIconWithArrow open={open} />}
65
65
  buttonClassName={classes.iconButton}
66
66
  placement="bottom-end"
67
+ aria-label="Open plot options menu"
67
68
  >
68
69
  {options}
69
70
  </PopperMenu>
@@ -90,10 +91,11 @@ function DownloadOptions(props) {
90
91
  buttonIcon={<CloudDownloadIconWithArrow open={open} />}
91
92
  buttonClassName={classes.iconButton}
92
93
  placement="bottom-end"
94
+ aria-label="Open download options menu"
93
95
  >
94
96
  {urls.map(({ url, name }) => (
95
- <MenuItem dense key={`${url}_${name}`}>
96
- <Link underline="none" href={url} target="_blank" rel="noopener" className={classes.downloadLink}>
97
+ <MenuItem dense key={`${url}_${name}`} getArialLabel={() => `Click to download ${name}`}>
98
+ <Link underline="always" href={url} target="_blank" rel="noopener" className={classes.downloadLink}>
97
99
  Download {name}
98
100
  </Link>
99
101
  </MenuItem>
@@ -111,6 +113,7 @@ function ClosePaneButton(props) {
111
113
  size="small"
112
114
  className={classes.iconButton}
113
115
  title="close"
116
+ aria-label="Close panel button"
114
117
  >
115
118
  <CloseIcon />
116
119
  </IconButton>
@@ -128,14 +131,14 @@ export function TitleInfo(props) {
128
131
  return (
129
132
  // d-flex without wrapping div is not always full height; I don't understand the root cause.
130
133
  <>
131
- <div className={classes.title}>
132
- <div className={classes.titleLeft}>
134
+ <div className={classes.title} role="banner">
135
+ <div className={classes.titleLeft} role="heading" aria-level="1">
133
136
  {title}
134
137
  </div>
135
- <div className={classes.titleInfo} title={info}>
138
+ <div className={classes.titleInfo} title={info} role="note">
136
139
  {info}
137
140
  </div>
138
- <div className={classes.titleButtons}>
141
+ <div className={classes.titleButtons} role="toolbar" aria-label="Plot options and controls">
139
142
  <PlotOptions
140
143
  options={options}
141
144
  />
@@ -157,6 +160,8 @@ export function TitleInfo(props) {
157
160
  [classes.noScrollCard]: !isScroll && !isSpatial,
158
161
  },
159
162
  )}
163
+ aria-busy={!isReady}
164
+ role="main"
160
165
  >
161
166
  { !isReady && <LoadingIndicator /> }
162
167
  {children}
@@ -30,6 +30,7 @@ export function PopperMenu(props) {
30
30
  children,
31
31
  buttonClassName,
32
32
  placement = 'bottom-end',
33
+ 'aria-label': ariaLabel,
33
34
  } = props;
34
35
  const classes = useStyles();
35
36
 
@@ -52,8 +53,10 @@ export function PopperMenu(props) {
52
53
  <IconButton
53
54
  aria-describedby={id}
54
55
  onClick={handleClick}
56
+ onTouchEnd={handleClick}
55
57
  size="small"
56
58
  className={buttonClassName}
59
+ aria-label={ariaLabel}
57
60
  >
58
61
  {buttonIcon}
59
62
  </IconButton>
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useId } from 'react';
2
2
  import { TableCell, TableRow } from '@material-ui/core';
3
3
  import { capitalize } from '@vitessce/utils';
4
4
  import OptionSelect from './OptionSelect.js';
@@ -13,6 +13,8 @@ export default function CellColorEncodingOption(props) {
13
13
 
14
14
  const classes = useStyles();
15
15
 
16
+ const cellColorEncodingId = useId();
17
+
16
18
  const observationsLabelNice = capitalize(observationsLabel);
17
19
 
18
20
  function handleColorEncodingChange(event) {
@@ -21,16 +23,20 @@ export default function CellColorEncodingOption(props) {
21
23
 
22
24
  return (
23
25
  <TableRow>
24
- <TableCell className={classes.labelCell} htmlFor="cell-color-encoding-select">
25
- {observationsLabelNice} Color Encoding
26
+ <TableCell className={classes.labelCell} variant="head" scope="row">
27
+ <label
28
+ htmlFor={`cell-color-encoding-select-${cellColorEncodingId}`}
29
+ >
30
+ {observationsLabelNice} Color Encoding
31
+ </label>
26
32
  </TableCell>
27
- <TableCell className={classes.inputCell}>
33
+ <TableCell className={classes.inputCell} variant="body">
28
34
  <OptionSelect
29
35
  className={classes.select}
30
36
  value={cellColorEncoding}
31
37
  onChange={handleColorEncodingChange}
32
38
  inputProps={{
33
- id: 'cell-color-encoding-select',
39
+ id: `cell-color-encoding-select-${cellColorEncodingId}`,
34
40
  }}
35
41
  >
36
42
  <option value="cellSetSelection">Cell Sets</option>
@@ -14,6 +14,7 @@ export default function OptionSelect(props) {
14
14
  root: classes.optionSelectRoot,
15
15
  ...classesProp,
16
16
  }}
17
+ aria-label="Select an option"
17
18
  />
18
19
  );
19
20
  }
@@ -12,7 +12,11 @@ export default function OptionsContainer(props) {
12
12
  return (
13
13
  <Box className={classes.box}>
14
14
  <TableContainer className={classes.tableContainer}>
15
- <Table className={classes.table} size="small">
15
+ <Table
16
+ className={classes.table}
17
+ size="small"
18
+ aria-label="Menu of options available for the view"
19
+ >
16
20
  <TableBody>
17
21
  {children}
18
22
  </TableBody>