From 1142ed743560ed6f74e888af6e65cbf90eef8283 Mon Sep 17 00:00:00 2001 From: gvieiraschwade Date: Sun, 9 Aug 2020 21:14:39 +0200 Subject: [PATCH] feat: playing card atom --- docs/playing-cards-svg.md | 31 + src/assets/svg-cards-optimized.svg | 1849 +++++++++++++++++ .../atoms/PlayingCard/PlayingCard.test.tsx | 61 + .../atoms/PlayingCard/PlayingCard.tsx | 40 + .../pages/HomePage/HomePage.test.tsx | 2 +- src/components/pages/HomePage/HomePage.tsx | 72 +- src/models/PlayingCardType.tsx | 56 + 7 files changed, 2107 insertions(+), 4 deletions(-) create mode 100644 docs/playing-cards-svg.md create mode 100644 src/assets/svg-cards-optimized.svg create mode 100644 src/components/atoms/PlayingCard/PlayingCard.test.tsx create mode 100644 src/components/atoms/PlayingCard/PlayingCard.tsx create mode 100644 src/models/PlayingCardType.tsx diff --git a/docs/playing-cards-svg.md b/docs/playing-cards-svg.md new file mode 100644 index 0000000..6e40441 --- /dev/null +++ b/docs/playing-cards-svg.md @@ -0,0 +1,31 @@ +# Playing cards svg + +The SVG embedded in this project comes from [https://github.com/htdebeer/SVG-cards](https://github.com/htdebeer/SVG-cards), after a little optmization via [SVGOMG](https://jakearchibald.github.io/svgomg/) + +In order to use them: + +```jsx +import svgCards from '[RELATIVE_PATH_TO_ASSETS]/svg-cards-optimized.svg'; + + + + +``` + +The various cards have the following names: + +* Jokers: joker_black and joker_red +* Back card: back or alternative-back +* Picture cards: {club,diamond,heart,spade}_{king,queen,jack} +* Pip cards:{club,diamond,heart,spade}_{1,2,3,4,5,6,7,8,9,10} + +Examples: + +* The ace of club is `club_1`. +* The queen of diamonds is `diamond_queen`. + +The cards have the following natural positions: + +* width: `169.075` +* height: `244.64` +* center: `(+98.0375, +122.320)` \ No newline at end of file diff --git a/src/assets/svg-cards-optimized.svg b/src/assets/svg-cards-optimized.svg new file mode 100644 index 0000000..0821891 --- /dev/null +++ b/src/assets/svg-cards-optimized.svg @@ -0,0 +1,1849 @@ + + + + + 10 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + A + + + + + K + + + + + Q + + + + + J + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JOKER + + + JOKER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/atoms/PlayingCard/PlayingCard.test.tsx b/src/components/atoms/PlayingCard/PlayingCard.test.tsx new file mode 100644 index 0000000..15f4791 --- /dev/null +++ b/src/components/atoms/PlayingCard/PlayingCard.test.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { PlayingCard } from './PlayingCard'; + +const testCardSvg = (el: HTMLElement, pattern: string | RegExp) => + expect(el).toHaveAttribute('xlink:href', expect.stringMatching(pattern)); + +describe('PlayingCard', () => { + it('should render correctly', () => { + const { getByTestId } = render(); + expect(getByTestId('BaseCard')).toBeInTheDocument(); + }); + + describe('on default rendering', () => { + let frontFace: HTMLElement; + let backFace: HTMLElement; + beforeEach(() => { + const { getByTestId } = render(); + frontFace = getByTestId('PlayingCard_front_use'); + backFace = getByTestId('PlayingCard_back_use'); + }); + + it('should default front to joker_black', () => { + testCardSvg(frontFace, /#joker_black$/i); + }); + + it('should default front to no fill', () => { + expect(frontFace).toHaveAttribute('fill', ''); + }); + + it('should default back to back', () => { + testCardSvg(backFace, /#back$/i); + }); + + it('should default back to black color', () => { + expect(backFace).toHaveAttribute('fill', 'black'); + }); + }); + + describe('on rendering', () => { + let frontFace: HTMLElement; + let backFace: HTMLElement; + beforeEach(() => { + const { getByTestId } = render(); + frontFace = getByTestId('PlayingCard_front_use'); + backFace = getByTestId('PlayingCard_back_use'); + }); + + it('should render the correct card', () => { + testCardSvg(frontFace, /#spade_4$/i); + }); + + it('should always show back as back', () => { + testCardSvg(backFace, /#back$/i); + }); + + it('should render back as backColor property', () => { + expect(backFace).toHaveAttribute('fill', 'red'); + }); + }); +}); diff --git a/src/components/atoms/PlayingCard/PlayingCard.tsx b/src/components/atoms/PlayingCard/PlayingCard.tsx new file mode 100644 index 0000000..6224a79 --- /dev/null +++ b/src/components/atoms/PlayingCard/PlayingCard.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { createUseStyles } from 'react-jss'; +import svgCards from '../../../assets/svg-cards-optimized.svg'; +import { BaseCard } from '../BaseCard/BaseCard'; +import { PlayingCardType } from '../../../models/PlayingCardType'; + +/** + * Properties for PlayingCard + */ +export interface PlayingCardProps { + /** Card to be rendered */ + card?: PlayingCardType; + /** Color to be applied to back face */ + backColor?: string; +} + +const useStyles = createUseStyles({ + svgStyle: { + width: '100%', + }, +}); + +export const PlayingCard: React.FC = ({ card = 'joker_black', backColor = 'black' }) => { + const classes = useStyles(); + + const generateSvg = (isFront: boolean) => { + const testId = `PlayingCard_${isFront ? 'front' : 'back'}`; + return ( + + + + ); + }; + + return ; +}; diff --git a/src/components/pages/HomePage/HomePage.test.tsx b/src/components/pages/HomePage/HomePage.test.tsx index 44f6fc0..e81480c 100644 --- a/src/components/pages/HomePage/HomePage.test.tsx +++ b/src/components/pages/HomePage/HomePage.test.tsx @@ -5,7 +5,7 @@ import HomePage from './HomePage'; describe('HomePage', () => { it('should render home page', () => { const { getByText } = render(); - const divElement = getByText(/I am on homepage/i); + const divElement = getByText(/Card UI/i); expect(divElement).toBeInTheDocument(); }); }); diff --git a/src/components/pages/HomePage/HomePage.tsx b/src/components/pages/HomePage/HomePage.tsx index 878408d..70aded8 100644 --- a/src/components/pages/HomePage/HomePage.tsx +++ b/src/components/pages/HomePage/HomePage.tsx @@ -1,22 +1,88 @@ import React from 'react'; import { createUseStyles } from 'react-jss'; -import { BaseCard } from '../../atoms/BaseCard/BaseCard'; +import { PlayingCard } from '../../atoms/PlayingCard/PlayingCard'; +import { PlayingCardType } from '../../../models/PlayingCardType'; const useStyles = createUseStyles({ homePage: { background: '#cccccc', height: '100%', color: 'white', + overflow: 'auto', + display: 'grid', + gridTemplateColumns: 'repeat(5, 1fr)', }, }); const HomePage: React.FC = () => { const classes = useStyles(); + const allCards: PlayingCardType[] = [ + 'club_1', + 'club_2', + 'club_3', + 'club_4', + 'club_5', + 'club_6', + 'club_7', + 'club_8', + 'club_9', + 'club_10', + 'club_jack', + 'club_queen', + 'club_king', + 'diamond_1', + 'diamond_2', + 'diamond_3', + 'diamond_4', + 'diamond_5', + 'diamond_6', + 'diamond_7', + 'diamond_8', + 'diamond_9', + 'diamond_10', + 'diamond_jack', + 'diamond_queen', + 'diamond_king', + 'heart_1', + 'heart_2', + 'heart_3', + 'heart_4', + 'heart_5', + 'heart_6', + 'heart_7', + 'heart_8', + 'heart_9', + 'heart_10', + 'heart_jack', + 'heart_queen', + 'heart_king', + 'spade_1', + 'spade_2', + 'spade_3', + 'spade_4', + 'spade_5', + 'spade_6', + 'spade_7', + 'spade_8', + 'spade_9', + 'spade_10', + 'spade_jack', + 'spade_queen', + 'spade_king', + 'joker_black', + 'joker_red', + ]; + const backColors = ['black', 'red', 'blue', '#048b9a']; + return (
- I am on homepage - MY FRONT
} backFace={
MY BACK
} /> +

