در قسمت قبل toolbar را کدنویسی کردیم اما هنوز منوی کشویی در ری اکت را ایجاد نکرده ایم. منوی کشویی معادل responsive نوار toolbar برای گوشی های موبایل است. برای شروع کار در پوشه ی Navigation یک پوشه ی جدید به نام SideDrawer بسازید که حاوی فایلی به نام SideDrawer.js باشد. در ابتدا محتوای SideDawer.js مانند تمام کامپوننت های کاربردی دیگرمان و به شکل زیر است:
import React from 'react'; import Logo from '../../Logo/Logo'; import NavigationItems from '../NavigationItems/NavigationItems'; const sideDrawer = (props) => { // .... return ( ); } export default sideDrawer;
ما می خواهیم در این تابع کلاس های CSS را به صورت پویا تغییر بدهیم تا منوی کشویی وارد صفحه شود یا با بسته شدن آن از صفحه خارج شود؛ فعلا به جای این کدها از یک کامنت با چند نقطه استفاده کرده ایم اما بعدا کدهای آن را تکمیل می کنیم. همچنین از آنجایی که می خواهیم از آیتم های navigation استفاده کنیم، این کامپوننت را import کرده ایم و نیازی به دوباره نویسی کدها نیست.
برای تکمیل کدها می نویسیم:
const sideDrawer = (props) => { // .... return ( <div> <Logo /> <nav> <NavigationItems /> </nav> </div> ); }
یعنی لوگو و آیتم های navigation باید درون این کامپوننت باشند، اما کجا باشند؟ درست است باید آن ها را استایل دهی کنیم بنابراین در کنار فایل SideDrawer.js یک فایل به نام SideDrawer.module.css ایجاد کنید و کلاس ها و استایل های زیر را در آن قرار دهید:
.SideDrawer { position: fixed; width: 280px; max-width: 70%; height: 100%; left: 0; top: 0; z-index: 200; background-color: white; padding: 32px 16px; box-sizing: border-box; transition: transform 0.3s ease-out; } @media (min-width: 500px) { .SideDrawer { display: none; } } .Open { transform: translateX(0); } .Close { transform: translateX(-100%); }
نکات مهم:
حالا به فایل SideDrawer.js برگردید تا از این کلاس ها استفاده کنیم. ابتدا باید کلاس ها را import کنیم:
import classes from './SideDrawer.module.css';
سپس آن را به Div ریشه ای اضافه می کنیم:
return ( <div className={classes.SideDrawer}> <Logo /> <nav> <NavigationItems /> </nav> </div> );
در این مرحله باید از خودمان بپرسیم که SideDrawer را کجا قرار دهیم؟ درون App.js یا درون Toolbar یا جایی دیگر؟ اگر یادتان باشد Toolbar را درون Layout.js قرار دادیم و گفتیم که دلیل آن حضور Toolbar در تمامی صفحات سایت است. با همین منطق می توانیم SideDrawer را نیز در Layout.js اضافه کنیم. محتویات فایل Layout.js پس از اضافه کردن SideDrawer:
import React from 'react'; import Aux from '../../hoc/Auxx'; import classes from './Layout.module.css'; import Toolbar from '../Navigation/Toolbar/Toolbar'; import SideDrawer from '../Navigation/SideDrawer/SideDrawer'; const layout = (props) => ( <Aux> <Toolbar /> <SideDrawer /> <main className={classes.Content}> {props.children} </main> </Aux> ); export default layout;
اگر فایل ها را ذخیره کنیم و به مرورگر برویم چیزی مشاهده نمی شود. چرا؟ به دلیل اینکه گفته بودیم در دستگاه هایی با عرض صفحه ی بیشتر از 500 پیکسل SideDrawer نباید نمایش داده شود اما اگر سایز پنجره ی کروم را کوچک کنید و یا دکمه ی پیش نمایش mobile را از dev tools بزنید (قسمت مشخص شده در تصویر زیر)، SideDrawer را مشاهده خواهید کرد:
همانطور که می بینید اصلا ظاهر خوبی ندارد؛ لوگو بسیار بزرگ است و دکمه های navigation نیز پراکنده شده اند. البته جای تعجب هم ندارد چرا که ما هنوز آن ها را برای صفحات کوچک تنظیم نکرده ایم.
اگر یادتان باشد در فایل Logo.module.css مقدار height برای لوگو را 80 درصد قرار داده ایم:
.Logo { background-color: white; padding: 8px; height: 80%; box-sizing: border-box; border-radius: 5px; }
به همین دلیل است که لوگو آنقدر بزرگ نمایش داده می شود. برای حل این مشکل راه های مختلفی وجود دارد؛ مثلا می توانیم با استفاده از media query ها یک طراحی Responsive را پیاده سازی کنیم اما اگر چنین کاری را انجام دهیم، استفاده ی دوباره از لوگو سخت تر می شود. هدف ما این بود که بتوانیم بدون کدنویسی اضافه از کامپوننت ها استفاده کنیم اما با طراحی Responsive باید هر بار برای لوگو media query بنویسیم. بنابراین در فایل Logo.module.css مقدار height را روی 100 درصد قرار بدهید:
.Logo { background-color: white; padding: 8px; height: 100%; box-sizing: border-box; border-radius: 5px; }
حالا اندازه ی لوگو را درون Toolbar و SideDrawer تغییر می دهیم. ما می توانیم Toolbar.js را باز کرده و مقدار height را به صورت یک prop به فایل خودمان پاس بدهیم:
const toolbar = (props) => ( <header className={classes.Toolbar}> <div>MENU</div> <Logo height="80%" /> <nav> <NavigationItems /> </nav> </header> );
سپس به Logo.js می رویم و این prop را دریافت کرده و با استفاده از استایل های inline مقدار را تغییر می دهیم:
const logo = (props) => ( <div className={classes.Logo} style={{ height: props.height }}> <img src={burgerLogo} alt="MyBurger" /> </div> );
حالا وارد SideDrawer.js شده و همین کار را انجام دهید:
return ( <div className={classes.SideDrawer}> <Logo height="11%" /> <nav> <NavigationItems /> </nav> </div> );
اگر فایل ها را ذخیره کنید و به مرورگر بروید متوجه می شوید که مشکل ما از نظر اندازه ی لوگو حل شده است:
البته یک روش دیگر هم وجود دارد که می خواهم آن را به شما نشان بدهم. در روش دوم حل این مشکل به جای پاس دادن اندازه ی height این کار را می کنیم:
return ( <div className={classes.SideDrawer}> <div> <Logo /> </div> <nav> <NavigationItems /> </nav> </div> );
یعنی لوگو را درون یک div قرار می دهیم. همین کار را برای Toolbar نیز انجام می دهیم:
const toolbar = (props) => ( <header className={classes.Toolbar}> <div>MENU</div> <div> <Logo /> </div> <nav> <NavigationItems /> </nav> </header> );
سپس به فایل Toolbar.module.css می رویم و کلاسی به نام Logo را به آن اضافه می کنیم:
.Logo { height: 80%; }
همین کار را با SideDrawer.module.css انجام می دهیم:
.Logo { height: 11%; }
حالا وارد فایل SideDrawer.js شده و این کلاس را به div مورد نظر بدهید:
return ( <div className={classes.SideDrawer}> <div className={classes.Logo}> <Logo /> </div> <nav> <NavigationItems /> </nav> </div> );
اگر فایل ها را ذخیره کرده و به مرورگر بروید با همان نتیجه ی قبلی روبرو می شوید:
نکته: شاید فکر کنید که کلاس های Logo با هم تداخل پیدا می کنند اما ما از CSS Module ها استفاده می کنیم؛ یعنی در هنگام ایجاد برنامه نام این کلاس ها تغییر پیدا می کند (مثلا می شود Logo_Logo__3Ndfk) بنابراین هیچ تداخلی پیش نمی آید.
هر دو روش، روش های خوبی هستند و استفاده از آن ها به سلیقه ی شما بستگی دارد. در قسمت بعد آیتم های navigation را سر جایشان قرار خواهیم داد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.