Skip to content

Commit fd1ca28

Browse files
feat!: Add FlagCard & DefaultCard and implement FlagCard in DataCatalog (#1479)
**Related Ticket:** #1453 **Related PRs:** NASA-IMPACT/next-veda-ui#52 https://deploy-preview-1479--veda-ui.netlify.app/data-catalog https://deploy-preview-1479--veda-ui.netlify.app/sandbox/cards ### Description of Changes * Added a `BaseCard` component where `FlagCard` and `DefaultCard` extend off of * BaseCard Attributes to be used across cards * Created Fork of `CatalogContent` where we can start migrating components over to USWDS and renamed old one to `CatalogContentLegacy`. * This is FF * Updated ** - Exposed `CatalogContent` instead of `CatalogView`, updates reflected in connected NextJs PR * Added `Tags` component from USWDS * Added draft documentation of the components we are starting to expose from the library with props, I created this for now because we gotta start documenting this somewhere but we can figure out where and how best to document later * Added both card types to `/sandbox/cards` because right now we dont have a storybook(esque) implemented but right now, it looked like a fine enough place to showcase **What this doesn't do:** * DataSelectorModal isn't updated but uses the old view, @faustoperez will work on the designs for that so a separate ticket will follow * Card Accessibility states to be implemented as part of this ticket #1481 ### Notes & Questions About Changes * `FlagCard` and `DefaultCard` can be exposed as is, if exposed as is, they dont have the wrapping routing logic wrapped around it which makes it behave as a button. If the wrapping routing logic is wanted. The `Card` Component which is our wrapper to support current routing logic could be exposed and used where type `FLAG-LAYOUT` would be passed in. Users can decide. ### Validation / Testing * Validate that the Feature Flagging works `ENABLE_USWDS_DATA_CATALOG` * Validate when enabled... * DataCatalog Cards look correct * Entire card behaves like a button * The Card routes correctly * Validate that the DataSelectorModal is still the same as originally since nothing should have changed with its look or behavior _____ Self Validation Loom Walkthrough (recommended to watch @1.5x) https://www.loom.com/share/c52aa4227651422dbac9554a744f2aa8?sid=3ac71fca-189f-42ce-856c-0104ee6703c7
2 parents de89286 + e46fbac commit fd1ca28

File tree

29 files changed

+933
-65
lines changed

29 files changed

+933
-65
lines changed

.env

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ GOOGLE_FORM = 'https://docs.google.com/forms/d/e/1FAIpQLSfGcd3FDsM3kQIOVKjzdPn4f
1414

1515
SHOW_CONFIGURABLE_COLOR_MAP = 'TRUE'
1616

17-
# Enables the refactor page header component that uses the USWDS design system
17+
# USWDS FEATURE FLAGS
1818
ENABLE_USWDS_PAGE_HEADER = 'TRUE'
19-
# Enables the refactor page footer component that uses the USWDS design system
2019
ENABLE_USWDS_PAGE_FOOTER = 'TRUE'
20+
ENABLE_USWDS_DATA_CATALOG = 'TRUE'
21+
22+
2123
# Enables the display of Cookie consent form
2224
ENABLE_COOKIE_CONSENT_FORM = 'TRUE'

app/scripts/components/common/card/index.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import ClassicCard, { ClassicCardItem } from './classic';
1111
import CoverCard, { CoverCardItem } from './cover';
1212
import FeaturedCard, { FeaturedCardItem } from './featured';
1313
import HorizontalInfoCard, { HorizontalInfoCardItem } from './horizontal-info';
14+
import FlagCard from './uswds-cards/flag-card';
15+
import { LabelType } from './uswds-cards/types';
1416
import { LinkProperties } from '$types/veda';
1517
import * as utils from '$utils/utils';
1618
import { ElementInteractive } from '$components/common/element-interactive';
@@ -27,7 +29,8 @@ export enum CardType {
2729
CLASSIC = 'classic',
2830
COVER = 'cover',
2931
FEATURED = 'featured',
30-
HORIZONTALINFO = 'horizontal-info'
32+
HORIZONTALINFO = 'horizontal-info',
33+
FLAG = 'flag'
3134
}
3235

3336
export interface CardItemProps {
@@ -52,6 +55,7 @@ interface BaseCardComponentProps {
5255
footerContent?: JSX.Element;
5356
hideExternalLinkBadge?: boolean;
5457
onCardClickCapture?: MouseEventHandler;
58+
cardLabel?: LabelType;
5559
}
5660

5761
interface LinkCardComponentProps extends BaseCardComponentProps {
@@ -191,7 +195,26 @@ export default function CardComponent(
191195
tagLabels={data.tagLabels}
192196
/>
193197
);
198+
} else if (
199+
cardType === CardType.FLAG &&
200+
data.imgSrc &&
201+
data.imgAlt &&
202+
data.description &&
203+
data.footerContent
204+
) {
205+
baseProps['children'] = (
206+
<FlagCard
207+
imgSrc={data.imgSrc}
208+
imgAlt={data.imgAlt}
209+
heading={data.title}
210+
description={data.description}
211+
footer={data.footerContent}
212+
cardLabel='data_collection'
213+
/>
214+
);
215+
baseProps['style'] = { width: '100%' };
194216
}
217+
195218
return baseProps;
196219
};
197220

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from 'react';
2+
import { CardProps } from './types';
3+
import BaseCard from '.';
4+
5+
export default function DefaultCard(props: CardProps) {
6+
const defaultGridLayout = props.gridLayout
7+
? props.gridLayout
8+
: { desktop: { col: 3 } };
9+
return <BaseCard {...props} gridLayout={defaultGridLayout} />;
10+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react';
2+
import { CardProps } from './types';
3+
import BaseCard from '.';
4+
5+
type FlagCardProps = CardProps & {
6+
layout?: 'flagDefault' | 'flagMediaRight';
7+
};
8+
9+
export default function FlagCard(props: FlagCardProps) {
10+
const defaultLayout = props.layout ? props.layout : 'flagDefault';
11+
const defaultGridLayout = props.gridLayout
12+
? props.gridLayout
13+
: { desktop: { col: 12 } }; // Full Width
14+
return (
15+
<BaseCard
16+
{...props}
17+
layout={defaultLayout}
18+
gridLayout={defaultGridLayout}
19+
/>
20+
);
21+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react';
2+
import { CardProps } from './types';
3+
import { createCardLabel } from './utils';
4+
import {
5+
USWDSCardComponent,
6+
USWDSCardBody,
7+
USWDSCardFooter,
8+
USWDSCardHeader,
9+
USWDSCardMedia
10+
} from '$uswds';
11+
import './styles.scss';
12+
13+
// @TODO: Implement overrideable Card Acessibility States
14+
15+
function isString(value: string | JSX.Element): boolean {
16+
return typeof value === 'string';
17+
}
18+
19+
export default function BaseCard({
20+
layout,
21+
imgSrc,
22+
imgAlt,
23+
heading,
24+
description,
25+
footer,
26+
gridLayout,
27+
cardLabel
28+
}: CardProps) {
29+
const defaultHeaderClassNames = 'usa-card__heading card-header';
30+
const defaultBodyClassNames = 'font-body-xs';
31+
32+
return (
33+
<USWDSCardComponent layout={layout} gridLayout={gridLayout}>
34+
<USWDSCardHeader>
35+
{isString(heading) ? (
36+
<h2 className={defaultHeaderClassNames}>{heading}</h2>
37+
) : (
38+
heading
39+
)}
40+
</USWDSCardHeader>
41+
<USWDSCardMedia>
42+
{cardLabel && (
43+
<div style={{ position: 'absolute', padding: '15px' }}>
44+
{createCardLabel(cardLabel)}
45+
</div>
46+
)}
47+
<img src={imgSrc} alt={imgAlt} />
48+
</USWDSCardMedia>
49+
<USWDSCardBody>
50+
{isString(description) ? (
51+
<p className={defaultBodyClassNames}>{description}</p>
52+
) : (
53+
description
54+
)}
55+
</USWDSCardBody>
56+
<USWDSCardFooter>{footer}</USWDSCardFooter>
57+
</USWDSCardComponent>
58+
);
59+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@use '$styles/veda-ui-theme-vars.scss' as themeVars;
2+
3+
.usa-card {
4+
margin-bottom: 0;
5+
}
6+
7+
.card-header {
8+
color: themeVars.$veda-uswds-color-base-ink;
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export type LabelType = 'data_collection' | 'story';
2+
3+
export interface CardProps {
4+
layout?: string;
5+
heading: string | JSX.Element;
6+
footer: JSX.Element;
7+
imgSrc: string;
8+
imgAlt: string;
9+
description: string | JSX.Element;
10+
gridLayout?: any;
11+
cardLabel?: LabelType;
12+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react';
2+
import { LabelType } from './types';
3+
import { Tags } from '$components/common/tags';
4+
import Collection from '$components/common/svgs/collection';
5+
6+
const mapper = {
7+
data_collection: {
8+
title: 'Data Collection',
9+
svg: <Collection size='sm' />
10+
},
11+
story: {
12+
title: 'Story',
13+
svg: <Collection size='sm' /> // TO BE REPLACED
14+
}
15+
};
16+
17+
export const createCardLabel = (type: LabelType): JSX.Element => {
18+
const item = mapper[type];
19+
20+
return <Tags icon={item.svg} items={[item.title]} />;
21+
};

0 commit comments

Comments
 (0)