Card UI

+ {allCards.map((card, index) => ( +
+ +
+ ))} ); }; diff --git a/src/models/PlayingCardType.tsx b/src/models/PlayingCardType.tsx new file mode 100644 index 0000000..3a701ba --- /dev/null +++ b/src/models/PlayingCardType.tsx @@ -0,0 +1,56 @@ +/** Possible playing cards */ +export type PlayingCardType = + | 'club_1' + | 'club_2' + | 'club_3' + | 'club_4' + | 'club_5' + | 'club_6' + | 'club_7' + | 'club_8' + | 'club_9' + | 'club_10' + | 'club_jack' + | 'club_queen' + | 'club_king' + | 'diamond_1' + | 'diamond_2' + | 'diamond_3' + | 'diamond_4' + | 'diamond_5' + | 'diamond_6' + | 'diamond_7' + | 'diamond_8' + | 'diamond_9' + | 'diamond_10' + | 'diamond_jack' + | 'diamond_queen' + | 'diamond_king' + | 'heart_1' + | 'heart_2' + | 'heart_3' + | 'heart_4' + | 'heart_5' + | 'heart_6' + | 'heart_7' + | 'heart_8' + | 'heart_9' + | 'heart_10' + | 'heart_jack' + | 'heart_queen' + | 'heart_king' + | 'spade_1' + | 'spade_2' + | 'spade_3' + | 'spade_4' + | 'spade_5' + | 'spade_6' + | 'spade_7' + | 'spade_8' + | 'spade_9' + | 'spade_10' + | 'spade_jack' + | 'spade_queen' + | 'spade_king' + | 'joker_black' + | 'joker_red';