Skip to content

Commit

Permalink
Feat(web-react): Introduce Card component #1535
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelklibani committed Dec 9, 2024
1 parent 47c76d1 commit 091248e
Show file tree
Hide file tree
Showing 53 changed files with 4,149 additions and 0 deletions.
403 changes: 403 additions & 0 deletions packages/web-react/docs/stories/examples/CardComposition.stories.tsx

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/web-react/scripts/entryPoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const entryPoints = [
{ dirs: ['components', 'Alert'] },
{ dirs: ['components', 'Breadcrumbs'] },
{ dirs: ['components', 'Button'] },
{ dirs: ['components', 'Card'] },
{ dirs: ['components', 'Checkbox'] },
{ dirs: ['components', 'Collapse'] },
{ dirs: ['components', 'Container'] },
Expand Down
29 changes: 29 additions & 0 deletions packages/web-react/src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client';

import classNames from 'classnames';
import React, { ElementType } from 'react';
import { Direction } from '../../constants';
import { useStyleProps } from '../../hooks';
import { SpiritCardProps } from '../../types';
import { useCardStyleProps } from './useCardStyleProps';

const defaultProps: Partial<SpiritCardProps> = {
direction: Direction.VERTICAL,
elementType: 'article',
isBoxed: false,
};

const Card = <T extends ElementType = 'article'>(props: SpiritCardProps<T>) => {
const propsWithDefaults = { ...defaultProps, ...props };
const { elementType: ElementTag = 'article', direction, isBoxed, children, ...restProps } = propsWithDefaults;
const { classProps } = useCardStyleProps({ direction, isBoxed });
const { styleProps, props: otherProps } = useStyleProps(restProps);

return (
<ElementTag {...otherProps} className={classNames(classProps.root, styleProps.className)} style={styleProps.style}>
{children}
</ElementTag>
);
};

export default Card;
27 changes: 27 additions & 0 deletions packages/web-react/src/components/Card/CardArtwork.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client';

import classNames from 'classnames';
import React from 'react';
import { AlignmentX } from '../../constants';
import { useStyleProps } from '../../hooks';
import { SpiritCardArtworkProps } from '../../types';
import { useCardStyleProps } from './useCardStyleProps';

const defaultProps: Partial<SpiritCardArtworkProps> = {
alignmentX: AlignmentX.LEFT,
};

const CardArtwork = (props: SpiritCardArtworkProps) => {
const propsWithDefaults = { ...defaultProps, ...props };
const { children, alignmentX, ...restProps } = propsWithDefaults;
const { classProps } = useCardStyleProps({ artworkAlignmentX: alignmentX });
const { styleProps, props: otherProps } = useStyleProps(restProps);

return (
<div {...otherProps} className={classNames(classProps.artwork, styleProps.className)} style={styleProps.style}>
{children}
</div>
);
};

export default CardArtwork;
26 changes: 26 additions & 0 deletions packages/web-react/src/components/Card/CardBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use client';

import classNames from 'classnames';
import React from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritCardBodyProps } from '../../types';
import { useCardStyleProps } from './useCardStyleProps';

const defaultProps: Partial<SpiritCardBodyProps> = {
isSelectable: false,
};

const CardBody = (props: SpiritCardBodyProps) => {
const propsWithDefaults = { ...defaultProps, ...props };
const { children, isSelectable, ...restProps } = propsWithDefaults;
const { classProps } = useCardStyleProps({ isSelectable });
const { styleProps, props: otherProps } = useStyleProps(restProps);

return (
<div {...otherProps} className={classNames(classProps.body, styleProps.className)} style={styleProps.style}>
{children}
</div>
);
};

export default CardBody;
21 changes: 21 additions & 0 deletions packages/web-react/src/components/Card/CardEyebrow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use client';

import classNames from 'classnames';
import React from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritCardEyebrowProps } from '../../types';
import { useCardStyleProps } from './useCardStyleProps';

const CardEyebrow = (props: SpiritCardEyebrowProps) => {
const { children, ...restProps } = props;
const { classProps } = useCardStyleProps();
const { styleProps, props: otherProps } = useStyleProps(restProps);

return (
<div {...otherProps} className={classNames(classProps.eyebrow, styleProps.className)} style={styleProps.style}>
{children}
</div>
);
};

export default CardEyebrow;
27 changes: 27 additions & 0 deletions packages/web-react/src/components/Card/CardFooter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client';

import classNames from 'classnames';
import React from 'react';
import { AlignmentX } from '../../constants';
import { useStyleProps } from '../../hooks';
import { SpiritCardFooterProps } from '../../types';
import { useCardStyleProps } from './useCardStyleProps';

const defaultProps: Partial<SpiritCardFooterProps> = {
alignmentX: AlignmentX.LEFT,
};

