@genspectrum/dashboard-components 0.8.3 → 0.8.4

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.
@@ -903,7 +903,7 @@
903
903
  "type": {
904
904
  "text": "StoryObj<MutationFilterProps>"
905
905
  },
906
- "default": "{ ...Template, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter'); const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false }); const submitButton = () => canvas.getByRole('button', { name: '+' }); const listenerMock = fn(); await step('Setup event listener mock', async () => { canvasElement.addEventListener('gs-mutation-filter-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Enter a valid mutation', async () => { await userEvent.type(inputField(), 'A123T'); await waitFor(() => submitButton().click()); await waitFor(() => expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { nucleotideMutations: ['A123T'], aminoAcidMutations: [], nucleotideInsertions: [], aminoAcidInsertions: [], }, }), ), ); }); }, }"
906
+ "default": "{ ...Template, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter'); const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false }); const listenerMock = fn(); await step('Setup event listener mock', async () => { canvasElement.addEventListener('gs-mutation-filter-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Enter a valid mutation', async () => { await userEvent.type(inputField(), 'A123T'); const option = await canvas.findByRole('option'); await userEvent.click(option); await waitFor(() => expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { nucleotideMutations: ['A123T'], aminoAcidMutations: [], nucleotideInsertions: [], aminoAcidInsertions: [], }, }), ), ); }); }, }"
907
907
  },
908
908
  {
909
909
  "kind": "variable",
@@ -911,7 +911,7 @@
911
911
  "type": {
912
912
  "text": "StoryObj<MutationFilterProps>"
913
913
  },
914
- "default": "{ ...Template, args: { initialValue: ['seg1:123T', 'gene2:56', 'ins_seg2:78:AAA'], }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'referenceGenome', url: REFERENCE_GENOME_ENDPOINT, }, response: { status: 200, body: { nucleotideSequences: [ { name: 'seg1', sequence: 'dummy', }, { name: 'seg2', sequence: 'dummy', }, ], genes: [ { name: 'gene1', sequence: 'dummy', }, { name: 'gene2', sequence: 'dummy', }, ], }, }, options: { overwriteRoutes: false, }, }, ], }, }, play: async ({ canvasElement }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter'); await waitFor(() => { expect(canvas.getByText('seg1:123T')).toBeVisible(); expect(canvas.getByText('gene2:56')).toBeVisible(); return expect(canvas.getByText('ins_seg2:78:AAA')).toBeVisible(); }); }, }"
914
+ "default": "{ ...Template, args: { initialValue: ['seg1:123T', 'gene2:56', 'ins_seg2:78:AAA'], }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'referenceGenome', url: REFERENCE_GENOME_ENDPOINT, }, response: { status: 200, body: { nucleotideSequences: [ { name: 'seg1', sequence: 'dummy', }, { name: 'seg2', sequence: 'dummy', }, ], genes: [ { name: 'gene1', sequence: 'dummy', }, { name: 'gene2', sequence: 'dummy', }, ], }, }, options: { overwriteRoutes: false, }, }, ], }, }, play: async ({ canvasElement }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter'); const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false }); await waitFor(() => { const placeholderText = inputField().getAttribute('placeholder'); expect(placeholderText).toEqual( 'Enter a mutation (e.g. seg1:A123T, ins_seg1:123:AT, gene1:M123E, ins_gene1:123:ME)', ); }); await waitFor(() => { expect(canvas.getByText('seg1:123T')).toBeVisible(); expect(canvas.getByText('gene2:56')).toBeVisible(); return expect(canvas.getByText('ins_seg2:78:AAA')).toBeVisible(); }); }, }"
915
915
  }
916
916
  ],
