1. Pengantar
Komponen Material (MDC) membantu developer menerapkan Desain Material. Dibuat oleh tim engineer dan desainer UX di Google, MDC memiliki banyak komponen UI yang indah dan fungsional serta tersedia untuk Android, iOS, web, dan Flutter.material.io/develop |
MDC Web dirancang untuk berintegrasi ke dalam framework frontend apa pun sekaligus mempertahankan prinsip Desain Material. Codelab berikut akan memandu Anda dalam mem-build Komponen React, yang menggunakan MDC Web sebagai fondasinya. Prinsip yang dipelajari dalam codelab ini dapat diterapkan ke framework JavaScript apa pun.
Cara MDC Web dibuat
Lapisan JavaScript MDC Web terdiri dari tiga class per komponen: Component, Foundation, dan Adapter. Pola ini memberi MDC Web fleksibilitas untuk berintegrasi dengan framework frontend.
Dasar berisi logika bisnis yang mengimplementasikan Desain Material. Foundation tidak mereferensikan elemen HTML apa pun. Hal ini memungkinkan kita memisahkan logika interaksi HTML ke dalam Adaptor. Dasar memiliki Adaptor.
Adapter adalah antarmuka. Antarmuka Adaptor dirujuk oleh Foundation untuk menerapkan logika bisnis Desain Material. Anda dapat menerapkan Adapter di berbagai framework seperti Angular atau React. Implementasi Adaptor berinteraksi dengan struktur DOM.
Komponen memiliki Dasar, dan perannya adalah untuk
- Terapkan Adaptor, menggunakan JavaScript non-framework, dan
- Menyediakan metode publik yang melakukan proxy ke metode di Foundation.
Yang disediakan MDC Web
Setiap paket di MDC Web dilengkapi dengan Komponen, Dasar, dan Adaptor. Untuk membuat instance Komponen, Anda harus meneruskan elemen root ke metode konstruktor Komponen. Komponen mengimplementasikan Adaptor, yang berinteraksi dengan elemen DOM dan HTML. Komponen kemudian membuat instance Foundation, yang memanggil metode Adapter.
Untuk mengintegrasikan MDC Web ke dalam framework, Anda perlu membuat Komponen sendiri dalam bahasa/sintaksis framework tersebut. Komponen framework mengimplementasikan Adaptor MDC Web dan menggunakan Dasar MDC Web.
Yang akan Anda bangun
Codelab ini menunjukkan cara mem-build Adaptor kustom untuk menggunakan logika Dasar guna mendapatkan Komponen React Desain Material. Panduan ini mencakup topik lanjutan yang terdapat dalam artikel Mengintegrasikan ke Framework. React digunakan dalam codelab ini sebagai contoh framework, tetapi pendekatan ini dapat diterapkan ke framework lainnya.
Dalam codelab ini, Anda akan mem-build Panel Aplikasi Atas dan membuat ulang halaman demo panel aplikasi atas. Tata letak halaman demo sudah disiapkan sehingga Anda dapat mulai mengerjakan Panel Aplikasi Atas. Panel Aplikasi Atas akan mencakup:
- Ikon navigasi
- Item tindakan
- Ada 4 varian yang tersedia: varian pendek, selalu diciutkan, tetap, dan jelas
Yang Anda butuhkan:
- Node.js versi terbaru (yang dipaketkan dengan npm, pengelola paket JavaScript)
- Kode contoh (akan didownload di langkah berikutnya)
- Pengetahuan dasar tentang HTML, CSS, JavaScript, dan React
Bagaimana Anda menilai tingkat pengalaman Anda dengan pengembangan web?
2. Menyiapkan lingkungan pengembangan
Mendownload aplikasi codelab awal
Aplikasi awal terletak di direktori material-components-web-codelabs-master/mdc-112/starter
.
...atau meng-clone codelab dari GitHub
Untuk meng-clone codelab ini dari GitHub, jalankan perintah berikut:
git clone https://github.com/material-components/material-components-web-codelabs
cd material-components-web-codelabs/mdc-112/starter
Menginstal dependensi project
Dari direktori awal material-components-web-codelabs/mdc-112/starter
, jalankan:
npm install
Anda akan melihat banyak aktivitas dan pada akhirnya, terminal akan menampilkan penginstalan yang berhasil:
Menjalankan aplikasi awal
Di direktori yang sama, jalankan:
npm start
webpack-dev-server
akan dimulai. Arahkan browser ke http://localhost:8080/ untuk melihat halaman.
Berhasil! Kode awal untuk halaman Demo React Panel Aplikasi Teratas harus berjalan di browser Anda. Anda akan melihat dinding teks lorem ipsum, kotak Kontrol (kanan bawah), dan Panel Aplikasi Atas yang belum selesai:
Lihat kode dan project
Jika Anda membuka editor kode, direktori project akan terlihat seperti ini:
Buka file App.js
dan lihat metode render
yang menyertakan Komponen <TopAppBar>
:
App.js
render() {
const {isFixed, isShort, isRtl, isProminent, isAlwaysCollapsed, shouldReinit} = this.state;
return (
<section
dir={isRtl ? 'rtl' : 'ltr'}
className='mdc-typography'>
{
shouldReinit ? null :
<TopAppBar
navIcon={this.renderNavIcon()}
short={isShort}
prominent={isProminent}
fixed={isFixed}
alwaysCollapsed={isAlwaysCollapsed}
title='Mountain View, CA'
actionItems={this.actionItems}
/>
}
<div className={classnames('mdc-top-app-bar--fixed-adjust', {
'mdc-top-app-bar--short-fixed-adjust': isShort || isAlwaysCollapsed,
'mdc-top-app-bar--prominent-fixed-adjust': isProminent,
})}>
{this.renderDemoParagraphs()}
</div>
{this.renderControls()}
</section>
);
}
Ini adalah titik entri untuk TopAppBar
dalam aplikasi.
Buka file TopAppBar.js
yang merupakan class Component
React murni dengan metode render
:
TopAppBar.js
import React from 'react';
export default class TopAppBar extends React.Component {
render() {
return (
<header>
TOP APP BAR
</header>
);
}
}
3. Komposisi komponen
Di React, metode render
menghasilkan output HTML Komponen. Komponen Panel Aplikasi Atas akan merender tag <header />
, dan akan terdiri dari 2 bagian utama:
- Ikon navigasi dan bagian judul
- Bagian ikon tindakan
Jika Anda memiliki pertanyaan tentang elemen yang membentuk Panel Aplikasi Atas, buka dokumentasi di GitHub.
Ubah metode render()
di TopAppBar.js
agar terlihat seperti ini:
render() {
const {
title,
navIcon,
} = this.props;
return (
<header
className={this.classes}
style={this.getMergedStyles()}
ref={this.topAppBarElement}
>
<div className='mdc-top-app-bar__row'>
<section className='mdc-top-app-bar__section mdc-top-app-bar__section--align-start'>
{navIcon ? navIcon : null}
<span className="mdc-top-app-bar__title">
{title}
</span>
</section>
{this.renderActionItems()}
</div>
</header>
);
}
Ada dua elemen bagian dalam HTML ini. Yang pertama berisi ikon dan judul navigasi. Baris kedua berisi ikon tindakan.
Selanjutnya, tambahkan metode renderActionItems
:
renderActionItems() {
const {actionItems} = this.props;
if (!actionItems) {
return;
}
return (
<section className='mdc-top-app-bar__section mdc-top-app-bar__section--align-end' role='toolbar'>
{/* need to clone element to set key */}
{actionItems.map((item, key) => React.cloneElement(item, {key}))}
</section>
);
}
Developer akan mengimpor TopAppBar
ke aplikasi React dan meneruskan ikon tindakan ke elemen TopAppBar
. Anda dapat melihat contoh kode yang melakukan inisialisasi TopAppBar
di App.js
.
Metode getMergedStyles
tidak ada, yang digunakan dalam metode render
. Tambahkan metode JavaScript berikut ke class TopAppBar
:
getMergedStyles = () => {
const {style} = this.props;
const {style: internalStyle} = this.state;
return Object.assign({}, internalStyle, style);
}
this.classes
juga tidak ada dalam metode render
, tetapi akan dibahas di bagian selanjutnya. Selain metode pengambil yang hilang, this.classes
, masih ada bagian TopAppBar
yang perlu Anda terapkan sebelum Panel Aplikasi Atas dapat dirender dengan benar.
Bagian Komponen React yang masih belum ada di Panel Aplikasi Atas adalah:
- Dasar yang diinisialisasi
- Metode adaptor untuk diteruskan ke fondasi
- Markup JSX
- Pengelolaan varian (tetap, singkat, selalu diciutkan, jelas)
Pendekatan
- Implementasikan metode Adaptor.
- Lakukan inisialisasi Foundation di
componentDidMount
. - Panggil metode Foundation.destroy di
componentWillUnmount
. - Buat pengelolaan varian melalui metode pengambil yang menggabungkan nama class yang sesuai.
4. Mengimplementasikan metode Adaptor
Komponen TopAppBar
JS non-framework menerapkan metode Adaptor berikut (tercantum secara mendetail di sini):
hasClass()
addClass()
removeClass()
registerNavigationIconInteractionHandler()
deregisterNavigationIconInteractionHandler()
notifyNavigationIconClicked()
setStyle()
getTopAppBarHeight()
registerScrollHandler()
deregisterScrollHandler()
registerResizeHandler()
deregisterResizeHandler()
getViewportScrollY()
getTotalActionItems()
Karena React memiliki peristiwa sintetis serta berbagai praktik dan pola coding terbaik, metode Adapter perlu diterapkan kembali.
Metode Pengambil Adaptor
Di file TopAppBar.js
, tambahkan metode JavaScript berikut ke TopAppBar
:
get adapter() {
const {actionItems} = this.props;
return {
hasClass: (className) => this.classes.split(' ').includes(className),
addClass: (className) => this.setState({classList: this.state.classList.add(className)}),
removeClass: (className) => {
const {classList} = this.state;
classList.delete(className);
this.setState({classList});
},
setStyle: this.setStyle,
getTopAppBarHeight: () => this.topAppBarElement.current.clientHeight,
registerScrollHandler: (handler) => window.addEventListener('scroll', handler),
deregisterScrollHandler: (handler) => window.removeEventListener('scroll', handler),
registerResizeHandler: (handler) => window.addEventListener('resize', handler),
deregisterResizeHandler: (handler) => window.removeEventListener('resize', handler),
getViewportScrollY: () => window.pageYOffset,
getTotalActionItems: () => actionItems && actionItems.length,
};
}
API adaptor untuk pendaftaran peristiwa scroll dan ubah ukuran diterapkan secara identik dengan versi JS non-framework, karena React tidak memiliki peristiwa sintetis untuk men-scroll atau mengubah ukuran dan mematuhi sistem peristiwa DOM native. getViewPortScrollY
juga perlu ditunda ke DOM native karena merupakan fungsi pada objek window
, yang tidak ada di API React. Implementasi adaptor akan berbeda untuk setiap framework.
Anda mungkin melihat this.setStyle
tidak ada, yang dipanggil oleh metode get adapter
. Dalam file TopAppBar.js
, tambahkan metode JavaScript yang tidak ada ke class TopAppBar
:
setStyle = (varName, value) => {
const updatedStyle = Object.assign({}, this.state.style);
updatedStyle[varName] = value;
this.setState({style: updatedStyle});
}
Anda baru saja menerapkan Adaptor. Perhatikan bahwa Anda mungkin melihat error di konsol pada tahap ini karena implementasi penuh belum selesai. Bagian berikutnya akan memandu Anda cara menambahkan dan menghapus class CSS.
5. Mengimplementasikan metode Komponen
Mengelola Varian dan Kelas
React tidak memiliki API untuk mengelola class. Untuk meniru metode class tambahkan/hapus pada JavaScript native, tambahkan variabel status classList
. Ada tiga bagian kode di TopAppBar
yang berinteraksi dengan class CSS:
- Komponen
<TopAppBar />
melalui properticlassName
. - Metode Adaptor melalui
addClass
atauremoveClass
. - Di-hardcode dalam Komponen React
<TopAppBar />
.
Pertama, tambahkan impor berikut di bagian atas TopAppBar.js
, di bawah impor yang ada:
import classnames from 'classnames';
Kemudian, tambahkan kode berikut di dalam deklarasi class Komponen TopAppBar
:
export default class TopAppBar extends React.Component {
constructor(props) {
super(props);
this.topAppBarElement = React.createRef();
}
state = {
classList: new Set(),
style: {},
};
get classes() {
const {classList} = this.state;
const {
alwaysCollapsed,
className,
short,
fixed,
prominent,
} = this.props;
return classnames('mdc-top-app-bar', Array.from(classList), className, {
'mdc-top-app-bar--fixed': fixed,
'mdc-top-app-bar--short': short,
'mdc-top-app-bar--short-collapsed': alwaysCollapsed,
'mdc-top-app-bar--prominent': prominent,
});
}
...
}
Jika Anda membuka http://localhost:8080, kotak centang Kontrol kini akan mengaktifkan/menonaktifkan nama class dari DOM.
Kode ini membuat TopAppBar
dapat digunakan oleh banyak developer. Developer dapat berinteraksi dengan TopAppBar
API, tanpa perlu mengkhawatirkan detail implementasi class CSS.
Anda kini telah berhasil mengimplementasikan Adaptor. Bagian berikutnya akan memandu Anda membuat instance Foundation.
Memasang dan Melepas Komponen
Pembuatan instance Foundation terjadi dalam metode componentDidMount
.
Pertama, impor fondasi MDC Top App Bar dengan menambahkan impor berikut setelah impor yang ada di TopAppBar.js
:
import {MDCTopAppBarFoundation, MDCFixedTopAppBarFoundation, MDCShortTopAppBarFoundation} from '@material/top-app-bar';
Selanjutnya, tambahkan kode JavaScript berikut ke class TopAppBar
:
export default class TopAppBar extends React.Component {
...
foundation_ = null;
componentDidMount() {
this.initializeFoundation();
}
componentWillUnmount() {
this.foundation_.destroy();
}
initializeFoundation = () => {
if (this.props.short) {
this.foundation_ = new MDCShortTopAppBarFoundation(this.adapter);
} else if (this.props.fixed) {
this.foundation_ = new MDCFixedTopAppBarFoundation(this.adapter);
} else {
this.foundation_ = new MDCTopAppBarFoundation(this.adapter);
}
this.foundation_.init();
}
...
}
Salah satu praktik coding React yang baik adalah menentukan propTypes dan defaultProps. Tambahkan impor berikut setelah impor yang ada di TopAppBar.js:
import PropTypes from 'prop-types';
Kemudian, tambahkan kode berikut ke bagian bawah TopAppBar.js
(setelah class Komponen):
import PropTypes from 'prop-types';
TopAppBar.propTypes = {
alwaysCollapsed: PropTypes.bool,
short: PropTypes.bool,
fixed: PropTypes.bool,
prominent: PropTypes.bool,
title: PropTypes.string,
actionItems: PropTypes.arrayOf(PropTypes.element),
navIcon: PropTypes.element,
};
TopAppBar.defaultProps = {
alwaysCollapsed: false,
short: false,
fixed: false,
prominent: false,
title: '',
actionItems: null,
navIcon: null,
};
Anda kini telah berhasil menerapkan Komponen React Panel Aplikasi Atas. Jika membuka http://localhost:8080, Anda dapat bermain dengan halaman demo. Halaman demo akan berfungsi sama seperti halaman demo MDC Web. Halaman demo akan terlihat seperti ini:
6. Rangkuman
Dalam tutorial ini, kita telah membahas cara menggabungkan Fondasi Web MDC untuk digunakan dalam aplikasi React. Ada beberapa library di GitHub dan npm yang menggabungkan Komponen Web MDC seperti yang dijelaskan dalam Mengintegrasikan ke Framework. Sebaiknya gunakan daftar yang ada di sini. Daftar ini juga mencakup framework lain selain React seperti Angular dan Vue.
Tutorial ini menyoroti keputusan kami untuk membagi kode Web MDC menjadi 3 bagian, yaitu Dasar, Adaptor, dan Komponen. Arsitektur ini memungkinkan komponen berbagi kode umum saat bekerja dengan semua framework. Terima kasih telah mencoba Material Components React dan lihat library baru kami, MDC React. Kami harap Anda menikmati codelab ini.