From b58faae70d3b5a65cc5edb1fe2864dd79ee075db Mon Sep 17 00:00:00 2001 From: "Anna (Anya) Parker" <50943381+anna-parker@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:47:52 +0100 Subject: [PATCH] feat(components): add option to delete input of text-input and lineage-filter input with x and sort text-input datalist options --- .../lineageFilter/lineage-filter.stories.tsx | 34 +++++++++++++++ .../preact/lineageFilter/lineage-filter.tsx | 42 ++++++++++++++----- .../preact/textInput/fetchAutocompleteList.ts | 2 +- .../preact/textInput/text-input.stories.tsx | 21 +++++++++- .../src/preact/textInput/text-input.tsx | 42 ++++++++++++++----- 5 files changed, 118 insertions(+), 23 deletions(-) diff --git a/components/src/preact/lineageFilter/lineage-filter.stories.tsx b/components/src/preact/lineageFilter/lineage-filter.stories.tsx index 3ce4a033..647aa1b6 100644 --- a/components/src/preact/lineageFilter/lineage-filter.stories.tsx +++ b/components/src/preact/lineageFilter/lineage-filter.stories.tsx @@ -1,4 +1,5 @@ import { type Meta, type StoryObj } from '@storybook/preact'; +import { expect, fireEvent, fn, waitFor, within } from '@storybook/test'; import { LineageFilter, type LineageFilterProps } from './lineage-filter'; import { previewHandles } from '../../../.storybook/preview'; @@ -55,6 +56,39 @@ export const Default: StoryObj = { ), }; +export const WithInitialValue: StoryObj = { + ...Default, + args: { + ...Default.args, + initialValue: 'XCB', + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + + const changedListenerMock = fn(); + await step('Setup event listener mock', async () => { + canvasElement.addEventListener('gs-lineage-filter-changed', changedListenerMock); + }); + + await waitFor(() => { + const input = canvas.getByPlaceholderText('Enter lineage', { exact: false }); + expect(input).toHaveValue('XCB'); + }); + + await step('Remove initial value', async () => { + await fireEvent.click(canvas.getByRole('button', { name: '✕' })); + + await expect(changedListenerMock).toHaveBeenCalledWith( + expect.objectContaining({ + detail: { + host: undefined, + }, + }), + ); + }); + }, +}; + export const WithNoLapisField: StoryObj = { ...Default, args: { diff --git a/components/src/preact/lineageFilter/lineage-filter.tsx b/components/src/preact/lineageFilter/lineage-filter.tsx index 537eed66..9f932407 100644 --- a/components/src/preact/lineageFilter/lineage-filter.tsx +++ b/components/src/preact/lineageFilter/lineage-filter.tsx @@ -1,5 +1,5 @@ import { type FunctionComponent } from 'preact'; -import { useContext, useRef } from 'preact/hooks'; +import { useContext, useRef, useState } from 'preact/hooks'; import z from 'zod'; import { fetchLineageAutocompleteList } from './fetchLineageAutocompleteList'; @@ -45,6 +45,9 @@ const LineageFilterInner: FunctionComponent = ({ const inputRef = useRef(null); + const [hasInput, setHasInput] = useState(!!initialValue); + const [inputValue, setInputValue] = useState(initialValue || ''); + const { data, error, isLoading } = useQuery( () => fetchLineageAutocompleteList(lapis, lapisField), [lapisField, lapis], @@ -73,6 +76,8 @@ const LineageFilterInner: FunctionComponent = ({ composed: true, }), ); + setHasInput(value !== undefined); + setInputValue(value || ''); } }; @@ -85,15 +90,32 @@ const LineageFilterInner: FunctionComponent = ({ return ( <> - +
+ + {hasInput && ( + + )} +
{data.map((item) => (