Unverified Commit 0ebb4ac3 authored by Andrey Azov's avatar Andrey Azov Committed by GitHub
Browse files

Add a Chevron component (#515)

Also, add a ShowHide component, which consists of a label associated with a chevron
parent 924e02f3
Pipeline #175665 passed with stages
in 6 minutes and 46 seconds
...@@ -11,13 +11,9 @@ ...@@ -11,13 +11,9 @@
width: 16px; width: 16px;
} }
.expandBtn { .chevron {
margin-left: 10px; margin-left: 8px;
height: 6px;
img {
height: 12px;
width: 12px;
}
} }
&:hover, &:hover,
......
...@@ -136,7 +136,7 @@ describe('<TrackPanelListItem />', () => { ...@@ -136,7 +136,7 @@ describe('<TrackPanelListItem />', () => {
it('toggles the expanded/collapsed state of the track when clicked on the expand button', async () => { it('toggles the expanded/collapsed state of the track when clicked on the expand button', async () => {
const { container } = wrapInRedux(); const { container } = wrapInRedux();
const expandButton = container.querySelector('.expandBtn') as HTMLElement; const expandButton = container.querySelector('.chevron') as HTMLElement;
userEvent.click(expandButton); userEvent.click(expandButton);
......
...@@ -23,9 +23,6 @@ import { RootState } from 'src/store'; ...@@ -23,9 +23,6 @@ import { RootState } from 'src/store';
import analyticsTracking from 'src/services/analytics-service'; import analyticsTracking from 'src/services/analytics-service';
import browserMessagingService from 'src/content/app/browser/browser-messaging-service'; import browserMessagingService from 'src/content/app/browser/browser-messaging-service';
import ImageButton from 'src/shared/components/image-button/ImageButton';
import VisibilityIcon from 'src/shared/components/visibility-icon/VisibilityIcon';
import { import {
TrackItemColour, TrackItemColour,
TrackItemColourKey, TrackItemColourKey,
...@@ -57,8 +54,10 @@ import { ...@@ -57,8 +54,10 @@ import {
getBrowserActiveEnsObjectId getBrowserActiveEnsObjectId
} from '../../browserSelectors'; } from '../../browserSelectors';
import chevronDownIcon from 'static/img/shared/chevron-down.svg'; import ImageButton from 'src/shared/components/image-button/ImageButton';
import chevronUpIcon from 'static/img/shared/chevron-up.svg'; import Chevron from 'src/shared/components/chevron/Chevron';
import VisibilityIcon from 'src/shared/components/visibility-icon/VisibilityIcon';
import { ReactComponent as Ellipsis } from 'static/img/track-panel/ellipsis.svg'; import { ReactComponent as Ellipsis } from 'static/img/track-panel/ellipsis.svg';
import { DrawerView } from 'src/content/app/browser/drawer/drawerState'; import { DrawerView } from 'src/content/app/browser/drawer/drawerState';
...@@ -225,12 +224,11 @@ export const TrackPanelListItem = (props: TrackPanelListItemProps) => { ...@@ -225,12 +224,11 @@ export const TrackPanelListItem = (props: TrackPanelListItemProps) => {
</span> </span>
)} )}
{track.child_tracks && ( {track.child_tracks && (
<button onClick={toggleExpand} className={styles.expandBtn}> <Chevron
<img onClick={toggleExpand}
src={isCollapsed ? chevronDownIcon : chevronUpIcon} direction={isCollapsed ? 'down' : 'up'}
alt={isCollapsed ? 'expand' : 'collapse'} classNames={{ svg: styles.chevron }}
/> />
</button>
)} )}
</label> </label>
<div className={styles.ellipsisHolder}> <div className={styles.ellipsisHolder}>
......
...@@ -76,7 +76,9 @@ $backgroundColor: $black; ...@@ -76,7 +76,9 @@ $backgroundColor: $black;
top: 0; top: 0;
} }
.filterLabelWrapper { .filterLabelWrapper {
display: flex;
justify-content: flex-end;
padding-right: 20px; padding-right: 20px;
padding-bottom: 9px; padding-bottom: 9px;
padding-top: 6px; padding-top: 6px;
...@@ -118,14 +120,3 @@ $backgroundColor: $black; ...@@ -118,14 +120,3 @@ $backgroundColor: $black;
top: -2px; top: -2px;
} }
} }
.chevron {
margin-left: 10px;
margin-bottom: -3px;
height: 12px;
width: 12px;
}
.chevronUp {
transform: rotate(180deg);
}
...@@ -57,12 +57,11 @@ import GeneRelationships from 'src/content/app/entity-viewer/gene-view/component ...@@ -57,12 +57,11 @@ import GeneRelationships from 'src/content/app/entity-viewer/gene-view/component
import ViewInApp from 'src/shared/components/view-in-app/ViewInApp'; import ViewInApp from 'src/shared/components/view-in-app/ViewInApp';
import { CircleLoader } from 'src/shared/components/loader/Loader'; import { CircleLoader } from 'src/shared/components/loader/Loader';
import { TicksAndScale } from 'src/content/app/entity-viewer/gene-view/components/base-pairs-ruler/BasePairsRuler'; import { TicksAndScale } from 'src/content/app/entity-viewer/gene-view/components/base-pairs-ruler/BasePairsRuler';
import ShowHide from 'src/shared/components/show-hide/ShowHide';
import { FullGene } from 'src/shared/types/thoas/gene'; import { FullGene } from 'src/shared/types/thoas/gene';
import { SortingRule } from 'src/content/app/entity-viewer/state/gene-view/transcripts/geneViewTranscriptsSlice'; import { SortingRule } from 'src/content/app/entity-viewer/state/gene-view/transcripts/geneViewTranscriptsSlice';
import { ReactComponent as ChevronDown } from 'static/img/shared/chevron-down.svg';
import styles from './GeneView.scss'; import styles from './GeneView.scss';
type Gene = Pick<FullGene, 'symbol'> & type Gene = Pick<FullGene, 'symbol'> &
...@@ -268,19 +267,11 @@ const GeneViewWithData = (props: GeneViewWithDataProps) => { ...@@ -268,19 +267,11 @@ const GeneViewWithData = (props: GeneViewWithDataProps) => {
> >
{props.gene.transcripts.length > 5 && ( {props.gene.transcripts.length > 5 && (
<div className={styles.filterLabelWrapper}> <div className={styles.filterLabelWrapper}>
<div <ShowHide
className={classNames([styles.filterLabel], {
[styles.openFilterLabel]: isFilterOpen
})}
onClick={toggleFilter} onClick={toggleFilter}
> isExpanded={isFilterOpen}
{filterLabel} label={filterLabel}
<ChevronDown />
className={classNames([styles.chevron], {
[styles.chevronUp]: isFilterOpen
})}
/>
</div>
</div> </div>
)} )}
</div> </div>
......
...@@ -57,8 +57,6 @@ ...@@ -57,8 +57,6 @@
.downloadLink { .downloadLink {
grid-area: downloadLink; grid-area: downloadLink;
color: $blue;
cursor: pointer;
padding-top: 6px; padding-top: 6px;
} }
...@@ -67,17 +65,6 @@ ...@@ -67,17 +65,6 @@
padding-top: 6px; padding-top: 6px;
} }
.chevron {
margin-left: 10px;
margin-bottom: -3px;
height: 12px;
width: 12px;
transition: transform linear 0.2s;
&Up {
transform: rotate(-180deg);
}
}
.viewInApp { .viewInApp {
padding-top: 12px; padding-top: 12px;
} }
...@@ -35,6 +35,7 @@ import { buildFocusIdForUrl } from 'src/shared/state/ens-object/ensObjectHelpers ...@@ -35,6 +35,7 @@ import { buildFocusIdForUrl } from 'src/shared/state/ens-object/ensObjectHelpers
import { InstantDownloadTranscript } from 'src/shared/components/instant-download'; import { InstantDownloadTranscript } from 'src/shared/components/instant-download';
import ViewInApp from 'src/shared/components/view-in-app/ViewInApp'; import ViewInApp from 'src/shared/components/view-in-app/ViewInApp';
import ShowHide from 'src/shared/components/show-hide/ShowHide';
import { toggleTranscriptDownload } from 'src/content/app/entity-viewer/state/gene-view/transcripts/geneViewTranscriptsSlice'; import { toggleTranscriptDownload } from 'src/content/app/entity-viewer/state/gene-view/transcripts/geneViewTranscriptsSlice';
import { clearExpandedProteins } from 'src/content/app/entity-viewer/state/gene-view/proteins/geneViewProteinsSlice'; import { clearExpandedProteins } from 'src/content/app/entity-viewer/state/gene-view/proteins/geneViewProteinsSlice';
...@@ -48,8 +49,6 @@ import { View } from 'src/content/app/entity-viewer/state/gene-view/view/geneVie ...@@ -48,8 +49,6 @@ import { View } from 'src/content/app/entity-viewer/state/gene-view/view/geneVie
import transcriptsListStyles from '../DefaultTranscriptsList.scss'; import transcriptsListStyles from '../DefaultTranscriptsList.scss';
import styles from './TranscriptsListItemInfo.scss'; import styles from './TranscriptsListItemInfo.scss';
import { ReactComponent as ChevronDown } from 'static/img/shared/chevron-down.svg';
type Gene = Pick<FullGene, 'unversioned_stable_id' | 'stable_id'>; type Gene = Pick<FullGene, 'unversioned_stable_id' | 'stable_id'>;
type Transcript = Pick< type Transcript = Pick<
FullTranscript, FullTranscript,
...@@ -139,10 +138,6 @@ export const TranscriptsListItemInfo = ( ...@@ -139,10 +138,6 @@ export const TranscriptsListItemInfo = (
return urlFor.browser({ genomeId: genomeId, focus: focusIdForUrl }); return urlFor.browser({ genomeId: genomeId, focus: focusIdForUrl });
}; };
const chevronClassForDownload = classNames(styles.chevron, {
[styles.chevronUp]: props.expandDownload
});
return ( return (
<div className={mainStyles}> <div className={mainStyles}>
<div className={transcriptsListStyles.left}></div> <div className={transcriptsListStyles.left}></div>
...@@ -177,13 +172,12 @@ export const TranscriptsListItemInfo = ( ...@@ -177,13 +172,12 @@ export const TranscriptsListItemInfo = (
<div className={styles.moreInformation}>More information</div> <div className={styles.moreInformation}>More information</div>
<div <ShowHide
className={styles.downloadLink}
onClick={() => props.toggleTranscriptDownload(transcript.stable_id)} onClick={() => props.toggleTranscriptDownload(transcript.stable_id)}
> label="Download"
Download isExpanded={props.expandDownload}
<ChevronDown className={chevronClassForDownload} /> classNames={{ wrapper: styles.downloadLink }}
</div> />
{props.expandDownload && renderInstantDownload({ ...props, genomeId })} {props.expandDownload && renderInstantDownload({ ...props, genomeId })}
</div> </div>
<div className={transcriptsListStyles.right}> <div className={transcriptsListStyles.right}>
......
...@@ -39,13 +39,8 @@ ...@@ -39,13 +39,8 @@
padding: 0px; padding: 0px;
width: auto; width: auto;
padding-right: 60px; padding-right: 60px;
display: inline-block; grid-template-columns: max-content max-content;
margin-left: 20px; margin-left: 20px;
&:before,
&:after {
margin-top: -10px;
}
} }
.xrefAccordionItem:not(:first-child) { .xrefAccordionItem:not(:first-child) {
......
...@@ -73,13 +73,6 @@ $content-width: $gene_image_width; ...@@ -73,13 +73,6 @@ $content-width: $gene_image_width;
.chevron { .chevron {
margin-left: 6px; margin-left: 6px;
margin-bottom: -1px;
height: 12px;
width: 12px;
transition: transform linear 0.2s;
&Up {
transform: rotate(-180deg);
}
} }
.xrefCountChevronOpen { .xrefCountChevronOpen {
......
...@@ -18,7 +18,6 @@ import React, { useEffect, useState } from 'react'; ...@@ -18,7 +18,6 @@ import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import set from 'lodash/fp/set'; import set from 'lodash/fp/set';
import { Pick2 } from 'ts-multipick'; import { Pick2 } from 'ts-multipick';
import classNames from 'classnames';
import { CircleLoader } from 'src/shared/components/loader/Loader'; import { CircleLoader } from 'src/shared/components/loader/Loader';
import ProteinDomainImage from 'src/content/app/entity-viewer/gene-view/components/protein-domain-image/ProteinDomainImage'; import ProteinDomainImage from 'src/content/app/entity-viewer/gene-view/components/protein-domain-image/ProteinDomainImage';
...@@ -26,7 +25,7 @@ import ProteinImage from 'src/content/app/entity-viewer/gene-view/components/pro ...@@ -26,7 +25,7 @@ import ProteinImage from 'src/content/app/entity-viewer/gene-view/components/pro
import ProteinFeaturesCount from 'src/content/app/entity-viewer/gene-view/components/protein-features-count/ProteinFeaturesCount'; import ProteinFeaturesCount from 'src/content/app/entity-viewer/gene-view/components/protein-features-count/ProteinFeaturesCount';
import ExternalReference from 'src/shared/components/external-reference/ExternalReference'; import ExternalReference from 'src/shared/components/external-reference/ExternalReference';
import InstantDownloadProtein from 'src/shared/components/instant-download/instant-download-protein/InstantDownloadProtein'; import InstantDownloadProtein from 'src/shared/components/instant-download/instant-download-protein/InstantDownloadProtein';
import { ReactComponent as ChevronDown } from 'static/img/shared/chevron-down.svg'; import Chevron from 'src/shared/components/chevron/Chevron';
import { import {
ExternalSource, ExternalSource,
...@@ -101,23 +100,18 @@ const ProteinsListItemInfo = (props: Props) => { ...@@ -101,23 +100,18 @@ const ProteinsListItemInfo = (props: Props) => {
const params: { [key: string]: string } = useParams(); const params: { [key: string]: string } = useParams();
const { genomeId } = params; const { genomeId } = params;
const [ const [transcriptWithProteinDomains, setTranscriptWithProteinDomains] =
transcriptWithProteinDomains, useState<TranscriptWithProteinDomains | null>(null);
setTranscriptWithProteinDomains
] = useState<TranscriptWithProteinDomains | null>(null);
const [proteinSummaryStats, setProteinSummaryStats] = useState< const [proteinSummaryStats, setProteinSummaryStats] =
ProteinStats | null | undefined useState<ProteinStats | null | undefined>();
>();
const [domainsLoadingState, setDomainsLoadingState] = useState<LoadingState>( const [domainsLoadingState, setDomainsLoadingState] = useState<LoadingState>(
LoadingState.LOADING LoadingState.LOADING
); );
const [ const [summaryStatsLoadingState, setSummaryStatsLoadingState] =
summaryStatsLoadingState, useState<LoadingState>(LoadingState.LOADING);
setSummaryStatsLoadingState
] = useState<LoadingState>(LoadingState.LOADING);
const proteinId = const proteinId =
transcript.product_generating_contexts[0].product.unversioned_stable_id; transcript.product_generating_contexts[0].product.unversioned_stable_id;
...@@ -296,10 +290,6 @@ export const ProteinExternalReferenceGroup = ( ...@@ -296,10 +290,6 @@ export const ProteinExternalReferenceGroup = (
setXrefGroupOpen(!isXrefGroupOpen); setXrefGroupOpen(!isXrefGroupOpen);
}; };
const chevronClasses = classNames(styles.chevron, {
[styles.chevronUp]: isXrefGroupOpen
});
if (xrefs.length > 3) { if (xrefs.length > 3) {
const displayXref = xrefs[0]; const displayXref = xrefs[0];
return ( return (
...@@ -318,7 +308,11 @@ export const ProteinExternalReferenceGroup = ( ...@@ -318,7 +308,11 @@ export const ProteinExternalReferenceGroup = (
} }
> >
+ {xrefs.length - 1} + {xrefs.length - 1}
<ChevronDown className={chevronClasses} /> <Chevron
direction={isXrefGroupOpen ? 'up' : 'down'}
animate={true}
classNames={{ svg: styles.chevron }}
/>
</span> </span>
</div> </div>
</div> </div>
......
...@@ -5,6 +5,12 @@ $submenuSidePadding: 30px; ...@@ -5,6 +5,12 @@ $submenuSidePadding: 30px;
.helpMenu { .helpMenu {
grid-row: menu; grid-row: menu;
position: relative; position: relative;
// increase specificity through nesting in order to be able to override child's styles
.chevron {
height: 7px;
fill: $blue;
}
} }
.menuBar { .menuBar {
...@@ -67,8 +73,3 @@ $submenuSidePadding: 30px; ...@@ -67,8 +73,3 @@ $submenuSidePadding: 30px;
.submenuItem:hover { .submenuItem:hover {
background: $ice-blue; background: $ice-blue;
} }
.chevron {
height: 14px;
fill: $blue;
}
...@@ -20,7 +20,7 @@ import { useDispatch } from 'react-redux'; ...@@ -20,7 +20,7 @@ import { useDispatch } from 'react-redux';
import { push } from 'connected-react-router'; import { push } from 'connected-react-router';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { ReactComponent as Chevron } from 'static/img/shared/chevron-right.svg'; import Chevron from 'src/shared/components/chevron/Chevron';
import { import {
Menu as MenuType, Menu as MenuType,
...@@ -129,7 +129,7 @@ const Submenu = (props: SubmenuProps) => { ...@@ -129,7 +129,7 @@ const Submenu = (props: SubmenuProps) => {
{item.type === 'collection' ? ( {item.type === 'collection' ? (
<> <>
{item.name} {item.name}
<Chevron className={styles.chevron} /> <Chevron direction="right" classNames={{ svg: styles.chevron }} />
</> </>
) : ( ) : (
item.name item.name
......
...@@ -18,9 +18,12 @@ import React from 'react'; ...@@ -18,9 +18,12 @@ import React from 'react';
import noop from 'lodash/noop'; import noop from 'lodash/noop';
import classNames from 'classnames'; import classNames from 'classnames';
import { Consumer as ItemConsumer, ItemContext } from './ItemContext';
import Chevron from 'src/shared/components/chevron/Chevron';
import { InjectedButtonAttributes } from '../helpers/AccordionStore'; import { InjectedButtonAttributes } from '../helpers/AccordionStore';
import { DivAttributes } from '../helpers/types'; import { DivAttributes } from '../helpers/types';
import { Consumer as ItemConsumer, ItemContext } from './ItemContext';
import defaultStyles from '../css/Accordion.scss'; import defaultStyles from '../css/Accordion.scss';
...@@ -36,6 +39,7 @@ export const AccordionItemButton = (props: Props) => { ...@@ -36,6 +39,7 @@ export const AccordionItemButton = (props: Props) => {
extendDefaultStyles, extendDefaultStyles,
toggleExpanded, toggleExpanded,
disabled, disabled,
children,
...rest ...rest
} = props; } = props;
...@@ -55,7 +59,17 @@ export const AccordionItemButton = (props: Props) => { ...@@ -55,7 +59,17 @@ export const AccordionItemButton = (props: Props) => {
className={styles} className={styles}
onClick={disabled ? noop : toggleExpanded} onClick={disabled ? noop : toggleExpanded}
data-accordion-component="AccordionItemButton" data-accordion-component="AccordionItemButton"
/> >
<div>{children}</div>
{!disabled && (
<div>
<Chevron
direction={rest['aria-expanded'] ? 'up' : 'down'}
animate={true}
/>
</div>
)}
</div>
); );
}; };
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
} }
.accordionButtonDefault { .accordionButtonDefault {
display: grid;
grid-template-columns: 1fr auto;
column-gap: 0.6rem;
color: #444; color: #444;
cursor: pointer; cursor: pointer;
padding: 18px; padding: 18px;
...@@ -19,39 +22,11 @@ ...@@ -19,39 +22,11 @@
position: relative; position: relative;
}