Open3

Reactコンポーネントメモ書き

oosukeoosuke

Typography

@emotion/styledを利用

import styled from "@emotion/styled";

type Props = {
    variant?: "h1" | "h2" | "h3" | "h4" | "h5" | "p" | "small" | "span";
    type?:
        | "secondary"
        | "success"
        | "light"
        | "primary"
        | "danger"
        | "warning"
        | "info"
        | "default";
    align?: "inherit" | "justify" | "left" | "right" | "center" | "justify-all";
    children: React.ReactNode;
}  & React.HtmlHTMLAttributes<HTMLElement>;

const colors = (color: Props["type"]) => {
    switch (color) {
        case "primary":
            return "#1976d2";
        case "secondary":
            return "#6C757D";
        case "success":
            return "#2e7d32";
        case "danger":
            return "#d32f2f";
        case "warning":
            return "#ff9800";
        case "info":
            return "#0288d1";
        case "light":
            return "#F8F9FA";
        default:
            return "#212529";
    }
};

const Section = styled.section<Props>`
    color: ${(props) => colors(props.type)};
    text-align: ${(props) => props.align};
`;

export const Typography: React.FC<Props> = ({
    variant = "p",
    type = "default",
    align = "inherit",
    children,
    ...rest
}) => {
    const Element = Section.withComponent(variant);
    return (
       <Element color={type} align={align} {...rest}>
            {children}
        </Element>
    );
};
oosukeoosuke

Stack(flexbox用)

@emotion/styledを利用

import styled from "@emotion/styled";

type Props = {
  children: React.ReactNode;
  spacing?: number;
  direction?: "row" | "row-reverse" | "column" | "column-reverse";
  alignItems?: "flex-start" | "center" | "flex-end" | "stretch" | "baseline";
  justifyContent?:
    | "flex-start"
    | "center"
    | "flex-end"
    | "space-between"
    | "space-around"
    | "space-evenly";
};

export const Stack = styled.div<Props>`
  padding: 16px;
  display: flex;
  gap: ${(props) => (props.spacing || 1) * 8}px;
  flex-direction: ${(props) => props.direction || "column"};
  align-items: ${(props) => props.alignItems || "flex-start"};
  justify-content: ${(props) => props.justifyContent || "flex-start"};
`;
oosukeoosuke

Link(NextLink用)

@emotion/styledを利用

import { colors } from "@/theme/colors";
import styled from "@emotion/styled";
import NextLink from "next/link";

type Props = {
  children: React.ReactNode;
  href: string;
};

const StyledLink = styled(NextLink)`
  text-decoration: none;
  color: ${colors("default")};
  transition: "0.3 all";
  &:hover {
    opacity: 0.8;
  }
`;

export const Link: React.FC<Props> = ({ children, href }) => {
  return <StyledLink href={href}>{children}</StyledLink>;
};