Quote components
Component ini digunakan untuk menampilkan quoteText
, terdapat tiga kondisi tampilan, yaitu:
- ketika
quoteText
bernilainull
akan muncul pernyataan bahwa quote kosong, tampilan loading akan dihilangkan. - ketika
loading
bernilai true, maka akan muncul tampilan loading, tampilan quote akan dihilangkan. - ketika
quoteText
bernilai teks dari API, akan menampilkan isi dari teks, tampilan loading akan dihilangkan.
Folder structure
Buatlah file dan folder seperti berikut:
src/
components/
Quote/
__test__/
index.test.ts
constants.ts
index.tsx
styles.css
Keterangan:
Quote/__test__/index.test.ts
file unit test.Quote/constants.ts
adalah file yang berisikan definisi konstanta.Quote/index.tsx
adalah file component jsx.Quote/styles.css
adalah file css yang berisikan definisi style yang akan dipakai dalam component.
Constants
Untuk memudahkan, teks untuk beberapa kondisi diatas akan didefinisikan sebagai konstanta di file constants.ts
.
const constants = {
messages: {
IS_EMPTY: 'Received empty quote, please generate new one',
IS_LOADING: 'Loading quotes . . .',
},
};
export default constants;
Styles
Menambahkan Font dari Google Fonts
Untuk menambahkan font dari google fonts, silahkan buka laman web Google Fonts, kemudian pilihlah font yang disukai (saat ini saya memilih Raleway).
Pilih Font Weights yang diinginkan, kemudian copy code yang ada pada use on web.
Saya memilih font weights 400, 500, dan 700 beserta dengan varian italics. Kira-kira code yang digenerate akan tampil seperti dibawah ini:
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap"
rel="stylesheet"
/>
Kemudian buka file index.html di public/index.html
, tempelkan pada bagian <head>
.
tampilan file index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#f3f3f3" />
<meta
name="description"
content="Random quote generator from famous people"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,400;0,700;1,400;1,700&display=swap"
rel="stylesheet"
/>
<title>Random Quote Generator</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
Menulis file css
Kemudian definisikan styles untuk component di file styles.css
:
.quote-content {
border-left: solid 4px #f7df94;
padding-left: 24px;
font-family: sans-serif;
}
.quote-empty {
font-family: monospace;
}
Test
Untuk memastikan komponen akan tampil dengan sesuai kondisi, maka mari buat test file di __test__/index.test.ts
yang berisikan code sebagai berikut:
import { render, screen } from '@testing-library/react';
import constants from '../constants';
import Quote from '..';
describe('Quote component test cases', () => {
it(`Should render empty quote message when quote is null or undefined`, () => {
render(<Quote />);
const content = screen.queryByTestId('content');
expect(content).toBeInTheDocument();
expect(content).toHaveClass('quote-empty');
expect(content).toHaveTextContent(constants.messages.IS_EMPTY);
expect(screen.queryByTestId('loading-indicator')).toBeNull();
});
it(`Should render loading messages when loading quote`, () => {
render(<Quote loading />);
expect(screen.queryByTestId('content')).toBeNull();
expect(screen.getByTestId('loading-indicator')).toHaveTextContent(
constants.messages.IS_LOADING
);
});
it(`Should render text from props`, () => {
const quoteText = 'lorem ipsum dolor sit amet';
render(<Quote text={quoteText} />);
const content = screen.queryByTestId('content');
expect(content).toHaveTextContent(quoteText);
expect(content).toHaveClass('quote-content');
expect(screen.queryByTestId('loading-indicator')).toBeNull();
});
});
Component
Quote component memiliki props:
text
digunakan untuk passingquoteText
ke dalam component dalam bentuk string.loading
digunakan untuk flagloading
saat fetching data dengan tipe boolean.
Sehingga dapat didefinisikan:
type propTypes = {
text?: string;
loading?: boolean;
};
Jangan lupa import styles.css
agar styles dapat digunakan pada component Quote
.
import './styles.css';
type propTypes = {
text?: string;
loading?: boolean;
};
Kemudian definisikan Function Component dengan nama Quote
seperti berikut:
import './styles.css';
type propTypes = {
text?: string;
loading?: boolean;
};
const Quote: React.FC<propTypes> = ({ text = null, loading = false}) => ();
Untuk menyelesaikan test case it Should render loading messages when loading quote. Berikan pemeriksaan kondisi jika props loading
adalah true
, maka tampilkan teks IS_LOADING
dari file constants.ts
.
import './constants.ts';
import './styles.css';
type propTypes = {
text?: string;
loading?: boolean;
};
const Quote: React.FC<propTypes> = ({ text = null, loading = false }) => {
if (loading) {
return (
<p data-testid="loading-indicator">{constants.messages.IS_LOADING}</p>
);
}
};
Kemudian untuk menampilkan quote, buatlah <blockquote>
seperti ini:
import constants from './constants';
import './styles.css';
type propTypes = {
text?: string;
loading?: boolean;
};
const Quote: React.FC<propTypes> = ({ text = null, loading = false }) => {
if (loading) {
return (
<p data-testid="loading-indicator">{constants.messages.IS_LOADING}</p>
);
}
return (
<blockquote className="quote-content" data-testid="content">
"{text}"
</blockquote>
);
};
export default Quote;
Jangan lupa, ketika quote bernilai null
atau empty string (''
) harus menampilkan message dan styles yang sesuai. Sehingga code componentnya seperti ini:
import constants from './constants';
import './styles.css';
type propTypes = {
text?: string;
loading?: boolean;
};
const Quote: React.FC<propTypes> = ({ text = null, loading = false }) => {
if (loading) {
return (
<p data-testid="loading-indicator">{constants.messages.IS_LOADING}</p>
);
}
const contentClassName = !text ? 'quote-empty' : 'quote-content';
const contentText = text || constants.messages.IS_EMPTY;
return (
<blockquote className={contentClassName} data-testid="content">
"{contentText}"
</blockquote>
);
};
export default Quote;
jika dirasa selesai, maka ketika running test, akan menampilkan hasil seperti ini:
PASS src/components/Quote/__test__/index.test.tsx
Quote component test cases
✓ Should render empty quote message when quote is null or undefined (52 ms)
✓ Should render Loading quotes . . . when loading quote (6 ms)
✓ Should render text from props (5 ms)
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 3.084 s
Ran all test suites related to changed files.
Untuk Pembahasan Quote components selesai sampai sini, jika ada pertanyaan bisa ditanyakan di twitter @sadevva_
Keep in touch for the updates ya! Cheers 🥂,