Skip to content

Commit

Permalink
Styled Inspector (#56)
Browse files Browse the repository at this point in the history
* inspector: use babel for m1

* feature: panel layout

* chore: componentize

* feat:error handling, LOC + kb

* chore: cleanup

* chore: font loading, tweak on debug mode
  • Loading branch information
g-a-v-i-n authored Jul 3, 2022
1 parent ae93573 commit 42ce9a5
Show file tree
Hide file tree
Showing 31 changed files with 3,846 additions and 331 deletions.
2 changes: 1 addition & 1 deletion lib/forge-std
2 changes: 1 addition & 1 deletion lib/solmate
3 changes: 3 additions & 0 deletions packages/inspector/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["next/babel"]
}
27 changes: 27 additions & 0 deletions packages/inspector/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ButtonProps } from "../types";
import classnames from "classnames";

export function Button(props: ButtonProps) {
const cns = classnames({
"bg-primary": props.primary,
"bg-white/20" : !props.primary,
"shadow-none opacity-50 pointer-events-none": props.disabled,
"shadow-elevation-low": !props.disabled,
})
return (
<button
type="button"
className={`transition-opacity user-select-none px-2 py-0.5 border border-white/10 text-white rounded-lg ${cns} ${props.className}`}
onClick={props.onClick}
>
{props.children}
</button>
);
}

Button.defaultProps = {
primary: false,
className: "",
children: null,
disabled: false,
};
35 changes: 0 additions & 35 deletions packages/inspector/components/Buttons.tsx

This file was deleted.

15 changes: 15 additions & 0 deletions packages/inspector/components/Container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Div100vh from "react-div-100vh";
import { GenericComponentProps } from "../types";

export function Container(props: GenericComponentProps) {
return (
<Div100vh className={`relative w-full flex h-full ${props.className}`}>
{props.children}
</Div100vh>
);
}

Container.defaultProps = {
className: "",
children: null,
};
4 changes: 2 additions & 2 deletions packages/inspector/components/Dots.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useEffect, useState} from "react";
import { useEffect, useState } from "react";

const Dots = () => {
const [state, setState] = useState(0);
Expand All @@ -14,4 +14,4 @@ const Dots = () => {
return <span className="dots">{new Array(state).fill(".").join("").padEnd(3, " ")}</span>;
};

export {Dots};
export { Dots };
7 changes: 7 additions & 0 deletions packages/inspector/components/HorizontalRule.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function HorizontalRule(props: { className?: string }) {
return <div className={`w-full border-t border-t-black ${props.className}`} />;
}

HorizontalRule.defaultProps = {
className: "",
};
27 changes: 27 additions & 0 deletions packages/inspector/components/ImageViewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { NFTState } from "../types";

type ImageViewerProps = {
debug?: boolean;
className?: string;
rawSVG: string;
metadata: NFTState["metadata"];
};

export function ImageViewer(props: ImageViewerProps) {
return (
<div
className={`rounded-3xl shadow-elevation-medium relative h-full w-auto overflow-hidden ${props.className}`}
>
<img
src={props.metadata.image}
className={`rounded-3xl w-full h-auto ${props.debug ? "debug-svg" : ""}`}
/>
<div className="rounded-3xl z-10 absolute content-none top-0 left-0 right-0 bottom-0 border border-white/10" />
</div>
);
}

ImageViewer.defaultProps = {
debug: false,
className: "",
};
16 changes: 16 additions & 0 deletions packages/inspector/components/Pane.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { GenericComponentProps } from "../types";

export function Pane(props: GenericComponentProps) {
return (
<section
className={`bg-background w-full h-full flex flex-col overflow-y-scroll overflow-x-hidden ${props.className}`}
>
{props.children}
</section>
);
}

Pane.defaultProps = {
className: "",
children: null,
};
58 changes: 0 additions & 58 deletions packages/inspector/components/Panels.tsx

This file was deleted.

25 changes: 25 additions & 0 deletions packages/inspector/components/RawSVGViewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
type RawSVGViewerProps = {
debug?: boolean;
className?: string;
rawSVG: string;
isLoading?: boolean;
};

export function RawSVGViewer(props: RawSVGViewerProps) {
return (
<div
className={`rounded-3xl shadow-elevation-medium relative h-full w-auto bg-white/5 ${props.className}`}
>
<div
className={`rounded-3xl h-full w-auto overflow-hidden transition-opacity duration-300 ${props.isLoading ? 'opacity-0' : 'opacity-100'} ${props.debug ? "debug-svg" : ""}`}
dangerouslySetInnerHTML={{ __html: props.rawSVG }}
/>
<div className={`rounded-3xl z-90 absolute content-none top-0 left-0 right-0 bottom-0 ${props.debug ? 'inner-shadow-border-debug':"inner-shadow-border"}`} />
</div>
);
}

RawSVGViewer.defaultProps = {
debug: false,
className: "",
};
21 changes: 21 additions & 0 deletions packages/inspector/components/ToggleButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ButtonProps } from "../types";

