[Day 27 - 小试身手] Todolist with React (2)

在上一章Todolist with React (1),建立了专案环境、并且拆离 UI 设定好所有 Component 後,现在就让我们使用套件 Styled-components 来为组件添加样式。

上面是目前的画面

这是预计实现的样式

App Component

首先是最外层的 App Component,要设定

  • Wrapper:包覆内部所有元素,设定背景和大小。
  • Title:Todolist 标题样式

App.js

import TaskList from "./TaskList";
import AddTask from "./AddTask";

function App() {
  return (
    <Wrapper>
      <Title>Todolist</Title>
      <AddTask />
      <TaskList />
    </Wrapper>
  );
}
import styled from "styled-components";

const Wrapper = styled.div`
  background-color: #3c5d95;
  height: 100vh;
  padding-top: 70px;
`;

const Title = styled.h1`
  margin: 0;
  text-align: center;
  font-weight: bold;
  font-size: 28px;
  letter-spacing: 2px;
  color: #ffc236;
  text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
`;

清除 body margin / 设定字体

在 App.js 引入 CSS 档 app.css ,清除 body 预设的 margin,并且设定网页统一的字型样式。

import "./app.css";

app.css

body {
  margin: 0;
  font-family: "Noto Sans TC", sans-serif;
}

AddTask Component

新增任务的区块 AddTask Component,要设定:

  • Wrapper:包覆内部所有元素,指定元素的排列规则。
  • Input:输入框区块,&::placeholder 可以设定预设显示文字的字体颜色。
  • AddBtn:新增按钮区块,利用巢状写法一定设定内部的图片样式。

AddTask.js

import addIcon from "../assets/icon/add.png";

function AddTask() {
  return (
    <Wrapper>
        <Input
          name="addtask"
          type="text"
          placeholder={"add new task ..."}
        />
      <AddBtn>
        <img src={addIcon} alt=""/>
      </AddBtn>
    </Wrapper>
  );
}
import styled from "styled-components";

const Wrapper = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 300px;
  margin: 25px auto 40px;
`;

const Input = styled.input`
  padding: 0.5em;
  margin: 0.5em;
  background-color: inherit;
  border: none;
  border-bottom: 2px solid #333;
  width: 300px;
  font-size: 16px;
  letter-spacing: 0.05em;

  &::placeholder {
    color: #333;
  }
`;

const AddBtn = styled.button`
  padding: 0;
  border: none;
  height: 27px;
  width: 27px;
  background-color: inherit;

  img {
    cursor: pointer;
  }
`;

TaskList Component

列出待办事项,包含筛选器跟清单的 TaskList Component,要设定:

  • Wrapper:设定宽度,控制内部元素的范围。
  • TaskItemContainer:任务清单区块,设定任务 TaskItem 的排列方式。

TaskList.js

import Filter from "./Filter";
import TaskItem from "./TaskItem";

function TaskList() {
  return (
    <Wrapper>
      <Filter />
      <TaskItemContainer>
          <TaskItem />
          <TaskItem />
          <TaskItem />
      </TaskItemContainer>
    </Wrapper>
  );
}
import styled from "styled-components";

const Wrapper = styled.div`
  margin: 0 auto;
  width: 80%;
  max-width: 600px;
  min-width: 300px;
`;

const TaskItemContainer = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  padding: 30px 0;
  background-color: #f8f8f8;
`;

Filter Component

再来是筛选器 Filter Component,要设定:

  • ButtonContainer:设定内部按钮的排列方式。
  • Button:指定按钮样式,&:hover 可以设定滑鼠移至按钮的样式。

Filter.js

function Filter() {
return (
    <ButtonContainer>
      <Button>ALL</Button>
      <Button>TODO</Button>
      <Button>DONE</Button>
    </ButtonContainer>
  );
}
import styled from "styled-components";

const ButtonContainer = styled.div`
  display: flex;
`;

const Button = styled.div`
  width: min-content;
  padding: 5px 10px;
  margin-right: 10px;
  background-color: #bebebe;
  border: none;
  border-bottom: 2px solid #3c5d95;
  border-radius: 3px 3px 0 0;
  color: white;
  letter-spacing: 0.1em;
  text-align: center;
  cursor: pointer;

  &:hover {
    background-color: #ffc236;
  }
`;

TaskItem Components

代表每个任务的 TaskItem Component,要设定:

  • Wrapper:设定整个任务方块的大小和内部元素的排列方式
  • CheckBox:勾选框的样式
  • TaskName:设定任务文字样式
  • Button:删除任务的按钮样式

TaskItem.js

function TaskItem() {
  return (
    <Wrapper>
      <CheckBox type="checkbox"/>
      <TaskName>NEW TASK</TaskName>
      <Button>Delete</Button>
    </Wrapper>
  );
}
import styled from "styled-components";

const Wrapper = styled.div`
  background-color: white;
  width: 80%;
  height: 60px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  letter-spacing: 0.05em;
  padding: 0 20px;
`;

const CheckBox = styled.input.attrs({ type: 'checkbox' })`
  width: 18px;
  height: 18px;
  cursor: pointer;
`;

const TaskName = styled.div`
  flex-grow: 1;
  margin: 0 20px;
`;

const Button = styled.div`
  background-color: #bebebe;
  border: none;
  border-radius: 3px;
  padding: 5px 10px;
  width: min-content;
  color: white;
  letter-spacing: 0.05em;
  cursor: pointer;

  &:hover {
    background-color: #F5727E;
  }
`;


小结

这样就完成了所有的样式设定,建议大家在做的过程中,可以一段一段去观察每个样式会对网页造成什麽样的改变,进而去熟悉使用各式各样的样式。在下一篇文章,就来在 React 中加入 Redux,使用 React-redux 动态产生任务清单,那我们就明天见罗!

范例程序码

如果文章中有错误的地方,要麻烦各位大大不吝赐教;喜欢的话,也要记得帮我按赞订阅喔❤️


<<:  Day26_CSS语法9

>>:  [Day25]DDL语句建立资料表2

Day18-"字串练习-1"

利用两种不同方法分别宣告两字串,并将资料印出,每笔资料都须换行。 . . . . . #inclu...

Day 23 Flask-Login

上一篇讲完了可以在客户端及伺服端双向通讯的 WebSocket ,这篇要讲的是有关登入系统的 Fla...

Angular Reactive Form 响应式表单 (formControl)

昨天我们看了 一长串的表单使用范例 都是经过理解消化後所写出来的 code ,那麽今天就来聊一聊消化...

【Day16】电子商务与行销篇-电子商务

#odoo #开源系统 #数位赋能 #E化自主 从Google 在 2020 年 12 月发表的智慧...

Day 19 - Rancher App(v2.5) 介绍

本文将於赛後同步刊登於笔者部落格 有兴趣学习更多 Kubernetes/DevOps/Linux 相...