Skip to content

Commit

Permalink
docs(components): document gs-location-filter
Browse files Browse the repository at this point in the history
Refs: #129
  • Loading branch information
fengelniederhammer committed Apr 24, 2024
1 parent 68ea129 commit 43fb24f
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 14 deletions.
1 change: 1 addition & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ This helps others quickly grasping what you did even if they are not familiar wi

### PR Checklist
<!-- Check completed items of strikethrough irrelevant items (using ~~text~~) -->
- [ ] All necessary documentation has been adapted.
- [ ] The implemented feature is covered by an appropriate test.
4 changes: 2 additions & 2 deletions .github/workflows/storybook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
uses: bitovi/github-actions-storybook-to-github-pages@v1.0.3
with:
path: components/storybook-static
install_command: cd components && npm ci && cd ..
build_command: cd components && npm run build-storybook && cd ..
install_command: cd components && npm ci&& cd ..
build_command: cd components && npm run generate-manifest && npm run build-storybook && cd ..
env:
DISABLE_PREACT_STORYBOOK: true
4 changes: 3 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ jobs:
key: ${{ runner.os }}-node-${{ hashFiles('components/**/package-lock.json') }}

- name: Install npm packages
run: npm ci
run: |
npm ci
npm run generate-manifest
- name: Get Installed Playwright Version
id: playwright-version
Expand Down
2 changes: 1 addition & 1 deletion components/.storybook-preact/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { StorybookConfig } from '@storybook/preact-vite';

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(jsx|tsx)'],
stories: ['../src/**/*.stories.@(jsx|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
Expand Down
5 changes: 4 additions & 1 deletion components/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import type { Preview } from '@storybook/web-components';
import { Preview, setCustomElementsManifest } from '@storybook/web-components';

import '../src/styles/tailwind.css';
import { REFERENCE_GENOME_ENDPOINT } from '../src/constants';
import referenceGenome from '../src/lapisApi/__mockData__/referenceGenome.json';
import customElements from '../custom-elements.json';

setCustomElementsManifest(customElements);

const preview: Preview = {
parameters: {
Expand Down
3 changes: 2 additions & 1 deletion components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ npm run generate-manifest:watch

We use Storybook to develop our components.

To start Storybook, run:
To start Storybook, run (`npm run generate-manifest` makes sure to generate the `custom-elements.json` first):

```bash
npm run generate-manifest
npm run storybook-preact
npm run storybook
```
Expand Down
16 changes: 16 additions & 0 deletions components/src/web-components/PreactLitAdapter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,32 @@ const minMaxPercentSliderElementCss = unsafeCSS(minMaxPercentSliderCss);
export abstract class PreactLitAdapter extends ReactiveElement {
static override styles = [tailwindElementCss, minMaxPercentSliderElementCss];

/**
* @internal
* The URL of the Lapis instance.
*
* This component must be a child of a `gs-app` component.
* This value will automatically be injected by the parent `gs-app` component.
*/
@consume({ context: lapisContext })
lapis: string = '';

/**
* @internal
* The reference genomes of the underlying organism.
* These will be fetched from the Lapis instance.
*
* This component must be a child of a `gs-app` component.
* This value will automatically be injected by the parent `gs-app` component.
*/
@consume({ context: referenceGenomeContext, subscribe: true })
referenceGenome: ReferenceGenome = {
nucleotideSequences: [],
genes: [],
};

override update(changedProperties: PropertyValues) {
console.log('this.lapis', this.lapis);
const vdom = (
<LapisUrlContext.Provider value={this.lapis}>
<ReferenceGenomeContext.Provider value={this.referenceGenome}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { withActions } from '@storybook/addon-actions/decorator';
import { expect, fn, userEvent, waitFor } from '@storybook/test';
import type { Meta, StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';

import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
import '../app';
import './location-filter-component';
import data from '../../preact/locationFilter/__mockData__/aggregated.json';
import { type LocationFilterProps } from '../../preact/locationFilter/location-filter';
import { withinShadowRoot } from '../withinShadowRoot.story';

const meta: Meta = {
Expand All @@ -18,21 +20,21 @@ const meta: Meta = {
},
},
decorators: [withActions],
tags: ['autodocs'],
};

export default meta;

const Template: StoryObj<{ fields: string[] }> = {
const Template: StoryObj<LocationFilterProps> = {
render: (args) => {
return html` <gs-app lapis="${LAPIS_URL}">
<div class="max-w-screen-lg">
<gs-location-filter .fields=${args.fields}></gs-location-filter>
<gs-location-filter .fields=${args.fields} value=${ifDefined(args.value)}></gs-location-filter>
</div>
</gs-app>`;
},
args: {
fields: ['region', 'country', 'division', 'location'],
value: '',
},
};

Expand All @@ -44,7 +46,7 @@ const aggregatedEndpointMatcher = {
},
};

export const LocationFilter: StoryObj<{ fields: string[] }> = {
export const LocationFilter: StoryObj<LocationFilterProps> = {
...Template,
parameters: {
fetchMock: {
Expand All @@ -67,7 +69,7 @@ export const LocationFilter: StoryObj<{ fields: string[] }> = {
},
};

export const DelayToShowLoadingState: StoryObj<{ fields: string[] }> = {
export const DelayToShowLoadingState: StoryObj<LocationFilterProps> = {
...Template,
parameters: {
fetchMock: {
Expand All @@ -87,7 +89,7 @@ export const DelayToShowLoadingState: StoryObj<{ fields: string[] }> = {
},
};

export const FetchingLocationsFails: StoryObj<{ fields: string[] }> = {
export const FetchingLocationsFails: StoryObj<LocationFilterProps> = {
...Template,
parameters: {
fetchMock: {
Expand All @@ -113,7 +115,7 @@ export const FetchingLocationsFails: StoryObj<{ fields: string[] }> = {
},
};

export const FiresEvent: StoryObj<{ fields: string[] }> = {
export const FiresEvent: StoryObj<LocationFilterProps> = {
...Template,
parameters: {
fetchMock: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,51 @@ import { LocationFilter } from '../../preact/locationFilter/location-filter';
import { PreactLitAdapter } from '../PreactLitAdapter';

/**
* @fires {CustomEvent<Record<string, string>>} gs-location-changed - When the location has changed
* ## Tag
*
* `gs-location-filter`
*
* ## Context
*
* This component provides an input field to specify filters for locations.
*
* It expects a list of fields that form a strict hierarchical order, such as continent, country, and city.
* The component retrieves a list of all possible values for these fields from the Lapis instance.
* This list is then utilized to display autocomplete suggestions and to validate the input.
*
* Given `fields` are `['field1', 'field2', ..., 'fieldN']`,
* then valid values for the location filter must be in the form `valueForField1 / valueForField2 / ... / valueForFieldK`,
* where `1 <= K <= N`.
* Values for the fields `i > K` are considered `undefined`.
*
* @fires {CustomEvent<Record<string, string>>} gs-location-changed
* 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"
* }
* ```
*/
@customElement('gs-location-filter')
export class LocationFilterComponent extends PreactLitAdapter {
/**
* The initial value to use for this location filter.
* Must be of the form `valueForField1 / valueForField2 / ... / valueForFieldN`.
*/
@property()
value = '';

/**
* The fields to display in the location filter, in hierarchical order.
* The top-level field should be the first entry in the array.
* This component assumes that the values for each field form a strict hierarchy
* (e.g., `fields = ['continent', 'country', 'city']`).
*/
@property({ type: Array })
fields: string[] = [];

Expand Down
25 changes: 25 additions & 0 deletions components/src/web-components/input/location-filter.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ArgTypes, Description, Meta, Story, Title, Source } from '@storybook/blocks';

import * as LocationFilterStories from './location-filter-component.stories.ts';

<Meta of={LocationFilterStories} name='Docs' />

<Title of={LocationFilterStories} />

<Description of={LocationFilterStories} />

## Specification

<ArgTypes of={LocationFilterStories} />

## Example

<Source
code={`<gs-location-filter fields="['continent', 'country']" value='Europe / Switzerland'></gs-location-filter>`}
/>

### Live Example

[See here](?path=/story/input-location-filter--location-filter)

<Story of={LocationFilterStories.LocationFilter} />
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const meta: Meta = {
},
},
decorators: [withActions],
tags: ['autodocs'],
};

export default meta;
Expand Down

0 comments on commit 43fb24f

Please sign in to comment.