Skip to content

Instantly share code, notes, and snippets.

@whoisryosuke
Created July 28, 2020 21:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whoisryosuke/97cc4b5617fe639e0b38b19ea2d4264d to your computer and use it in GitHub Desktop.
Save whoisryosuke/97cc4b5617fe639e0b38b19ea2d4264d to your computer and use it in GitHub Desktop.
React / Typescript - SVG component that accepts SVG in `as` prop --
import React from "react";
// Ignore because SC type pkg is broken for now
// @ts-ignore
import styled from "styled-components";
import {
compose,
typography,
space,
color,
layout,
SpaceProps,
ColorProps,
} from "styled-system";
export type Assign<T, U> = {
[P in keyof (T & U)]: P extends keyof T
? T[P]
: P extends keyof U
? U[P]
: never;
};
export interface BoxOwnProps extends SpaceProps, ColorProps {
as?: React.ElementType;
variant?: string;
}
export interface BoxProps
extends Assign<React.ComponentProps<"div">, BoxOwnProps> {}
export const Box = styled("div")<BoxProps>(
{
boxSizing: "border-box",
margin: 0,
minWidth: 0,
},
compose(typography, space, color, layout)
);
import * as React from "react";
import { Box, Assign, BoxOwnProps } from "zenny-ui-box";
export interface SVGProps
extends Assign<React.ComponentProps<"svg">, BoxOwnProps> {}
export const SVG = styled(Box).attrs(
({ as: Component, width, height, viewBox }: SVGProps) => ({
// Define props on top of Box
// Set underlying element as svg
// Or custom component (like react-icons)
as: Component ?? "svg",
xmlns: "http://www.w3.org/2000/svg",
viewBox: viewBox ?? "0 0 24 24",
width: width ?? "24px",
height: height ?? "24px",
})
)<SVGProps>();
// <SVG as={FiArrowDownCircle} width="48px" height="48px" />
// <SVG as={FiArrowDownCircle} color="primary" stroke="currentcolor" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment