iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 26
1
自我挑戰組

30 天來點 Design System系列 第 26

Day 26 建立 導覽相關組件

  • 分享至 

  • xImage
  •  

包含:

  • breadcrumbs 麵包屑
  • steps 步驟

Breadcrumbs

實作

import React, { Fragment } from "react";
import styled from "styled-jss";
import propTypes from "prop-types";
import isEmpty from 'lodash/isEmpty';
import Typography from "../Typography";
import theme from "../theme";

const StyledPath = styled("a")({
  display: "inline-block",
  textDecoration: "none",
  color: ({ theme, href }) => isEmpty(href) ? theme.colors.grey4: theme.colors.primary,
});

const StyledSeparate = styled("span")({
  display: ({ hidden }) => (hidden ? "none" : "inline-block"),
  padding: ({ theme }) => theme.getSpacing(0.5),
  color: ({ theme }) => theme.colors.grey2,
});

const Paths = ({ paths }) => {
  return paths.map((item, index) => {
    const showSeparator = index === paths.length - 1;
    return (
      <Fragment>
        <StyledPath href={item.path}>
          <Typography>{item.text}</Typography>
        </StyledPath>
        <StyledSeparate hidden={showSeparator}>/</StyledSeparate>
      </Fragment>
    );
  });
};

const Breadcrumbs = ({ paths, ...props }) => {
  return (
    <Fragment>
      <Paths paths={paths} />
    </Fragment>
  );
};

Breadcrumbs.propTypes = {
  paths: propTypes.arrayOf(
    propTypes.shape({
      text: propTypes.string,
      path: propTypes.string,
    })
  ),
};

Breadcrumbs.defaultProps = {
  paths: [],
};

export default Breadcrumbs;

Usage

import React, { Fragment } from "react";
import theme from "../../lib/theme";
import Button from "../../lib/Button/index";
import ThemeProvider from "../../lib/ThemeProvider";
import Breadcrumbs from '../../lib/Breadcrumbs';

const paths = [
  {
    text: 'path 1',
  },
  {
    text: 'path 2',
    path: '/'
  },
  {
    text: 'path 3',
    path: '/'
  }
]

const Provider = (props) => {
  return <ThemeProvider theme={theme}>{props.children}</ThemeProvider>;
};

const Template = (args) => {
  return (
    <Provider>
      <Fragment>
        <Breadcrumbs paths={paths}/>
      </Fragment>
    </Provider>
  );
};

export const Default = Template.bind({});

// 你的頁面標題
export default {
  component: Breadcrumbs,
  title: "Components/Breadcrumbs",
};

結果如下:

Steps

import React, { Fragment } from "react";
import styled from "styled-jss";
import propTypes from "prop-types";

const StyledStep = styled("span")({
  width: 10,
  height: 10,
  display: "block",
  borderRadius: 20,
  lineHeight: "10px",
  textAlign: "center",
  padding: ({ theme }) => theme.getSpacing(1),
  color:  ({ theme, active, step }) => active.includes(step) ? theme.colors.white: theme.colors.grey4,
  backgroundColor: ({ theme, active, step }) => active.includes(step) ? theme.colors.primary: theme.colors.grey1,
});

const StyledStepsContainer = styled("div")({
  width: "100%",
  display: "flex",
  alignItems: "center",
  justifyContent: "space-between",
});

const Separator = styled("div")({
  flex: 1,
  height: 1,
  border: '5px solid #fff',
  display: ({ hide }) => (hide ? "none" : "block"),
  backgroundColor: ({ theme }) => theme.colors.grey1,
  borderBottom: ({ theme }) => `1px solid ${theme.colors.grey1}px`,
});

const Step = ({ step, active }) => {
  return <StyledStep step={step} active={active}>{step}</StyledStep>;
};

const Steps = ({ steps, active }) => {
  return (
    <StyledStepsContainer>
      {steps.map((step, index) => {
        const showSeparator = steps.length - 1 === index;
        return (
          <Fragment>
            <Step step={step} active={active} />
            <Separator hide={showSeparator} />
          </Fragment>
        );
      })}
    </StyledStepsContainer>
  );
};

Steps.propTypes = {
  steps: propTypes.arrayOf(
    propTypes.oneOfType([propTypes.number, propTypes.string])
  ),
  active: propTypes.arrayOf(
    propTypes.oneOfType([propTypes.number, propTypes.string])
  ),
};

export default Steps;

Usage

import React, { Fragment } from "react";
import theme from "../../lib/theme";
import Steps from "../../lib/Steps";
import ThemeProvider from "../../lib/ThemeProvider";

const steps = [1, 2, 3];
const active = [1, 2];

const Provider = (props) => {
  return <ThemeProvider theme={theme}>{props.children}</ThemeProvider>;
};

const Template = (args) => {
  return (
    <Provider>
      <Fragment>
        <Steps {...args} />
      </Fragment>
    </Provider>
  );
};

export const Default = Template.bind({});
Default.args = {
  steps,
  active,
};

// 你的頁面標題
export default {
  component: Steps,
  title: "Components/Steps",
};

結果如下:


上一篇
Day 25 建立 下拉選單
下一篇
Day 27 建立 Switch
系列文
30 天來點 Design System30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言