const CardFooter = (props: SpiritCardFooterProps) => {
const propsWithDefaults = { ...defaultProps, ...props };
const { children, alignmentX, ...restProps } = propsWithDefaults;
const { classProps } = useCardStyleProps({ footerAlignmentX: alignmentX });
const { styleProps, props: otherProps } = useStyleProps(restProps);

return (
<footer {...otherProps} className={classNames(classProps.footer, styleProps.className)} style={styleProps.style}>
{children}
</footer>
);
};

export default CardFooter;
40 changes: 40 additions & 0 deletions packages/web-react/src/components/Card/CardLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use client';

import classNames from 'classnames';
import React, { ElementType, forwardRef } from 'react';
import { useStyleProps } from '../../hooks';
import { PolymorphicRef, SpiritCardLinkProps, SpiritLinkProps } from '../../types';
import { useCardStyleProps } from './useCardStyleProps';

const defaultProps: Partial<SpiritCardLinkProps> = {
elementType: 'a',
};

/* We need an exception for components exported with forwardRef */
/* eslint no-underscore-dangle: ['error', { allow: ['_CardLink'] }] */
const _CardLink = <E extends ElementType = 'a'>(props: SpiritCardLinkProps<E>, ref: PolymorphicRef<E>): JSX.Element => {
const propsWithDefaults = { ...defaultProps, ...props };
const {
elementType: ElementTag = defaultProps.elementType as ElementType,
children,
...restProps
} = propsWithDefaults;
const { classProps } = useCardStyleProps();
const { styleProps, props: otherProps } = useStyleProps(restProps);

return (
<ElementTag
{...otherProps}
{...styleProps}
href={restProps.href}
className={classNames(classProps.link, styleProps.className)}
ref={ref}
>
{children}
</ElementTag>
);
};

const CardLink = forwardRef<HTMLAnchorElement, SpiritLinkProps<ElementType>>(_CardLink);

export default CardLink;
21 changes: 21 additions & 0 deletions packages/web-react/src/components/Card/CardLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use client';

import classNames from 'classnames';
import React from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritCardLogoProps } from '../../types';
import { useCardStyleProps } from './useCardStyleProps';

const CardLogo = (props: SpiritCardLogoProps) => {
const { children, ...restProps } = props;
const { classProps } = useCardStyleProps();
const { styleProps, props: otherProps } = useStyleProps(restProps);

return (
<div {...otherProps} className={classNames(classProps.logo, styleProps.className)} style={{ ...styleProps.style }}>
{children}
</div>
);
};

export default CardLogo;
28 changes: 28 additions & 0 deletions packages/web-react/src/components/Card/CardMedia.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use client';

import classNames from 'classnames';
import React from 'react';
import { useStyleProps } from '../../hooks';
import { CardSizes, SpiritCardMediaProps } from '../../types';
import { useCardStyleProps } from './useCardStyleProps';

const defaultProps: Partial<SpiritCardMediaProps> = {
hasFilledHeight: false,
isExpanded: false,
size: CardSizes.AUTO,
};

const CardMedia = (props: SpiritCardMediaProps) => {
const propsWithDefaults = { ...defaultProps, ...props };
const { children, size, isExpanded, hasFilledHeight, ...restProps } = propsWithDefaults;
const { classProps } = useCardStyleProps({ size, isExpanded, hasFilledHeight });
const { styleProps, props: otherProps } = useStyleProps(restProps);

return (
<div {...otherProps} className={classNames(classProps.media, styleProps.className)} style={styleProps.style}>
<div className={classProps.mediaCanvas}>{children}</div>
</div>
);
};

export default CardMedia;
27 changes: 27 additions & 0 deletions packages/web-react/src/components/Card/CardTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client';

import classNames from 'classnames';
import React, { ElementType } from 'react';
import { useStyleProps } from '../../hooks';
import { SpiritCardTitleProps } from '../../types';
import { useCardStyleProps } from './useCardStyleProps';

const defaultProps: Partial<SpiritCardTitleProps> = {
elementType: 'h4',
isHeading: true,
};

const CardTitle = <T extends ElementType = 'h4'>(props: SpiritCardTitleProps<T>) => {
const propsWithDefaults = { ...defaultProps, ...props };
const { elementType: ElementTag = 'h4', children, isHeading, ...restProps } = propsWithDefaults;
const { classProps } = useCardStyleProps({ isHeading });
const { styleProps, props: otherProps } = useStyleProps(restProps);

return (
<ElementTag {...otherProps} className={classNames(classProps.title, styleProps.className)} style={styleProps.style}>
{children}
</ElementTag>
);
};

export default CardTitle;
Loading

0 comments on commit 091248e

Please sign in to comment.