DAY 24 Full Screen Modal

接着我们要做的是打开 menu hamberger 後的 full screen modal,里面包含了所有 VOGUE links

Modal

首先我们再新增一个 modal 的 partial,抽离出来管理这个物件的 style,并且在 Header.js 中加入相关的 div 以及 class

// main.sass

@import "variable"
@import "basic"
@import "typography"
@import "header"
@import "dropdown"
@import "modal"

打开的方式跟之前的 dropdown 一样,只在於这次有开关的按钮区别,所以会有参数带入控制开关

// Header.js

export default function Header() {
	// ...
  const [modalOpen, setModalOpen] = React.useState(false);
  const handleModalClick = (status) => {
    setModalOpen(status);
  };

  return (
    <nav className="header">
      // ...
      <div className={modalOpen === true ? "modal show" : "modal"}>
        <div className="modal-dialog">
          <div className="modal-content">
            <div className="modal-header">
              <div className="modal-title">VOGUE</div>
              <label
                className="close-button"
                onClick={() => handleModalClick(false)}
              >
              </label>
            </div>
            <div className="modal-body">
              <p>Modal body text goes here.</p>
            </div>
          </div>
        </div>
      </div>
    </nav>
  );
}

在 sass 的部分加上 modal 以及 show 来控制显示的开关,以及移动到 modal-button 上的 hover style

// _modal.sass

.modal
    position: fixed
    top: 0
    left: 0
    display: none
    width: 100%
    height: 100%
    background-color: $primary-color
    color: $primary-background-color

.modal-button:hover
    @extend %hover-style

.show
    display: block

接下来利用 fontawesome 中的 close 来当作关闭按钮

// Header.js

<div className="modal-header">
  <div className="modal-title">VOGUE</div>
  <label
    className="close-button"
    onClick={() => handleModalClick(false)}
  >
    <FontAwesomeIcon icon={faTimes} size="3x" />
  </label>
</div>

sass 的部分针对 button 调整位置

// _modal.sass

.modal-header
  .close-button
      margin: 8px
      padding: 16px
      position: fixed
      top: 0
      right: 0
      cursor: pointer

接下来看看画面

Untitled

Untitled

可以看到 logo、menu 的位置是有对齐的!

接着要完成的是 Modal 中的 Content 部分,里面包含了去各页的连结 link

小提醒!可以先把 const [modalOpen, setModalOpen] = React.useState(true); 设定为 true,这样比较方便检视 modal 的效果,不然每次重新 render 还要打开来太麻烦了XD

因为 content 中有三个栏位,所以我们要再另外设置一个 modal column 来分装这三个栏位

.modal-column
    vertical-align: top
    border-top: 1.5px solid $primary-background-color
    width: 29vw
    display: inline-block
    margin: 16px

大概调整一下跟官网的配置一样,这边要注意的是:

  1. vertical-align: top - 让 column 们是靠上对齐的
  2. width: 29vw - vw 是指当前画面的宽度,而29就是画面宽度的29%,针对三栏简易的用这样去分配宽度
  3. display: inline-block - 让 column 们可以并肩并行!

再来针对 column 中的内容个别去设定 style

.modal-column
    // ...
    a
        padding: 16px 0
        display: block
        color: $primary-background-color
        &:hover
            color: $secondary-color

    hr
        border: none
        height: 1px
        color: $darker-gray
        background-color: $darker-gray

    .logo-font
        font-family: $logo-font
        font-size: 48px
        font-weight: 300
        text-transform: capitalize
  1. a - 因为自行预设是黑色,所以我们要针对 modal 下的 a 在另外进行样式设定,包含 hover 时的颜色,也可以顺便设定 padding 让排版看起来更整齐
  2. hr - 官方是使用 ul li 的方式来做分隔线,但我觉得有点麻烦,所以直接使用 hr 来做分隔
  3. .logo-font - 这个部分是,中间那组 column 的字型是使用 logo 的字型,针对这部分也个别做 class 去设定

接下来是 js 的部分,因为 secondary menu 的部分被重复使用了,为了方便我将它做成 array 的形式来使用,而右侧其他资讯 info 的地方也一并使用 array 的形式作储存,方便我们後续带出资料

const secondaryMenu = [
    "fashion",
    "beauty",
    "entertainment",
    "lifestyle",
    "luxury",
    "video",
    "Vogue有意识",
  ];

const info = [
    "秀场图辑 RUNWAY SHOW",
    "可能研究所",
    "美人会部落格",
    "风格达人",
    "评美时尚客",
    "活动快报",
  ];

而 render 出的方式使用前面使用过的 map,整个 modal 的内容目前会如下

<div className={modalOpen === true ? "modal show" : "modal"}>
    <div className="modal-dialog">
      <div className="modal-content">
        <div className="modal-header">
          <div className="modal-title">VOGUE</div>
          <label
            className="close-button"
            onClick={() => handleModalClick(false)}
          >
            <FontAwesomeIcon icon={faTimes} size="3x" />
          </label>
        </div>
        <div className="modal-body">
          <div className="modal-column">
            <a href="/">membership</a>
            <hr />
            <a href="/">vogue shop</a>
          </div>
          <div className="modal-column">
            {secondaryMenu.map(function (item) {
              return (
                <div>
                  <a className="logo-font" href="/">
                    {item}
                  </a>
                  <hr />
                </div>
              );
            })}
          </div>
          <div className="modal-column">
            {info.map(function (item) {
              return (
                <div>
                  <a href="/">{item}</a>
                  <hr />
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  </div>

前面有设定的 logo-font 样式使用 class 的方式套用上去了,大功告成!

今天就先到这边,大家掰掰~~~


除此之外,也欢迎大家走走逛逛关於我们团队夥伴的文章

lu23770127 - SASS 基础初学三十天

10u1 - 糟了!是世界奇观!

juck30808 - Python - 数位行销分析与 Youtube API 教学

HLD - 浅谈物件导向与Design Pattern介绍

SiQing47 - 前端?後端?你早晚都要全端的,何不从现在开始?


<<:  Day 27 自订路由

>>:  25 把卡片摆一摆

TypeScript 能手养成之旅 Day 7 物件型别-函式型别

前言 前一篇我们介绍了基础物件型别,今天要来介绍同样是物件型别之一的函式型别,让我继续探索 Type...

Day1 — 前言:为什麽是 AVR?

或许看到本系列文章会产生的第一个疑问大概就是:「为什麽是 AVR?」。的确,现在潮潮都用 x86,不...

Normals & Lighting

大家好,我是西瓜,你现在看到的是 2021 iThome 铁人赛『如何在网页中绘制 3D 场景?从 ...

Day16 React-Router(一)基本路由

随着专案越来越庞大,如果我们想用单页应用程序(SPA)架设网站,需透过route(路由)来渲染不同的...

[影片]第28天:英雄指南-5. 新增应用内导航(3)

GitHub:https://github.com/dannypc1628/Angular-Tou...