917
917
  "exports": [
@@ -955,7 +955,7 @@
955
955
  "declarations": [
956
956
  {
957
957
  "kind": "class",
958
- "description": "## Context\nThis component provides an input field to specify filters for nucleotide and amino acid mutations and insertions.\n\nInput values have to be provided one at a time and submitted by pressing the Enter key or by clicking the '+' button.\nAfter submission, the component validates the input and fires an event with the selected mutations.\nAll previously selected mutations are displayed at the input field and added to the event.\nUsers can remove a mutation by clicking the 'x' button next to the mutation.\n\n## Input Validation\n\nValidation of the input is performed according to the following rules:\n\n### Mutations\n\nMutations have to conform to the following format: `<gene/segment>:<symbol at reference><position><Substituted symbol/Deletion>`\n- Gene/segment: The gene or segment where the mutation occurs. Must be contained in the reference genome.\n (Optional for elements with only one gene/segment)\n- Symbol at reference: The symbol at the reference position. (Optional)\n- Position: The position of the mutation. (Required)\n- Substituted symbol/Deletion: The substituted symbol or '-' for a deletion. (Required)\n\nExamples: `S:614G`, `614G`, `614-`, `614G`\n\n### Insertions\n\nInsertions have to conform to the following format: `ins_<gene/segment>:<position>:<Inserted symbols>`\n- Gene/segment: The gene or segment where the insertion occurs. Must be contained in the reference genome.\n (Optional for elements with only one gene/segment)\n- Position: The position of the insertion. (Required)\n- Inserted symbols: The symbols that are inserted. (Required)\n\nExamples: `ins_S:614:G`, `ins_614:G`",
958
+ "description": "## Context\nThis component provides an input field to specify filters for nucleotide and amino acid mutations and insertions.\n\nInput values have to be provided one at a time and submitted by pressing the Enter key or by selecting an option from the dropdown.\nAlternatively, they can be provided as a string of comma-separated values, which will be directly parsed and validated.\nAfter submission (after pressing Enter or pasting a comma-separated string) an event is fired with the selected mutations.\nAll previously selected mutations are displayed at the input field and added to the event.\nUsers can remove a mutation by clicking the 'x' button next to the mutation.\n\n## Input Validation\n\nValidation of the input is performed according to the following rules:\n\n### Mutations\n\nMutations have to conform to the following format: `<gene/segment>:<symbol at reference><position><Substituted symbol/Deletion>`\n- Gene/segment: The gene or segment where the mutation occurs. Must be contained in the reference genome.\n (Optional for elements with only one gene/segment)\n- Symbol at reference: The symbol at the reference position. (Optional)\n- Position: The position of the mutation. (Required)\n- Substituted symbol/Deletion: The substituted symbol or '-' for a deletion. (Required)\n\nExamples: `S:614G`, `614G`, `614-`, `614G`\n\n### Insertions\n\nInsertions have to conform to the following format: `ins_<gene/segment>:<position>:<Inserted symbols>`\n- Gene/segment: The gene or segment where the insertion occurs. Must be contained in the reference genome.\n (Optional for elements with only one gene/segment)\n- Position: The position of the insertion. (Required)\n- Inserted symbols: The symbols that are inserted. (Required)\n\nExamples: `ins_S:614:G`, `ins_614:G`",
959
959
  "name": "MutationFilterComponent",
960
960
  "members": [
961
961
  {
@@ -4741,15 +4741,15 @@ input.tab:checked + .tab-content,
4741
4741
  .mt-4 {
4742
4742
  margin-top: 1rem;
4743
4743
  }
4744
- .inline-block {
4745
- display: inline-block;
4746
- }
4747
4744
  .inline {
4748
4745
  display: inline;
4749
4746
  }
4750
4747
  .flex {
4751
4748
  display: flex;
4752
4749
  }
4750
+ .inline-flex {
4751
+ display: inline-flex;
4752
+ }
4753
4753
  .table {
4754
4754
  display: table;
4755
4755
  }
@@ -4819,6 +4819,9 @@ input.tab:checked + .tab-content,
4819
4819
  --tw-translate-y: -50%;
4820
4820
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
4821
4821
  }
4822
+ .cursor-pointer {
4823
+ cursor: pointer;
4824
+ }
4822
4825
  .resize {
4823
4826
  resize: both;
4824
4827
  }
@@ -4867,9 +4870,6 @@ input.tab:checked + .tab-content,
4867
4870
  .break-words {
4868
4871
  overflow-wrap: break-word;
4869
4872
  }
4870
- .rounded-full {
4871
- border-radius: 9999px;
4872
- }
4873
4873
  .rounded-lg {
4874
4874
  border-radius: 0.5rem;
4875
4875
  }
@@ -4898,12 +4898,6 @@ input.tab:checked + .tab-content,
4898
4898
  .border-b-2 {
4899
4899
  border-bottom-width: 2px;
4900
4900
  }
4901
- .border-solid {
4902
- border-style: solid;
4903
- }
4904
- .border-none {
4905
- border-style: none;
4906
- }
4907
4901
  .border-error {
4908
4902
  --tw-border-opacity: 1;
4909
4903
  border-color: var(--fallback-er,oklch(var(--er)/var(--tw-border-opacity, 1)));
@@ -4924,14 +4918,18 @@ input.tab:checked + .tab-content,
4924
4918
  --tw-border-opacity: 1;
4925
4919
  border-color: rgb(156 163 175 / var(--tw-border-opacity, 1));
4926
4920
  }
4927
- .border-red-500 {
4921
+ .border-slate-500 {
4928
4922
  --tw-border-opacity: 1;
4929
- border-color: rgb(239 68 68 / var(--tw-border-opacity, 1));
4923
+ border-color: rgb(100 116 139 / var(--tw-border-opacity, 1));
4930
4924
  }
4931
4925
  .bg-red-200 {
4932
4926
  --tw-bg-opacity: 1;
4933
4927
  background-color: rgb(254 202 202 / var(--tw-bg-opacity, 1));
4934
4928
  }
4929
+ .bg-slate-200 {
4930
+ --tw-bg-opacity: 1;
4931
+ background-color: rgb(226 232 240 / var(--tw-bg-opacity, 1));
4932
+ }
4935
4933
  .bg-white {
4936
4934
  --tw-bg-opacity: 1;
4937
4935
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
@@ -4945,10 +4943,6 @@ input.tab:checked + .tab-content,
4945
4943
  .p-4 {
4946
4944
  padding: 1rem;
4947
4945
  }
4948
- .px-2 {
4949
- padding-left: 0.5rem;
4950
- padding-right: 0.5rem;
4951
- }
4952
4946
  .px-4 {
4953
4947
  padding-left: 1rem;
4954
4948
  padding-right: 1rem;
@@ -5015,6 +5009,10 @@ input.tab:checked + .tab-content,
5015
5009
  --tw-text-opacity: 1;
5016
5010
  color: rgb(96 96 96 / var(--tw-text-opacity, 1));
5017
5011
  }
5012
+ .text-black {
5013
+ --tw-text-opacity: 1;
5014
+ color: rgb(0 0 0 / var(--tw-text-opacity, 1));
5015
+ }
5018
5016
  .text-blue-600 {
5019
5017
  --tw-text-opacity: 1;
5020
5018
  color: rgb(37 99 235 / var(--tw-text-opacity, 1));
@@ -5090,10 +5088,6 @@ input.tab:checked + .tab-content,
5090
5088
  border-bottom-left-radius: var(--rounded-box, 1rem);
5091
5089
  }
5092
5090
  }
5093
- .focus-within\\:border-gray-400:focus-within {
5094
- --tw-border-opacity: 1;
5095
- border-color: rgb(156 163 175 / var(--tw-border-opacity, 1));
5096
- }
5097
5091
  .hover\\:scale-110:hover {
5098
5092
  --tw-scale-x: 1.1;
5099
5093
  --tw-scale-y: 1.1;
@@ -5108,6 +5102,10 @@ input.tab:checked + .tab-content,
5108
5102
  --tw-bg-opacity: 1;
5109
5103
  background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
5110
5104
  }
5105
+ .hover\\:bg-gray-300:hover {
5106
+ --tw-bg-opacity: 1;
5107
+ background-color: rgb(209 213 219 / var(--tw-bg-opacity, 1));
5108
+ }
5111
5109
  .hover\\:font-bold:hover {
5112
5110
  font-weight: 700;
5113
5111
  }
@@ -5127,15 +5125,6 @@ input.tab:checked + .tab-content,
5127
5125
  --tw-text-opacity: 1;
5128
5126
  color: rgb(55 65 81 / var(--tw-text-opacity, 1));
5129
5127
  }
5130
- .focus\\:outline-none:focus {
5131
- outline: 2px solid transparent;
5132
- outline-offset: 2px;
5133
- }
5134
- .focus\\:ring-0:focus {
5135
- --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
5136
- --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
5137
- box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
5138
- }
5139
5128
  .peer:hover ~ .peer-hover\\:visible {
5140
5129
  visibility: visible;
5141
5130
  }
@@ -10001,31 +9990,19 @@ const MutationFilterInner = ({ initialValue }) => {
10001
9990
  const [selectedFilters, setSelectedFilters] = h(
10002
9991
  getInitialState(initialValue, referenceGenome)
10003
9992
  );
10004
- const [inputValue, setInputValue] = h("");
10005
- const [isError, setIsError] = h(false);
10006
- const formRef = A(null);
10007
- const handleSubmit = (event) => {
10008
- event.preventDefault();
10009
- if (inputValue === "") {
10010
- return;
10011
- }
10012
- const parsedMutation = parseAndValidateMutation(inputValue, referenceGenome);
10013
- if (parsedMutation === null) {
10014
- setIsError(true);
10015
- return;
10016
- }
10017
- const newSelectedValues = {
9993
+ const filterRef = A(null);
9994
+ const handleRemoveValue = (option) => {
9995
+ const newSelectedFilters = {
10018
9996
  ...selectedFilters,
10019
- [parsedMutation.type]: [...selectedFilters[parsedMutation.type], parsedMutation.value]
9997
+ [option.type]: selectedFilters[option.type].filter((i2) => option.value.toString() != i2.toString())
10020
9998
  };
10021
- setSelectedFilters(newSelectedValues);
10022
- fireChangeEvent(newSelectedValues);
10023
- setInputValue("");
9999
+ setSelectedFilters(newSelectedFilters);
10000
+ fireChangeEvent(newSelectedFilters);
10024
10001
  };
10025
10002
  const fireChangeEvent = (selectedFilters2) => {
10026
10003
  var _a;
10027
10004
  const detail = mapToMutationFilterStrings(selectedFilters2);
10028
- (_a = formRef.current) == null ? void 0 : _a.dispatchEvent(
10005
+ (_a = filterRef.current) == null ? void 0 : _a.dispatchEvent(
10029
10006
  new CustomEvent("gs-mutation-filter-changed", {
10030
10007
  detail,
10031
10008
  bubbles: true,
@@ -10033,38 +10010,25 @@ const MutationFilterInner = ({ initialValue }) => {
10033
10010
  })
10034
10011
  );
10035
10012
  };
10036
- const handleInputChange = (event) => {
10037
- setInputValue(event.target.value);
10038
- setIsError(false);
10039
- };
10040
- return /* @__PURE__ */ u$1("form", { className: "w-full border boder-gray-300 rounded-md relative", onSubmit: handleSubmit, ref: formRef, children: [
10041
- /* @__PURE__ */ u$1("div", { className: "absolute -top-3 -right-3", children: /* @__PURE__ */ u$1(MutationFilterInfo, {}) }),
10042
- /* @__PURE__ */ u$1("div", { className: "w-full flex p-2 flex-wrap items-center", children: [
10013
+ return /* @__PURE__ */ u$1("div", { className: "w-full border border-gray-300 rounded-md relative", ref: filterRef, children: [
10014
+ /* @__PURE__ */ u$1("div", { className: "absolute -top-3 -right-3 z-10", children: /* @__PURE__ */ u$1(MutationFilterInfo, {}) }),
10015
+ /* @__PURE__ */ u$1("div", { className: "relative w-full p-1", children: [
10043
10016
  /* @__PURE__ */ u$1(
10044
- SelectedMutationDisplay,
10017
+ MutationFilterSelector,
10045
10018
  {
10046
- selectedFilters,
10047
- setSelectedFilters,
10048
- fireChangeEvent
10019
+ referenceGenome,
10020
+ setSelectedFilters: (newSelectedFilters) => {
10021
+ setSelectedFilters(newSelectedFilters);
10022
+ fireChangeEvent(newSelectedFilters);
10023
+ },
10024
+ selectedFilters
10049
10025
  }
10050
10026
  ),
10051
10027
  /* @__PURE__ */ u$1(
10052
- "div",
10028
+ SelectedMutationFilterDisplay,
10053
10029
  {
10054
- className: `w-full flex border ${isError ? "border-red-500" : "border-gray-300"} border-solid m-2 text-sm focus-within:border-gray-400 `,
10055
- children: [
10056
- /* @__PURE__ */ u$1(
10057
- "input",
10058
- {
10059
- className: "grow flex-1 p-1 border-none focus:outline-none focus:ring-0",
10060
- type: "text",
10061
- value: inputValue,
10062
- onInput: handleInputChange,
10063
- placeholder: getPlaceholder(referenceGenome)
10064
- }
10065
- ),
10066
- /* @__PURE__ */ u$1("button", { type: "submit", className: "btn btn-xs m-1", children: "+" })
10067
- ]
10030
+ selectedFilters,
10031
+ handleRemoveValue
10068
10032
  }
10069
10033
  )
10070
10034
  ] })
@@ -10099,123 +10063,164 @@ function getInitialState(initialValue, referenceGenome) {
10099
10063
  }
10100
10064
  );
10101
10065
  }
10066
+ const MutationFilterSelector = ({ referenceGenome, setSelectedFilters, selectedFilters }) => {
10067
+ const [option, setOption] = h(null);
10068
+ const [inputValue, setInputValue] = h("");
10069
+ const selectorRef = A(null);
10070
+ const handleInputChange = (newValue) => {
10071
+ if (newValue.includes(",") || newValue.includes(";")) {
10072
+ handleCommaSeparatedInput(newValue);
10073
+ } else {
10074
+ setInputValue(newValue);
10075
+ const result = parseAndValidateMutation(newValue, referenceGenome);
10076
+ setOption(result);
10077
+ }
10078
+ };
10079
+ const handleCommaSeparatedInput = (inputValue2) => {
10080
+ const inputValues = inputValue2.split(/[,;]/);
10081
+ let newSelectedOptions = selectedFilters;
10082
+ let updated = false;
10083
+ const invalidQueries = [];
10084
+ for (const value of inputValues) {
10085
+ const trimmedValue = value.trim();
10086
+ const parsedMutation = parseAndValidateMutation(trimmedValue, referenceGenome);
10087
+ if (parsedMutation) {
10088
+ const type = parsedMutation.type;
10089
+ if (!selectedFilters[type].some((i2) => parsedMutation.value.toString() === i2.toString())) {
10090
+ newSelectedOptions = {
10091
+ ...newSelectedOptions,
10092
+ [parsedMutation.type]: [...newSelectedOptions[parsedMutation.type], parsedMutation.value]
10093
+ };
10094
+ updated = true;
10095
+ }
10096
+ } else {
10097
+ invalidQueries.push(trimmedValue);
10098
+ }
10099
+ }
10100
+ setInputValue(invalidQueries.join(","));
10101
+ if (updated) {
10102
+ setSelectedFilters(newSelectedOptions);
10103
+ setOption(null);
10104
+ }
10105
+ };
10106
+ const handleOptionClick = () => {
10107
+ if (option === null) {
10108
+ return;
10109
+ }
10110
+ const type = option.type;
10111
+ if (!selectedFilters[type].some((i2) => option.value.toString() === i2.toString())) {
10112
+ const newSelectedValues = {
10113
+ ...selectedFilters,
10114
+ [option == null ? void 0 : option.type]: [...selectedFilters[option == null ? void 0 : option.type], option == null ? void 0 : option.value]
10115
+ };
10116
+ setSelectedFilters(newSelectedValues);
10117
+ }
10118
+ setInputValue("");
10119
+ setOption(null);
10120
+ };
10121
+ const handleEnterPress = (event) => {
10122
+ if (event.key === "Enter" && option !== null) {
10123
+ handleOptionClick();
10124
+ }
10125
+ };
10126
+ const handleBlur = (event) => {
10127
+ var _a;
10128
+ if (!((_a = selectorRef.current) == null ? void 0 : _a.contains(event.relatedTarget))) {
10129
+ setOption(null);
10130
+ }
10131
+ };
10132
+ return /* @__PURE__ */ u$1("div", { ref: selectorRef, tabIndex: -1, children: [
10133
+ /* @__PURE__ */ u$1(
10134
+ "input",
10135
+ {
10136
+ type: "text",
10137
+ className: "w-full p-2 border-gray-300 border rounded-md",
10138
+ placeholder: getPlaceholder(referenceGenome),
10139
+ value: inputValue,
10140
+ onInput: (e2) => {
10141
+ handleInputChange(e2.target.value);
10142
+ },
10143
+ onKeyDown: (e2) => handleEnterPress(e2),
10144
+ onFocus: () => handleInputChange(inputValue),
10145
+ onBlur: handleBlur
10146
+ }
10147
+ ),
10148
+ option != null && /* @__PURE__ */ u$1(
10149
+ "div",
10150
+ {
10151
+ role: "option",
10152
+ className: "hover:bg-gray-300 absolute cursor-pointer p-2 border-1 border-slate-500 bg-slate-200",
10153
+ onClick: () => handleOptionClick(),
10154
+ children: option.value.toString()
10155
+ }
10156
+ )
10157
+ ] });
10158
+ };
10102
10159
  function getPlaceholder(referenceGenome) {
10103
10160
  const segmentPrefix = referenceGenome.nucleotideSequences.length > 1 ? `${referenceGenome.nucleotideSequences[0].name}:` : "";
10104
10161
  const firstGene = referenceGenome.genes[0].name;
10105
10162
  return `Enter a mutation (e.g. ${segmentPrefix}A123T, ins_${segmentPrefix}123:AT, ${firstGene}:M123E, ins_${firstGene}:123:ME)`;
10106
10163
  }
10107
- const SelectedMutationDisplay = ({ selectedFilters, setSelectedFilters, fireChangeEvent }) => {
10108
- const onSelectedRemoved = (mutation, key) => {
10109
- const newSelectedValues = {
10110
- ...selectedFilters,
10111
- [key]: selectedFilters[key].filter((i2) => !mutation.equals(i2))
10112
- };
10113
- setSelectedFilters(newSelectedValues);
10114
- fireChangeEvent(newSelectedValues);
10115
- };
10116
- return /* @__PURE__ */ u$1(Fragment, { children: [
10164
+ const backgroundColor = {
10165
+ aminoAcidMutations: singleGraphColorRGBByName("teal", 0.4),
10166
+ nucleotideMutations: singleGraphColorRGBByName("green", 0.4),
10167
+ aminoAcidInsertions: singleGraphColorRGBByName("purple", 0.4),
10168
+ nucleotideInsertions: singleGraphColorRGBByName("indigo", 0.4)
10169
+ };
10170
+ const backgroundColorMap = (data) => {
10171
+ return backgroundColor[data.type] || "lightgray";
10172
+ };
10173
+ const SelectedMutationFilterDisplay = ({ selectedFilters, handleRemoveValue }) => {
10174
+ return /* @__PURE__ */ u$1("div", { className: "flex flex-wrap", children: [
10117
10175
  selectedFilters.nucleotideMutations.map((mutation) => /* @__PURE__ */ u$1(
10118
- SelectedNucleotideMutation,
10176
+ SelectedFilter,
10119
10177
  {
10120
- mutation,
10121
- onDelete: (mutation2) => onSelectedRemoved(mutation2, "nucleotideMutations")
10178
+ handleRemoveValue,
10179
+ mutationFilter: { type: "nucleotideMutations", value: mutation }
10122
10180
  },
10123
10181
  mutation.toString()
10124
10182
  )),
10125
10183
  selectedFilters.aminoAcidMutations.map((mutation) => /* @__PURE__ */ u$1(
10126
- SelectedAminoAcidMutation,
10184
+ SelectedFilter,
10127
10185
  {
10128
- mutation,
10129
- onDelete: (mutation2) => onSelectedRemoved(mutation2, "aminoAcidMutations")
10186
+ handleRemoveValue,
10187
+ mutationFilter: { type: "aminoAcidMutations", value: mutation }
10130
10188
  },
10131
10189
  mutation.toString()
10132
10190
  )),
10133
- selectedFilters.nucleotideInsertions.map((insertion) => /* @__PURE__ */ u$1(
10134
- SelectedNucleotideInsertion,
10191
+ selectedFilters.nucleotideInsertions.map((mutation) => /* @__PURE__ */ u$1(
10192
+ SelectedFilter,
10135
10193
  {
10136
- insertion,
10137
- onDelete: (insertion2) => onSelectedRemoved(insertion2, "nucleotideInsertions")
10194
+ handleRemoveValue,
10195
+ mutationFilter: { type: "nucleotideInsertions", value: mutation }
10138
10196
  },
10139
- insertion.toString()
10197
+ mutation.toString()
10140
10198
  )),
10141
- selectedFilters.aminoAcidInsertions.map((insertion) => /* @__PURE__ */ u$1(
10142
- SelectedAminoAcidInsertion,
10199
+ selectedFilters.aminoAcidInsertions.map((mutation) => /* @__PURE__ */ u$1(
10200
+ SelectedFilter,
10143
10201
  {
10144
- insertion,
10145
- onDelete: (insertion2) => onSelectedRemoved(insertion2, "aminoAcidInsertions")
10202
+ handleRemoveValue,
10203
+ mutationFilter: { type: "aminoAcidInsertions", value: mutation }
10146
10204
  },
10147
- insertion.toString()
10205
+ mutation.toString()
10148
10206
  ))
10149
10207
  ] });
10150
10208
  };
10151
- const SelectedAminoAcidInsertion = ({ insertion, onDelete }) => {
10152
- const backgroundColor = singleGraphColorRGBByName("teal", 0.3);
10153
- const textColor = singleGraphColorRGBByName("teal", 1);
10154
- return /* @__PURE__ */ u$1(
10155
- SelectedFilter,
10156
- {
10157
- mutation: insertion,
10158
- onDelete,
10159
- backgroundColor,
10160
- textColor
10161
- }
10162
- );
10163
- };
10164
- const SelectedAminoAcidMutation = ({ mutation, onDelete }) => {
10165
- const backgroundColor = singleGraphColorRGBByName("rose", 0.3);
10166
- const textColor = singleGraphColorRGBByName("rose", 1);
10167
- return /* @__PURE__ */ u$1(
10168
- SelectedFilter,
10169
- {
10170
- mutation,
10171
- onDelete,
10172
- backgroundColor,
10173
- textColor
10174
- }
10175
- );
10176
- };
10177
- const SelectedNucleotideMutation = ({ mutation, onDelete }) => {
10178
- const backgroundColor = singleGraphColorRGBByName("indigo", 0.3);
10179
- const textColor = singleGraphColorRGBByName("indigo", 1);
10180
- return /* @__PURE__ */ u$1(
10181
- SelectedFilter,
10182
- {
10183
- mutation,
10184
- onDelete,
10185
- backgroundColor,
10186
- textColor
10187
- }
10188
- );
10189
- };
10190
- const SelectedNucleotideInsertion = ({ insertion, onDelete }) => {
10191
- const backgroundColor = singleGraphColorRGBByName("green", 0.3);
10192
- const textColor = singleGraphColorRGBByName("green", 1);
10193
- return /* @__PURE__ */ u$1(
10194
- SelectedFilter,
10195
- {
10196
- mutation: insertion,
10197
- onDelete,
10198
- backgroundColor,
10199
- textColor
10200
- }
10201
- );
10202
- };
10203
- const SelectedFilter = ({
10204
- mutation,
10205
- onDelete,
10206
- backgroundColor,
10207
- textColor
10208
- }) => {
10209
+ const SelectedFilter = ({ handleRemoveValue, mutationFilter }) => {
10209
10210
  return /* @__PURE__ */ u$1(
10210
10211
  "span",
10211
10212
  {
10212
- class: "inline-block mx-1 px-2 py-1 font-medium text-xs rounded-full",
10213
- style: { backgroundColor, color: textColor },
10213
+ name: mutationFilter.value.toString(),
10214
+ className: "center p-2 m-1 inline-flex text-black rounded-md",
10215
+ style: {
10216
+ backgroundColor: backgroundColorMap(mutationFilter)
10217
+ },
10214
10218
  children: [
10215
- mutation.toString(),
10216
- /* @__PURE__ */ u$1("button", { className: "ml-1", type: "button", onClick: () => onDelete(mutation), children: "" })
10219
+ mutationFilter.value.toString(),
10220
+ /* @__PURE__ */ u$1("button", { className: "ml-1", onClick: () => handleRemoveValue(mutationFilter), children: "×" })
10217
10221
  ]
10218
- }
10222
+ },
10223
+ mutationFilter.value.toString()
10219
10224
  );
10220
10225
  };
10221
10226
  function mapToMutationFilterStrings(selectedFilters) {