export function ToggleButton(props: ButtonProps & { isOn: boolean }) {
return (
<button
type="button"
className="px-2 py-0.5 bg-white/20 border border-white/5 text-white rounded-lg flex items-center justify-center gap-x-1.5 shadow-elevation-low "
onClick={props.onClick}
>
<div className={`transition-all user-select-none w-2 h-2 rounded-full ${props.isOn ? "bg-white shadow-glow" : "bg-white/20 shadow-none"}`} />
{props.children}
</button>
);
}

ToggleButton.defaultProps = {
primary: false,
className: "",
children: null,
isOn: false,
};
14 changes: 14 additions & 0 deletions packages/inspector/components/Toolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { GenericComponentProps } from "../types";

export function Toolbar(props: GenericComponentProps) {
return (
<span className={`w-full bg-white/5 flex h-14 min-h-12 items-center px-3 flex-shrink-0 gap-x-2 ${props.className}`}>
{props.children}
</span>
);
}

Toolbar.defaultProps = {
className: "",
children: null,
};
28 changes: 28 additions & 0 deletions packages/inspector/components/TraitsTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { trait } from "../types";
import { isOdd } from "../util";

export const TraitsTable = ({
name,
loading,
tokenId,
attributes,
}: {
name: string;
loading: boolean;
tokenId: number;
attributes: trait[];
}) => {
const Loading = () => "loading";
return (
<div className="flex w-full flex-col">
<span className="w-full px-8 py-2 text-white font-bold bg-white/5">{name}</span>

{attributes.map(({ trait_type, value }, i) => (
<span className={`w-full flex ${isOdd(i) ? "bg-white/5" : "bg-white/10"}`}>
<span className="w-full px-8 py-1 text-white text-sm">{trait_type}</span>
<span className="w-full px-8 py-1 text-primary text-sm font-medium">{value}</span>
</span>
))}
</div>
);
};
7 changes: 7 additions & 0 deletions packages/inspector/components/VerticalRule.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function VerticalRule(props: { className?: string }) {
return <div className={`border-l border-l-black ${props.className}`} />;
}

VerticalRule.defaultProps = {
className: "",
};
12 changes: 1 addition & 11 deletions packages/inspector/hooks/useNFT.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import { useState, useEffect } from "react";
import { decodeBase64 } from "../util";
import { trait } from "../types";

type NFTState = {
metadata: {
name: string;
image: string;
attributes: trait[];
};
tokenId: number;
rawSVG: string;
};
import { trait, NFTState } from "../types";

const defaultState = {
metadata: {
Expand Down
23 changes: 21 additions & 2 deletions packages/inspector/hooks/useSVG.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
import { useState, useEffect } from "react";
// import babelParser from 'prettier/parser-babel'
import htmlParser from 'prettier/parser-html'

import prettier from 'prettier/standalone'

const options = {
parser: 'html',
plugins: [htmlParser],
tabWidth: 2,
semi: false,
singleQuote: false
}

function formatSVG(code: string) {
return prettier.format(code, options)
}

import formatSVG from "xml-formatter";

export const useSvg = (svg: string) => {
const [formatted, setFormatted] = useState("");
const [error, setError] = useState("");

useEffect(() => {
try {
setFormatted(formatSVG(svg));
if (svg === null) {
setFormatted("");
} else {
setFormatted(formatSVG(svg));
}
} catch (e) {
setError(e.message);
}
Expand Down
Loading

0 comments on commit 42ce9a5

Please sign in to comment.