@genspectrum/dashboard-components 0.3.0 → 0.3.1

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.
@@ -483,7 +483,7 @@
483
483
  "type": {
484
484
  "text": "StoryObj<LocationFilterProps>"
485
485
  },
486
- "default": "{ ...Template, parameters: { fetchMock: { mocks: [ { matcher: aggregatedEndpointMatcher, response: { status: 200, body: data, }, }, ], }, }, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-location-filter'); const submitButton = () => canvas.getByRole('button', { name: 'Submit' }); const inputField = () => canvas.getByRole('combobox'); const listenerMock = fn(); await step('Setup event listener mock', async () => { canvasElement.addEventListener('gs-location-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Input invalid location', async () => { await userEvent.type(inputField(), 'Not / A / Location'); await userEvent.click(submitButton()); await expect(listenerMock).not.toHaveBeenCalled(); await userEvent.type(inputField(), '{backspace>18/}'); }); await step('Select Asia', async () => { await userEvent.type(inputField(), 'Asia'); await userEvent.click(submitButton()); await expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { region: 'Asia', }, }), ); }); await step('Select Asia / Bangladesh / Rajshahi / Chapainawabgonj', async () => { await userEvent.type(inputField(), ' / Bangladesh / Rajshahi / Chapainawabgonj'); await userEvent.click(submitButton()); await expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { region: 'Asia', country: 'Bangladesh', division: 'Rajshahi', location: 'Chapainawabgonj', }, }), ); }); }, }"
486
+ "default": "{ ...Template, parameters: { fetchMock: { mocks: [ { matcher: aggregatedEndpointMatcher, response: { status: 200, body: data, }, }, ], }, }, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-location-filter'); const inputField = () => canvas.getByRole('combobox'); const listenerMock = fn(); await step('Setup event listener mock', async () => { canvasElement.addEventListener('gs-location-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Input invalid location', async () => { await userEvent.type(inputField(), 'Not / A / Location'); await expect(listenerMock).not.toHaveBeenCalled(); await userEvent.type(inputField(), '{backspace>18/}'); }); await step('Select Asia', async () => { await userEvent.type(inputField(), 'Asia'); await expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { region: 'Asia', }, }), ); }); await step('Select Asia / Bangladesh / Rajshahi / Chapainawabgonj', async () => { await userEvent.type(inputField(), ' / Bangladesh / Rajshahi / Chapainawabgonj'); await expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { region: 'Asia', country: 'Bangladesh', division: 'Rajshahi', location: 'Chapainawabgonj', }, }), ); }); }, }"
487
487
  }
488
488
  ],
489
489
  "exports": [
@@ -574,7 +574,7 @@
574
574
  "type": {
575
575
  "text": "CustomEvent<Record<string, string>>"
576
576
  },
577
- "description": "Fired when the field is submitted with a valid location value. The `details` of this event contain an object with all `fields` as keys and the corresponding values as values, if they are not `undefined`. Example: ``` { continent: \"Asia\", country: \"China\", city: \"Beijing\" } ```",
577
+ "description": "Fired when a value from the datalist is selected or when a valid value is typed into the field. The `details` of this event contain an object with all `fields` as keys and the corresponding values as values, if they are not `undefined`. Example: ``` { continent: \"Asia\", country: \"China\", city: \"Beijing\" } ```",
578
578
  "name": "gs-location-changed"
579
579
  }
580
580
  ],
@@ -2617,19 +2617,6 @@ html {
2617
2617
  }
2618
2618
  }
2619
2619
 
2620
- .btn-outline.btn-primary:hover {
2621
- --tw-text-opacity: 1;
2622
- color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
2623
- }
2624
-
2625
- @supports (color: color-mix(in oklab, black, black)) {
2626
-
2627
- .btn-outline.btn-primary:hover {
2628
- background-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
2629
- border-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
2630
- }
2631
- }
2632
-
2633
2620
  .btn-disabled:hover,
2634
2621
  .btn[disabled]:hover,
2635
2622
  .btn:disabled:hover {
@@ -3099,34 +3086,12 @@ input.tab:checked + .tab-content,
3099
3086
  background-color: var(--btn-color, var(--fallback-b2));
3100
3087
  border-color: var(--btn-color, var(--fallback-b2));
3101
3088
  }
3102
-
3103
- .btn-primary {
3104
- --btn-color: var(--fallback-p);
3105
- }
3106
- }
3107
- @supports (color: color-mix(in oklab, black, black)) {
3108
-
3109
- .btn-outline.btn-primary.btn-active {
3110
- background-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
3111
- border-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
3112
- }
3113
3089
  }
3114
3090
  .btn:focus-visible {
3115
3091
  outline-style: solid;
3116
3092
  outline-width: 2px;
3117
3093
  outline-offset: 2px;
3118
3094
  }
3119
- .btn-primary {
3120
- --tw-text-opacity: 1;
3121
- color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
3122
- outline-color: var(--fallback-p,oklch(var(--p)/1));
3123
- }
3124
- @supports (color: oklch(0% 0 0)) {
3125
-
3126
- .btn-primary {
3127
- --btn-color: var(--p);
3128
- }
3129
- }
3130
3095
  .btn.glass {
3131
3096
  --tw-shadow: 0 0 #0000;
3132
3097
  --tw-shadow-colored: 0 0 #0000;
@@ -3151,14 +3116,6 @@ input.tab:checked + .tab-content,
3151
3116
  border-color: transparent;
3152
3117
  background-color: var(--fallback-bc,oklch(var(--bc)/0.2));
3153
3118
  }
3154
- .btn-outline.btn-primary {
3155
- --tw-text-opacity: 1;
3156
- color: var(--fallback-p,oklch(var(--p)/var(--tw-text-opacity)));
3157
- }
3158
- .btn-outline.btn-primary.btn-active {
3159
- --tw-text-opacity: 1;
3160
- color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
3161
- }
3162
3119
  .btn.btn-disabled,
3163
3120
  .btn[disabled],
3164
3121
  .btn:disabled {
@@ -4309,9 +4266,6 @@ input.tab:checked + .tab-content,
4309
4266
  .me-1 {
4310
4267
  margin-inline-end: 0.25rem;
4311
4268
  }
4312
- .ml-1 {
4313
- margin-left: 0.25rem;
4314
- }
4315
4269
  .ml-2 {
4316
4270
  margin-left: 0.5rem;
4317
4271
  }
@@ -7723,7 +7677,7 @@ const LocationFilterInner = ({ initialValue, fields }) => {
7723
7677
  const lapis = P(LapisUrlContext);
7724
7678
  const [value, setValue] = p(initialValue ?? "");
7725
7679
  const [unknownLocation, setUnknownLocation] = p(false);
7726
- const formRef = F(null);
7680
+ const divRef = F(null);
7727
7681
  const { data, error, isLoading } = useQuery(() => fetchAutocompletionList(fields, lapis), [fields, lapis]);
7728
7682
  if (isLoading) {
7729
7683
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
@@ -7732,35 +7686,27 @@ const LocationFilterInner = ({ initialValue, fields }) => {
7732
7686
  return /* @__PURE__ */ u$1(ErrorDisplay, { error });
7733
7687
  }
7734
7688
  const onInput = (event) => {
7735
- if (event.target instanceof HTMLInputElement) {
7736
- const inputValue = event.target.value;
7737
- setValue(inputValue);
7738
- if (unknownLocation) {
7739
- const eventDetail = parseLocation(inputValue, fields);
7740
- if (hasMatchingEntry(data, eventDetail)) {
7741
- setUnknownLocation(false);
7742
- }
7743
- }
7744
- }
7745
- };
7746
- const submit = (event) => {
7747
7689
  var _a;
7748
- event.preventDefault();
7749
- const eventDetail = parseLocation(value, fields);
7690
+ const inputValue = event.currentTarget.value;
7691
+ setValue(inputValue);
7692
+ if (inputValue.trim() === value.trim()) {
7693
+ return;
7694
+ }
7695
+ const eventDetail = parseLocation(inputValue, fields);
7750
7696
  if (hasMatchingEntry(data, eventDetail)) {
7751
- setUnknownLocation(false);
7752
- (_a = formRef.current) == null ? void 0 : _a.dispatchEvent(
7697
+ (_a = divRef.current) == null ? void 0 : _a.dispatchEvent(
7753
7698
  new CustomEvent("gs-location-changed", {
7754
7699
  detail: eventDetail,
7755
7700
  bubbles: true,
7756
7701
  composed: true
7757
7702
  })
7758
7703
  );
7704
+ setUnknownLocation(false);
7759
7705
  } else {
7760
7706
  setUnknownLocation(true);
7761
7707
  }
7762
7708
  };
7763
- return /* @__PURE__ */ u$1("form", { class: "flex w-full", onSubmit: submit, ref: formRef, children: [
7709
+ return /* @__PURE__ */ u$1("div", { class: "flex w-full", ref: divRef, children: [
7764
7710
  /* @__PURE__ */ u$1(
7765
7711
  "input",
7766
7712
  {
@@ -7774,8 +7720,7 @@ const LocationFilterInner = ({ initialValue, fields }) => {
7774
7720
  /* @__PURE__ */ u$1("datalist", { id: "countries", children: data == null ? void 0 : data.map((v2) => {
7775
7721
  const value2 = fields.map((field) => v2[field]).filter((value3) => value3 !== null).join(" / ");
7776
7722
  return /* @__PURE__ */ u$1("option", { value: value2 }, value2);
7777
- }) }),
7778
- /* @__PURE__ */ u$1("button", { class: "btn btn-primary ml-1", type: "submit", children: "Submit" })
7723
+ }) })
7779
7724
  ] });
7780
7725
  };
7781
7726
  const parseLocation = (location, fields) => {