diff --git a/.changeset/fair-queens-travel.md b/.changeset/fair-queens-travel.md
new file mode 100644
index 00000000..caf3f897
--- /dev/null
+++ b/.changeset/fair-queens-travel.md
@@ -0,0 +1,7 @@
+---
+"@polkadex/ux": major
+"docs": minor
+"web": minor
+---
+
+Scaffolding of Basic Shared Components
diff --git a/.github/workflows/pr-main.yml b/.github/workflows/pr-main.yml
index 0a1c6e8f..f4b2f6b0 100644
--- a/.github/workflows/pr-main.yml
+++ b/.github/workflows/pr-main.yml
@@ -2,7 +2,7 @@ name: CI Build and Test
on:
pull_request:
- types: [labeled]
+ types: [labeled, synchronize]
push:
branches: [main]
diff --git a/apps/docs/app/page.tsx b/apps/docs/app/page.tsx
index a265aa1c..d46fa508 100644
--- a/apps/docs/app/page.tsx
+++ b/apps/docs/app/page.tsx
@@ -1,5 +1,4 @@
import Image from "next/image";
-import { Card } from "ui";
import styles from "./page.module.css";
@@ -125,13 +124,7 @@ export default function Page(): JSX.Element {
-
- {LINKS.map(({ title, href, description }) => (
-
- {description}
-
- ))}
-
+
);
}
diff --git a/apps/docs/next.config.js b/apps/docs/next.config.js
index b19cd371..848b4e08 100644
--- a/apps/docs/next.config.js
+++ b/apps/docs/next.config.js
@@ -1,4 +1,4 @@
module.exports = {
reactStrictMode: true,
- transpilePackages: ["ui", "react-providers"],
+ transpilePackages: ["@polkadex/ux", "react-providers"],
};
diff --git a/apps/docs/package.json b/apps/docs/package.json
index 88d56d22..b3e04168 100644
--- a/apps/docs/package.json
+++ b/apps/docs/package.json
@@ -12,7 +12,7 @@
"next": "^13.4.19",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "ui": "*"
+ "@polkadex/ux": "*"
},
"devDependencies": {
"@next/eslint-plugin-next": "^13.4.19",
diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx
index 7ce283eb..3e9df9d8 100644
--- a/apps/web/app/page.tsx
+++ b/apps/web/app/page.tsx
@@ -1,6 +1,5 @@
"use client";
import Image from "next/image";
-import { Card } from "ui";
import styles from "./page.module.css";
@@ -124,13 +123,7 @@ export default function Page(): JSX.Element {
-
- {LINKS.map(({ title, href, description }) => (
-
- {description}
-
- ))}
-
+
);
}
diff --git a/apps/web/next.config.js b/apps/web/next.config.js
index 64d6eb3e..6a3ed026 100644
--- a/apps/web/next.config.js
+++ b/apps/web/next.config.js
@@ -1,7 +1,7 @@
module.exports = {
reactStrictMode: false,
transpilePackages: [
- "ui",
+ "@polkadex/ux",
"@polkadex/react-providers",
"@chainsafe/metamask-polkadot-adapter",
],
diff --git a/apps/web/package.json b/apps/web/package.json
index bb5d5abc..41c3026b 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -14,7 +14,7 @@
"react-dom": "^18.2.0",
"@polkadex/react-providers": "*",
"@polkadot-cloud/react": "^0.1.127",
- "ui": "*"
+ "@polkadex/ux": "*"
},
"devDependencies": {
"@next/eslint-plugin-next": "^13.4.19",
diff --git a/packages/ui/README.md b/packages/ui/README.md
new file mode 100644
index 00000000..7033f249
--- /dev/null
+++ b/packages/ui/README.md
@@ -0,0 +1,7 @@
+# Polkadex UX
+
+## Getting Started
+An open source design system for building modern websites and applications.
+
+## Documentation
+Visit http://ux.polkadex.trade to view the documentation.
diff --git a/packages/ui/card.tsx b/packages/ui/card.tsx
deleted file mode 100644
index e6551f32..00000000
--- a/packages/ui/card.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import * as React from "react";
-
-export function Card({
- className,
- title,
- children,
- href,
-}: {
- className?: string;
- title: string;
- children: React.ReactNode;
- href: string;
-}): JSX.Element {
- return (
-
-
- {title} ->
-
- {children}
-
- );
-}
diff --git a/packages/ui/index.ts b/packages/ui/index.ts
new file mode 100644
index 00000000..d8b2730f
--- /dev/null
+++ b/packages/ui/index.ts
@@ -0,0 +1,2 @@
+// component exports
+export * from "./src/components";
diff --git a/packages/ui/index.tsx b/packages/ui/index.tsx
deleted file mode 100644
index 926b1511..00000000
--- a/packages/ui/index.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-// component exports
-export { Card } from "./card";
diff --git a/packages/ui/package.json b/packages/ui/package.json
index b7e4c127..f2470ee0 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -1,21 +1,47 @@
{
- "name": "ui",
- "version": "0.0.0",
- "main": "./index.tsx",
- "types": "./index.tsx",
+ "name": "@polkadex/ux",
+ "version": "0.0.1",
+ "main": "./dist/index.js",
+ "module": "./dist/index.mjs",
+ "types": "./dist/index.d.ts",
"license": "MIT",
+ "files": [
+ "dist/**"
+ ],
"scripts": {
- "lint": "eslint .",
- "generate:component": "turbo gen react-component"
+ "dev": "tsup index.ts --format esm,cjs --watch --dts",
+ "build": "tsup index.ts --format esm,cjs --dts",
+ "typecheck": "tsc --noEmit",
+ "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
+ "lint": "eslint ./src"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
},
"devDependencies": {
"@turbo/gen": "^1.10.12",
"@types/node": "^20.5.2",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
- "eslint-config-custom": "*",
- "react": "^18.2.0",
+ "autoprefixer": "^10.4.16",
+ "classnames": "^2.3.2",
+ "@polkadex-ts/eslint-config": "*",
+ "postcss": "^8.4.31",
+ "tailwind-merge": "^2.0.0",
"tsconfig": "*",
- "typescript": "^4.5.2"
+ "typescript": "^4.5.2",
+ "tsup": "^7.2.0",
+ "tailwindcss-animate": "^1.0.7"
+ },
+ "dependencies": {
+ "@heroicons/react": "^2.0.18",
+ "@radix-ui/react-alert-dialog": "^1.0.5",
+ "@radix-ui/react-dropdown-menu": "^2.0.6",
+ "@radix-ui/react-popover": "^1.0.7",
+ "@radix-ui/react-slot": "^1.0.2",
+ "@radix-ui/react-tooltip": "^1.0.7",
+ "tailwindcss": "^3.3.5",
+ "react-use": "^17.4.0"
}
}
diff --git a/packages/ui/postcss.config.js b/packages/ui/postcss.config.js
new file mode 100644
index 00000000..12a703d9
--- /dev/null
+++ b/packages/ui/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/packages/ui/src/components/button.tsx b/packages/ui/src/components/button.tsx
new file mode 100644
index 00000000..3a62e005
--- /dev/null
+++ b/packages/ui/src/components/button.tsx
@@ -0,0 +1,80 @@
+import { ComponentProps, ElementType, PropsWithChildren } from "react";
+import classNames from "classnames";
+import { twMerge } from "tailwind-merge";
+import { Slot } from "@radix-ui/react-slot";
+
+export interface ButtonProps extends ComponentProps<"button"> {
+ asChild?: boolean;
+ size?: keyof (typeof variants)["size"];
+ variant?: keyof (typeof variants)["variant"];
+}
+
+const variants = {
+ size: {
+ xs: "h-3 px-0.5 py-2 text-xs rounded-sm",
+ sm: "h-6 px-1 py-2 rounded-sm",
+ default: "h6 px-4 py-2 rounded-md",
+ md: "h-10 px-4 py-2 rounded-md",
+ lg: "h-14 px-8 py-4 text-md rounded-md",
+ },
+ variant: {
+ primary: "bg-primary-base hover:bg-primary-hover active:bg-primary-pressed",
+ secondary:
+ "bg-secondary-base hover:bg-secondary-hover active:bg-secondary-pressed",
+ ghost:
+ "bg-transparent hover:bg-secondary-pressed active:bg-secondary-hover text-primary hover:text-textBase",
+ outline:
+ "border border-secondary-base hover:bg-secondary-pressed active:bg-secondary-hover ",
+ },
+};
+
+const Base = ({
+ className,
+ asChild = false,
+ size = "default",
+ variant = "primary",
+ children,
+ ...props
+}: PropsWithChildren) => {
+ const Rendercomponent: ElementType = asChild ? Slot : "button";
+ return (
+
+ {children}
+
+ );
+};
+
+const Primary = (props: PropsWithChildren>) => (
+
+);
+
+const Secondary = (props: PropsWithChildren>) => (
+
+);
+
+const Ghost = (props: PropsWithChildren>) => (
+
+);
+
+const Outline = (props: PropsWithChildren>) => (
+
+);
+
+export const Button = {
+ Primary,
+ Secondary,
+ Ghost,
+ Outline,
+};
diff --git a/packages/ui/src/components/copy.tsx b/packages/ui/src/components/copy.tsx
new file mode 100644
index 00000000..a812527c
--- /dev/null
+++ b/packages/ui/src/components/copy.tsx
@@ -0,0 +1,53 @@
+import { ComponentProps, MouseEvent, PropsWithChildren, useState } from "react";
+import { DocumentDuplicateIcon } from "@heroicons/react/24/solid";
+import classNames from "classnames";
+import { TooltipContentProps } from "@radix-ui/react-tooltip";
+import { twMerge } from "tailwind-merge";
+
+import { Tooltip } from "./tooltip";
+
+interface CopyProps extends ComponentProps<"div"> {
+ value: string | number;
+ side?: TooltipContentProps["side"];
+}
+
+export const Copy = ({
+ value,
+ className,
+ side = "top",
+ children,
+}: PropsWithChildren) => {
+ const [open, setOpen] = useState(false);
+ const [state, setState] = useState(false);
+
+ const onCopy = async (e: MouseEvent) => {
+ e.preventDefault();
+ if (!value) return;
+ try {
+ await navigator.clipboard.writeText(value.toString());
+ if (!state) setState(true);
+ } catch (error) {
+ console.error("Error copying to clipboard:", error);
+ }
+ };
+
+ const onMouseOut = () => state && setState(false);
+
+ return (
+
+
+ {children ?? (
+
+ )}
+
+ e.preventDefault()}
+ >
+ {state ? "Copied" : "Copy"}
+
+
+ );
+};
diff --git a/packages/ui/src/components/dropdown.tsx b/packages/ui/src/components/dropdown.tsx
new file mode 100644
index 00000000..bf24e22f
--- /dev/null
+++ b/packages/ui/src/components/dropdown.tsx
@@ -0,0 +1,236 @@
+import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
+import { Children, PropsWithChildren } from "react";
+import { CheckIcon } from "@heroicons/react/24/solid";
+import { twMerge } from "tailwind-merge";
+import classNames from "classnames";
+
+import { isValidComponent } from "../helpers";
+
+const Radio = ({
+ children,
+ ...props
+}: PropsWithChildren) => {
+ const items = Children.toArray(children);
+
+ return {items};
+};
+interface ItemRadioProps extends DropdownMenu.MenuRadioItemProps {
+ active?: boolean;
+}
+
+const ItemRadio = ({
+ children,
+ className,
+ active,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+
+ {children}
+
+ );
+};
+
+const ItemCheckbox = ({
+ children,
+ className,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+
+
+
+ {children}
+
+ );
+};
+
+interface ItemProps extends DropdownMenu.MenuItemProps {
+ shortcut?: string;
+}
+
+const Item = ({
+ children,
+ shortcut,
+ className,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {children}
+ {shortcut && {shortcut}}
+
+ );
+};
+
+const Trigger = ({
+ children,
+ asChild,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {asChild ? {children}
: children}
+
+ );
+};
+
+const Content = ({
+ children,
+ className,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {children}
+
+ );
+};
+
+const Sub = ({
+ children,
+ ...props
+}: PropsWithChildren) => {
+ const [SubTriggerComponent] = isValidComponent(children, SubTrigger);
+ const [SubContentComponent] = isValidComponent(children, SubContent);
+
+ return (
+
+ {SubTriggerComponent}
+ {SubContentComponent}
+
+ );
+};
+
+const SubTrigger = ({
+ children,
+ ...props
+}: PropsWithChildren) => {
+ return (
+ {children}
+ );
+};
+
+const SubContent = ({
+ children,
+ ...props
+}: PropsWithChildren) => {
+ return (
+ {children}
+ );
+};
+
+const Separator = ({
+ children,
+ className,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {children}
+
+ );
+};
+const Label = ({
+ children,
+ className,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {children}
+
+ );
+};
+
+const Dropdown = ({
+ children,
+ ...props
+}: PropsWithChildren) => {
+ const [TriggerComponent] = isValidComponent(children, Trigger);
+ const [ContentComponent] = isValidComponent(children, Content);
+
+ return (
+
+ {TriggerComponent}
+ {ContentComponent}
+
+ );
+};
+
+Dropdown.Trigger = Trigger;
+Dropdown.Content = Content;
+Dropdown.Separator = Separator;
+Dropdown.Label = Label;
+
+Dropdown.Sub = Sub;
+Dropdown.SubTrigger = SubTrigger;
+Dropdown.SubContent = SubContent;
+
+Dropdown.Item = Item;
+Dropdown.ItemCheckbox = ItemCheckbox;
+
+Dropdown.Radio = Radio;
+Dropdown.ItemRadio = ItemRadio;
+
+export { Dropdown };
diff --git a/packages/ui/src/components/genericMessage.tsx b/packages/ui/src/components/genericMessage.tsx
new file mode 100644
index 00000000..159e0570
--- /dev/null
+++ b/packages/ui/src/components/genericMessage.tsx
@@ -0,0 +1,48 @@
+import { ComponentProps, PropsWithChildren } from "react";
+import classNames from "classnames";
+import { twMerge } from "tailwind-merge";
+
+import * as Vectors from "../illustrations";
+
+interface GenericMessageProps extends ComponentProps<"div"> {
+ title: string;
+ illustration: keyof typeof Vectors;
+ inverted?: boolean;
+ imageProps?: ComponentProps<"svg">;
+}
+
+export const GenericMessage = ({
+ title,
+ illustration,
+ inverted,
+ children,
+ imageProps,
+ className,
+ ...props
+}: PropsWithChildren) => {
+ const IllustrationComponent = Vectors[illustration];
+ return (
+
+ );
+};
diff --git a/packages/ui/src/components/icon.tsx b/packages/ui/src/components/icon.tsx
new file mode 100644
index 00000000..3d886074
--- /dev/null
+++ b/packages/ui/src/components/icon.tsx
@@ -0,0 +1,16 @@
+import { ComponentProps } from "react";
+
+import * as Icons from "../icons";
+
+interface Props extends ComponentProps<"svg"> {
+ name: string;
+}
+export const Icon = ({ name, ...props }: Props) => {
+ const iconUppercase = name.toUpperCase();
+ const iconTicker = (
+ iconUppercase in Icons ? iconUppercase : "Wallet"
+ ) as keyof typeof Icons;
+
+ const IconComponent = Icons[iconTicker];
+ return ;
+};
diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts
new file mode 100644
index 00000000..47528738
--- /dev/null
+++ b/packages/ui/src/components/index.ts
@@ -0,0 +1,16 @@
+// component exports
+export * from "./button";
+export * from "./logo";
+export * from "./typography";
+export * from "./modal";
+export * from "./interaction";
+export * from "./dropdown";
+export * from "./popover";
+export * from "./skeleton";
+export * from "./spinner";
+export * from "./genericMessage";
+export * from "./multistep";
+export * from "./input";
+export * from "./tooltip";
+export * from "./copy";
+export * from "./icon";
diff --git a/packages/ui/src/components/input.tsx b/packages/ui/src/components/input.tsx
new file mode 100644
index 00000000..3fd1e989
--- /dev/null
+++ b/packages/ui/src/components/input.tsx
@@ -0,0 +1,97 @@
+import { MagnifyingGlassIcon } from "@heroicons/react/24/solid";
+import { InputHTMLAttributes, PropsWithChildren, useRef } from "react";
+
+import { Button } from "./button";
+
+interface PrimaryInputProps extends InputHTMLAttributes {
+ increase: () => void;
+ decrease: () => void;
+ ticker: string;
+ label: string;
+}
+
+const Primary = ({
+ label,
+ increase,
+ decrease,
+ ticker,
+ ...props
+}: PropsWithChildren) => {
+ const ref = useRef(null);
+ return (
+ ref?.current?.focus()}
+ >
+
{label}
+
+
+
{ticker}
+
+
+
+
+
+
+ );
+};
+
+const Search = (props: InputHTMLAttributes) => (
+
+
+
+
+);
+
+interface VerticalProps extends InputHTMLAttributes {
+ label: string;
+ optional?: boolean;
+ action?: () => void;
+}
+const Vertical = ({ label, optional, action, ...props }: VerticalProps) => (
+
+
+
+ {label} {optional && (Optional)}
+
+
+
+ {action && (
+
+ Change
+
+ )}
+
+);
+
+export const Input = {
+ Primary,
+ Search,
+ Vertical,
+};
diff --git a/packages/ui/src/components/interaction.tsx b/packages/ui/src/components/interaction.tsx
new file mode 100644
index 00000000..4d3516ec
--- /dev/null
+++ b/packages/ui/src/components/interaction.tsx
@@ -0,0 +1,169 @@
+import { ComponentProps, PropsWithChildren } from "react";
+import classNames from "classnames";
+import { ArrowLeftIcon, XMarkIcon } from "@heroicons/react/24/solid";
+import { twMerge } from "tailwind-merge";
+
+import { isValidComponent } from "../helpers";
+
+import { Typography } from "./typography";
+import { Button, ButtonProps } from "./button";
+
+interface TitleProps extends ComponentProps<"div"> {
+ onBack?: () => void;
+ onClose?: () => void;
+ withPadding?: boolean;
+}
+const Title = ({
+ children,
+ withPadding = true,
+ onBack,
+ onClose,
+ className,
+ ...props
+}: PropsWithChildren) => {
+ const hasBack = typeof onBack === "function";
+ const hasClose = typeof onClose === "function";
+
+ return (
+
+ {hasBack && (
+
+ )}
+
+ {children}
+
+ {hasClose && (
+
+ )}
+
+ );
+};
+
+interface FooterProps extends ComponentProps<"div"> {
+ withPadding?: boolean;
+}
+
+const Footer = ({
+ children,
+ className,
+ withPadding = true,
+ ...props
+}: PropsWithChildren) => {
+ const [ActionComponent] = isValidComponent(children, Action);
+ const [CloseComponent] = isValidComponent(children, Close);
+
+ const customClassNames = twMerge(
+ classNames(withPadding && "px-7", "flex flex-col gap-3"),
+ className
+ );
+
+ if (!ActionComponent || (CloseComponent && children))
+ return (
+
+ {children}
+
+ );
+ return (
+
+ {ActionComponent}
+ {CloseComponent}
+
+ );
+};
+
+interface ActionProps extends ButtonProps, ComponentProps<"button"> {}
+
+const Action = ({ children, ...props }: PropsWithChildren) => {
+ return (
+
+ {children}
+
+ );
+};
+
+const Close = ({
+ children,
+ ...props
+}: PropsWithChildren>) => {
+ return (
+
+ {children}
+
+ );
+};
+
+interface ContentProps extends ComponentProps<"div"> {
+ onBack?: () => void;
+ onClose?: () => void;
+ withPadding?: boolean;
+}
+
+const Content = ({
+ children,
+ withPadding = true,
+ className,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {children}
+
+ );
+};
+const Interaction = ({
+ children,
+ className,
+ ...props
+}: PropsWithChildren>) => {
+ const [TitleCompontent] = isValidComponent(children, Title);
+ const [ContentCompontent] = isValidComponent(children, Content);
+ const [FooterCompontent] = isValidComponent(children, Footer);
+
+ return (
+
+ {TitleCompontent}
+ {ContentCompontent}
+ {FooterCompontent}
+
+ );
+};
+
+Interaction.Title = Title;
+Interaction.Content = Content;
+Interaction.Footer = Footer;
+Interaction.Action = Action;
+Interaction.Close = Close;
+
+export { Interaction };
diff --git a/packages/ui/src/components/logo.tsx b/packages/ui/src/components/logo.tsx
new file mode 100644
index 00000000..bca39e1f
--- /dev/null
+++ b/packages/ui/src/components/logo.tsx
@@ -0,0 +1,236 @@
+import { ComponentProps } from "react";
+
+const Thea = (props: ComponentProps<"svg">) => (
+
+);
+
+const Orderbook = (props: ComponentProps<"svg">) => (
+
+);
+
+const Polkadex = (props: ComponentProps<"svg">) => (
+
+);
+
+const Ux = (props: ComponentProps<"svg">) => (
+
+);
+
+export const Logo = {
+ Thea,
+ Orderbook,
+ Polkadex,
+ Ux,
+};
diff --git a/packages/ui/src/components/modal.tsx b/packages/ui/src/components/modal.tsx
new file mode 100644
index 00000000..d6442359
--- /dev/null
+++ b/packages/ui/src/components/modal.tsx
@@ -0,0 +1,114 @@
+import { ComponentProps, PropsWithChildren } from "react";
+import * as AlertDialog from "@radix-ui/react-alert-dialog";
+import classNames from "classnames";
+import { twMerge } from "tailwind-merge";
+
+import { isValidComponent, placements } from "../helpers";
+
+interface TitleProps extends AlertDialog.DialogTitleProps {
+ onBack?: () => void;
+}
+
+const Title = ({
+ children,
+ className,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {children}
+
+ );
+};
+
+const Footer = ({
+ children,
+ ...props
+}: PropsWithChildren>) => {
+ return {children}
;
+};
+
+const Content = ({
+ children,
+ ...props
+}: PropsWithChildren) => {
+ return (
+ {children}
+ );
+};
+
+type ModalProps = {
+ closeOnClickOutside?: boolean;
+ placement?: (typeof placements)[number];
+} & Pick &
+ AlertDialog.DialogContentProps;
+
+const modalPlace = {
+ center: "left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%]",
+ "center left": "left-[1%] top-[50%] translate-y-[-50%]",
+ "center right": "right-[1%] top-[50%] translate-y-[-50%]",
+ "top center": "left-[50%] top-[1%] translate-x-[-50%]",
+ "top left": "left-[1%] top-[1%]",
+ "top right": "right-[1%] top-[1%]",
+ "bottom center": "left-[50%] bottom-[1%] translate-x-[-50%]",
+ "bottom left": "left-[1%] bottom-[1%]",
+ "bottom right": "right-[1%] bottom-[1%]",
+};
+
+const Modal = ({
+ children,
+ open,
+ onOpenChange,
+ defaultOpen,
+ closeOnClickOutside,
+ className,
+ placement = "center",
+ ...props
+}: PropsWithChildren) => {
+ const [TitleComponent] = isValidComponent(children, Title);
+ const [ContentComponent] = isValidComponent(children, Content);
+ const [FooterComponent] = isValidComponent(children, Footer);
+
+ return (
+
+
+ onOpenChange?.(!open) : undefined
+ }
+ />
+
+ {TitleComponent}
+ {ContentComponent}
+ {FooterComponent}
+
+
+
+ );
+};
+
+Modal.Title = Title;
+Modal.Content = Content;
+Modal.Footer = Footer;
+
+export { Modal };
diff --git a/packages/ui/src/components/multistep.tsx b/packages/ui/src/components/multistep.tsx
new file mode 100644
index 00000000..ba4abb75
--- /dev/null
+++ b/packages/ui/src/components/multistep.tsx
@@ -0,0 +1,56 @@
+import {
+ Children,
+ Key,
+ PropsWithChildren,
+ ReactElement,
+ ReactNode,
+ isValidElement,
+ useState,
+} from "react";
+import { usePrevious } from "react-use";
+
+export type Actions = {
+ onBack: () => void;
+ onNext: () => void;
+ onPage: (id: string) => void;
+ current: number;
+};
+
+export const Multistep = ({
+ defaultIndex = 0,
+ children,
+}: {
+ defaultIndex?: number;
+ children: ((value?: Actions) => ReactNode) | ReactNode;
+}) => {
+ const [current, setCurrent] = useState(defaultIndex);
+ const prevCount = usePrevious(current);
+
+ let RenderComponent: ReactNode;
+
+ if (typeof children === "function") {
+ const [child] = Children.toArray(
+ children({
+ onNext: () => {
+ const childCount = Children.count(child?.props?.children);
+ setCurrent((current) => (current + 1) % childCount);
+ },
+ onBack: () => setCurrent(prevCount ?? 0),
+ onPage: (key: Key) => {
+ const childIndex = (
+ child?.props?.children as ReactElement[]
+ )?.findIndex((e) => e.key === key);
+ setCurrent(childIndex >= 0 ? childIndex : 0);
+ },
+ current,
+ })
+ ).filter(isValidElement) as ReactElement>[];
+
+ RenderComponent = (child?.props?.children as ReactNode[])?.[current];
+ } else {
+ const allElements = Children.toArray(children).filter(isValidElement);
+ RenderComponent = allElements[current] ?? MultiStep error
;
+ }
+
+ return <>{RenderComponent}>;
+};
diff --git a/packages/ui/src/components/popover.tsx b/packages/ui/src/components/popover.tsx
new file mode 100644
index 00000000..1168a550
--- /dev/null
+++ b/packages/ui/src/components/popover.tsx
@@ -0,0 +1,74 @@
+import * as PopoverRadix from "@radix-ui/react-popover";
+import { PropsWithChildren } from "react";
+import { twMerge } from "tailwind-merge";
+import classNames from "classnames";
+
+import { isValidComponent } from "../helpers";
+
+const Close = ({
+ children,
+ asChild,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {asChild ? {children}
: children}
+
+ );
+};
+
+const Trigger = ({
+ children,
+ asChild,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {asChild ? {children}
: children}
+
+ );
+};
+
+const Content = ({
+ children,
+ className,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {children}
+
+ );
+};
+
+const Popover = ({
+ children,
+ ...props
+}: PropsWithChildren) => {
+ const [TriggerComponent] = isValidComponent(children, Trigger);
+ const [ContentComponent] = isValidComponent(children, Content);
+
+ return (
+
+ {TriggerComponent}
+ {ContentComponent}
+
+ );
+};
+
+Popover.Trigger = Trigger;
+Popover.Content = Content;
+Popover.Close = Close;
+
+export { Popover };
diff --git a/packages/ui/src/components/skeleton.tsx b/packages/ui/src/components/skeleton.tsx
new file mode 100644
index 00000000..6371a5df
--- /dev/null
+++ b/packages/ui/src/components/skeleton.tsx
@@ -0,0 +1,27 @@
+import classNames from "classnames";
+import { ComponentProps, Fragment, PropsWithChildren } from "react";
+import { twMerge } from "tailwind-merge";
+// import { twMerge } from "tailwind-merge"; // TODO: Merge is not working
+
+interface SkeletonProps extends ComponentProps<"div"> {
+ loading?: boolean;
+}
+
+export const Skeleton = ({
+ children,
+ loading,
+ className,
+ ...props
+}: PropsWithChildren) => {
+ if (!loading) return {children};
+
+ return (
+
+ );
+};
diff --git a/packages/ui/src/components/spinner.tsx b/packages/ui/src/components/spinner.tsx
new file mode 100644
index 00000000..ecc2f40f
--- /dev/null
+++ b/packages/ui/src/components/spinner.tsx
@@ -0,0 +1,161 @@
+import { ComponentProps } from "react";
+
+const Keyboard = (props: ComponentProps<"svg">) => {
+ return (
+
+ );
+};
+
+const Loading = (props: ComponentProps<"svg">) => (
+
+);
+const Spinner = {
+ Keyboard,
+ Loading,
+};
+
+export { Spinner };
diff --git a/packages/ui/src/components/token.tsx b/packages/ui/src/components/token.tsx
new file mode 100644
index 00000000..13321cce
--- /dev/null
+++ b/packages/ui/src/components/token.tsx
@@ -0,0 +1,16 @@
+import { ComponentProps } from "react";
+
+import * as Tokens from "../tokens";
+
+interface Props extends ComponentProps<"svg"> {
+ name: string;
+}
+export const Token = ({ name, ...props }: Props) => {
+ const tokenUppercase = name.toUpperCase();
+ const tokenTicker = (
+ tokenUppercase in Tokens ? tokenUppercase : "UNKN"
+ ) as keyof typeof Tokens;
+
+ const IconComponent = Tokens[tokenTicker];
+ return ;
+};
diff --git a/packages/ui/src/components/tooltip.tsx b/packages/ui/src/components/tooltip.tsx
new file mode 100644
index 00000000..7d6e7ef5
--- /dev/null
+++ b/packages/ui/src/components/tooltip.tsx
@@ -0,0 +1,66 @@
+import * as TooltipRadix from "@radix-ui/react-tooltip";
+import { PropsWithChildren } from "react";
+import { twMerge } from "tailwind-merge";
+import classNames from "classnames";
+
+import { isValidComponent } from "../helpers";
+
+const Trigger = ({
+ children,
+ asChild,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {asChild ? {children}
: children}
+
+ );
+};
+
+const Content = ({
+ children,
+ className,
+ sideOffset = 12,
+ ...props
+}: PropsWithChildren) => {
+ return (
+
+ {children}
+
+ );
+};
+
+const Tooltip = ({
+ children,
+ delayDuration = 150,
+ ...props
+}: PropsWithChildren) => {
+ const [TriggerComponent] = isValidComponent(children, Trigger);
+ const [ContentComponent] = isValidComponent(children, Content);
+
+ return (
+
+
+ {TriggerComponent}
+ {ContentComponent}
+
+
+ );
+};
+
+Tooltip.Trigger = Trigger;
+Tooltip.Content = Content;
+
+export { Tooltip };
diff --git a/packages/ui/src/components/typography.tsx b/packages/ui/src/components/typography.tsx
new file mode 100644
index 00000000..b5bf4b13
--- /dev/null
+++ b/packages/ui/src/components/typography.tsx
@@ -0,0 +1,135 @@
+import {
+ Children,
+ ComponentProps,
+ ElementType,
+ PropsWithChildren,
+ ReactElement,
+ cloneElement,
+} from "react";
+import classNames from "classnames";
+import { twMerge } from "tailwind-merge";
+
+import { componentIsTypeof } from "../helpers";
+interface TextProps extends ParagraphProps {
+ type?: "span" | "small" | "strong";
+ bold?: boolean;
+}
+
+const Text = ({
+ children,
+ className,
+ variant = "base",
+ size = "sm",
+ type = "span",
+ bold,
+ ...props
+}: PropsWithChildren) => {
+ const ElementRender = type;
+
+ return (
+
+ {children}
+
+ );
+};
+
+interface ParagraphProps extends ComponentProps<"p"> {
+ variant?: keyof typeof paragraphVariants;
+ size?: keyof typeof paragraphSize;
+}
+
+const paragraphVariants = {
+ base: "text-textBase",
+ primary: "text-primary",
+ secondary: "text-secondary",
+};
+
+const paragraphSize = {
+ xs: "text-xs",
+ sm: "text-sm",
+ base: "text-base",
+ md: "text-md",
+ lg: "text-lg",
+ xl: "text-xl",
+};
+
+const Paragraph = ({
+ children,
+ className,
+ variant = "base",
+ size = "md",
+ ...props
+}: PropsWithChildren) => {
+ const isChildrenParagraph = Children.toArray(children).some((child) =>
+ componentIsTypeof(child, "p")
+ );
+ const customClassNames = twMerge(
+ paragraphVariants[variant],
+ paragraphSize[size],
+ classNames("leading-5"),
+ className
+ );
+ if (isChildrenParagraph) {
+ const childElement = Children.only(children) as ReactElement;
+ return cloneElement(childElement, {
+ className: customClassNames,
+ ...props,
+ });
+ }
+ return (
+
+ {children}
+
+ );
+};
+
+interface HeadingProps extends ComponentProps<"h1"> {
+ type?: (typeof headingTypes)[number];
+ size?: keyof typeof headingSizes;
+}
+
+const headingTypes = ["h1", "h2", "h3", "h4", "h5", "h6"] as const;
+const headingSizes = {
+ "2xl": "text-[2rem] leading-[2.25rem]",
+ xl: "text-[1.75rem] leading-[2rem]",
+ lg: "text-[1.5rem] leading-[1.75rem]",
+ md: "text-[1.25rem] leading-[1.5rem]",
+ sm: "text-[1.125rem] leading-[1.75rem]",
+ xs: "text-[1rem] leading-[1.25rem]",
+};
+
+const Heading = ({
+ children,
+ className,
+ type = "h1",
+ size = "xl",
+ ...props
+}: PropsWithChildren) => {
+ const ElementRender = type as ElementType;
+ return (
+
+ {children}
+
+ );
+};
+
+export const Typography = {
+ Paragraph,
+ Text,
+ Heading,
+};
diff --git a/packages/ui/src/helpers/componentIsTypeof.ts b/packages/ui/src/helpers/componentIsTypeof.ts
new file mode 100644
index 00000000..39b6ab53
--- /dev/null
+++ b/packages/ui/src/helpers/componentIsTypeof.ts
@@ -0,0 +1,14 @@
+import { ReactElement, ReactNode, isValidElement } from "react";
+
+export const componentIsTypeof = (
+ child: ReactNode,
+ type: keyof JSX.IntrinsicElements
+) => {
+ if (!isValidElement(child)) return false;
+ const dynamicType =
+ typeof child.type === "function" && (child.type as () => ReactElement)();
+ const isDynamicType =
+ isValidElement(dynamicType) && dynamicType.type === type;
+ const isStringType = typeof child.type === "string" && child.type === type;
+ return isDynamicType || isStringType;
+};
diff --git a/packages/ui/src/helpers/index.ts b/packages/ui/src/helpers/index.ts
new file mode 100644
index 00000000..efa21a41
--- /dev/null
+++ b/packages/ui/src/helpers/index.ts
@@ -0,0 +1,3 @@
+export * from "./isValidComponent";
+export * from "./variants";
+export * from "./componentIsTypeof";
diff --git a/packages/ui/src/helpers/isValidComponent.ts b/packages/ui/src/helpers/isValidComponent.ts
new file mode 100644
index 00000000..9ff7e988
--- /dev/null
+++ b/packages/ui/src/helpers/isValidComponent.ts
@@ -0,0 +1,18 @@
+// TODO:Check Why comparision works but dissaper
+import { Children, ElementType, ReactNode, isValidElement } from "react";
+
+export const isValidComponent = (
+ children: T,
+ targetChild: ElementType
+) => {
+ const target: T[] = [];
+
+ Children.forEach(children, (item) => {
+ if (isValidElement(item) && item.type === targetChild) {
+ target.push(item as T);
+ }
+ return null;
+ });
+
+ return target ?? undefined;
+};
diff --git a/packages/ui/src/helpers/variants.ts b/packages/ui/src/helpers/variants.ts
new file mode 100644
index 00000000..58464040
--- /dev/null
+++ b/packages/ui/src/helpers/variants.ts
@@ -0,0 +1,11 @@
+export const placements = [
+ "center",
+ "center left",
+ "center right",
+ "top center",
+ "top left",
+ "top right",
+ "bottom center",
+ "bottom left",
+ "bottom right",
+] as const;
diff --git a/packages/ui/src/icons/activity.tsx b/packages/ui/src/icons/activity.tsx
new file mode 100644
index 00000000..e49f485c
--- /dev/null
+++ b/packages/ui/src/icons/activity.tsx
@@ -0,0 +1,21 @@
+import { ComponentProps } from "react";
+
+export function Activity(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/ask.tsx b/packages/ui/src/icons/ask.tsx
new file mode 100644
index 00000000..34ad8d52
--- /dev/null
+++ b/packages/ui/src/icons/ask.tsx
@@ -0,0 +1,19 @@
+import { ComponentProps } from "react";
+
+export function Ask(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/askAndBid.tsx b/packages/ui/src/icons/askAndBid.tsx
new file mode 100644
index 00000000..b6f5a809
--- /dev/null
+++ b/packages/ui/src/icons/askAndBid.tsx
@@ -0,0 +1,23 @@
+import { ComponentProps } from "react";
+
+export function AskAndBid(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/avatar.tsx b/packages/ui/src/icons/avatar.tsx
new file mode 100644
index 00000000..e79ce396
--- /dev/null
+++ b/packages/ui/src/icons/avatar.tsx
@@ -0,0 +1,102 @@
+import { ComponentProps } from "react";
+
+export function Avatar(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/balance.tsx b/packages/ui/src/icons/balance.tsx
new file mode 100644
index 00000000..a82b2438
--- /dev/null
+++ b/packages/ui/src/icons/balance.tsx
@@ -0,0 +1,25 @@
+import { ComponentProps } from "react";
+
+export function Balance(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/bid.tsx b/packages/ui/src/icons/bid.tsx
new file mode 100644
index 00000000..90ce071f
--- /dev/null
+++ b/packages/ui/src/icons/bid.tsx
@@ -0,0 +1,19 @@
+import { ComponentProps } from "react";
+
+export function Bid(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/deposit.tsx b/packages/ui/src/icons/deposit.tsx
new file mode 100644
index 00000000..1ff3b790
--- /dev/null
+++ b/packages/ui/src/icons/deposit.tsx
@@ -0,0 +1,15 @@
+import { ComponentProps } from "react";
+
+export function Deposit(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/enkrypt.tsx b/packages/ui/src/icons/enkrypt.tsx
new file mode 100644
index 00000000..b38070dd
--- /dev/null
+++ b/packages/ui/src/icons/enkrypt.tsx
@@ -0,0 +1,33 @@
+import { ComponentProps } from "react";
+
+export function ENKRYPT(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/history.tsx b/packages/ui/src/icons/history.tsx
new file mode 100644
index 00000000..a631fc57
--- /dev/null
+++ b/packages/ui/src/icons/history.tsx
@@ -0,0 +1,24 @@
+import { ComponentProps } from "react";
+
+export function History(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/index.ts b/packages/ui/src/icons/index.ts
new file mode 100644
index 00000000..e076db0e
--- /dev/null
+++ b/packages/ui/src/icons/index.ts
@@ -0,0 +1,17 @@
+export * from "./ask";
+export * from "./bid";
+export * from "./askAndBid";
+export * from "./range";
+export * from "./polkadotjs";
+export * from "./subWallet";
+export * from "./talisman";
+export * from "./wallet";
+export * from "./avatar";
+export * from "./deposit";
+export * from "./withdraw";
+export * from "./history";
+export * from "./transfer";
+export * from "./activity";
+export * from "./balance";
+export * from "./shutdown";
+export * from "./enkrypt";
diff --git a/packages/ui/src/icons/polkadotjs.tsx b/packages/ui/src/icons/polkadotjs.tsx
new file mode 100644
index 00000000..1b564674
--- /dev/null
+++ b/packages/ui/src/icons/polkadotjs.tsx
@@ -0,0 +1,13 @@
+import { ComponentProps } from "react";
+
+export function POLKADOTJS(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/range.tsx b/packages/ui/src/icons/range.tsx
new file mode 100644
index 00000000..5b0ed94d
--- /dev/null
+++ b/packages/ui/src/icons/range.tsx
@@ -0,0 +1,37 @@
+import { ComponentProps } from "react";
+
+export function Range(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/shutdown.tsx b/packages/ui/src/icons/shutdown.tsx
new file mode 100644
index 00000000..4da7be61
--- /dev/null
+++ b/packages/ui/src/icons/shutdown.tsx
@@ -0,0 +1,17 @@
+import { ComponentProps } from "react";
+
+export function Shutdown(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/subWallet.tsx b/packages/ui/src/icons/subWallet.tsx
new file mode 100644
index 00000000..8caa66af
--- /dev/null
+++ b/packages/ui/src/icons/subWallet.tsx
@@ -0,0 +1,13 @@
+import { ComponentProps } from "react";
+
+export function SUBWALLET(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/talisman.tsx b/packages/ui/src/icons/talisman.tsx
new file mode 100644
index 00000000..70937247
--- /dev/null
+++ b/packages/ui/src/icons/talisman.tsx
@@ -0,0 +1,15 @@
+import { ComponentProps } from "react";
+
+export function TALISMAN(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/transfer.tsx b/packages/ui/src/icons/transfer.tsx
new file mode 100644
index 00000000..83834718
--- /dev/null
+++ b/packages/ui/src/icons/transfer.tsx
@@ -0,0 +1,24 @@
+import { ComponentProps } from "react";
+
+export function Transfer(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/wallet.tsx b/packages/ui/src/icons/wallet.tsx
new file mode 100644
index 00000000..a4143fc5
--- /dev/null
+++ b/packages/ui/src/icons/wallet.tsx
@@ -0,0 +1,23 @@
+import { ComponentProps } from "react";
+
+export function Wallet(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/icons/withdraw.tsx b/packages/ui/src/icons/withdraw.tsx
new file mode 100644
index 00000000..ab9bf1f4
--- /dev/null
+++ b/packages/ui/src/icons/withdraw.tsx
@@ -0,0 +1,14 @@
+import { ComponentProps } from "react";
+
+export function Withdraw(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/illustrations/centralizedExchange.tsx b/packages/ui/src/illustrations/centralizedExchange.tsx
new file mode 100644
index 00000000..a1084594
--- /dev/null
+++ b/packages/ui/src/illustrations/centralizedExchange.tsx
@@ -0,0 +1,73 @@
+import { ComponentProps } from "react";
+
+export function CentralizedExchange(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/illustrations/connectAccount.tsx b/packages/ui/src/illustrations/connectAccount.tsx
new file mode 100644
index 00000000..b1d184e4
--- /dev/null
+++ b/packages/ui/src/illustrations/connectAccount.tsx
@@ -0,0 +1,48 @@
+import { ComponentProps } from "react";
+
+export function ConnectAccount(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/illustrations/decentralizedBridge.tsx b/packages/ui/src/illustrations/decentralizedBridge.tsx
new file mode 100644
index 00000000..51ca6a85
--- /dev/null
+++ b/packages/ui/src/illustrations/decentralizedBridge.tsx
@@ -0,0 +1,37 @@
+import { ComponentProps } from "react";
+
+export function DecentralizedBridge(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/illustrations/happy.tsx b/packages/ui/src/illustrations/happy.tsx
new file mode 100644
index 00000000..aeb6a577
--- /dev/null
+++ b/packages/ui/src/illustrations/happy.tsx
@@ -0,0 +1,211 @@
+import { ComponentProps } from "react";
+
+export function Happy(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/illustrations/index.ts b/packages/ui/src/illustrations/index.ts
new file mode 100644
index 00000000..c4a332b6
--- /dev/null
+++ b/packages/ui/src/illustrations/index.ts
@@ -0,0 +1,9 @@
+export * from "./walletNotFound";
+export * from "./insufficientBalance";
+export * from "./centralizedExchange";
+export * from "./decentralizedBridge";
+export * from "./connectAccount";
+export * from "./noData";
+export * from "./noResultFound";
+export * from "./happy";
+export * from "./newUser";
diff --git a/packages/ui/src/illustrations/insufficientBalance.tsx b/packages/ui/src/illustrations/insufficientBalance.tsx
new file mode 100644
index 00000000..aeff0347
--- /dev/null
+++ b/packages/ui/src/illustrations/insufficientBalance.tsx
@@ -0,0 +1,102 @@
+import { ComponentProps } from "react";
+
+export function InsufficientBalance(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/illustrations/newUser.tsx b/packages/ui/src/illustrations/newUser.tsx
new file mode 100644
index 00000000..27b31dc1
--- /dev/null
+++ b/packages/ui/src/illustrations/newUser.tsx
@@ -0,0 +1,364 @@
+import { ComponentProps } from "react";
+
+export function NewUser(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/illustrations/noData.tsx b/packages/ui/src/illustrations/noData.tsx
new file mode 100644
index 00000000..349dff35
--- /dev/null
+++ b/packages/ui/src/illustrations/noData.tsx
@@ -0,0 +1,163 @@
+import { ComponentProps } from "react";
+
+export function NoData(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/illustrations/noResultFound.tsx b/packages/ui/src/illustrations/noResultFound.tsx
new file mode 100644
index 00000000..05c53a9d
--- /dev/null
+++ b/packages/ui/src/illustrations/noResultFound.tsx
@@ -0,0 +1,112 @@
+import { ComponentProps } from "react";
+
+export function NoResultFound(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/illustrations/thea.tsx b/packages/ui/src/illustrations/thea.tsx
new file mode 100644
index 00000000..8d6fda31
--- /dev/null
+++ b/packages/ui/src/illustrations/thea.tsx
@@ -0,0 +1,88 @@
+import { ComponentProps } from "react";
+
+export function Thea(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/illustrations/walletNotFound.tsx b/packages/ui/src/illustrations/walletNotFound.tsx
new file mode 100644
index 00000000..f2192778
--- /dev/null
+++ b/packages/ui/src/illustrations/walletNotFound.tsx
@@ -0,0 +1,90 @@
+import { ComponentProps } from "react";
+
+export function WalletNotFound(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/tokens/astr.tsx b/packages/ui/src/tokens/astr.tsx
new file mode 100755
index 00000000..b42b23e3
--- /dev/null
+++ b/packages/ui/src/tokens/astr.tsx
@@ -0,0 +1,459 @@
+import { ComponentProps } from "react";
+
+export function ASTR(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/tokens/btc.tsx b/packages/ui/src/tokens/btc.tsx
new file mode 100755
index 00000000..4f794df2
--- /dev/null
+++ b/packages/ui/src/tokens/btc.tsx
@@ -0,0 +1,19 @@
+import { ComponentProps } from "react";
+
+export function BTC(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/tokens/dot.tsx b/packages/ui/src/tokens/dot.tsx
new file mode 100644
index 00000000..817a3949
--- /dev/null
+++ b/packages/ui/src/tokens/dot.tsx
@@ -0,0 +1,32 @@
+import { ComponentProps } from "react";
+
+export function DOT(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/tokens/eqb.tsx b/packages/ui/src/tokens/eqb.tsx
new file mode 100755
index 00000000..c9fe6120
--- /dev/null
+++ b/packages/ui/src/tokens/eqb.tsx
@@ -0,0 +1,279 @@
+import { ComponentProps } from "react";
+
+export function EQB(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/tokens/eth.tsx b/packages/ui/src/tokens/eth.tsx
new file mode 100755
index 00000000..76559c2a
--- /dev/null
+++ b/packages/ui/src/tokens/eth.tsx
@@ -0,0 +1,37 @@
+import { ComponentProps } from "react";
+
+export function ETH(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/tokens/glmr.tsx b/packages/ui/src/tokens/glmr.tsx
new file mode 100644
index 00000000..9b8d58ee
--- /dev/null
+++ b/packages/ui/src/tokens/glmr.tsx
@@ -0,0 +1,69 @@
+import { ComponentProps } from "react";
+
+export function GLMR(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/tokens/ibtc.tsx b/packages/ui/src/tokens/ibtc.tsx
new file mode 100755
index 00000000..678b78fc
--- /dev/null
+++ b/packages/ui/src/tokens/ibtc.tsx
@@ -0,0 +1,41 @@
+import { ComponentProps } from "react";
+
+export function IBTC(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/tokens/index.ts b/packages/ui/src/tokens/index.ts
new file mode 100644
index 00000000..c8960116
--- /dev/null
+++ b/packages/ui/src/tokens/index.ts
@@ -0,0 +1,10 @@
+export * from "./btc";
+export * from "./dot";
+export * from "./eth";
+export * from "./pdex";
+export * from "./usdt";
+export * from "./ibtc";
+export * from "./unkn";
+export * from "./glmr";
+export * from "./astr";
+export * from "./eqb";
diff --git a/packages/ui/src/tokens/pdex.tsx b/packages/ui/src/tokens/pdex.tsx
new file mode 100755
index 00000000..617fb4a1
--- /dev/null
+++ b/packages/ui/src/tokens/pdex.tsx
@@ -0,0 +1,38 @@
+import { ComponentProps } from "react";
+
+export function PDEX(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/tokens/unkn.tsx b/packages/ui/src/tokens/unkn.tsx
new file mode 100755
index 00000000..70e8029e
--- /dev/null
+++ b/packages/ui/src/tokens/unkn.tsx
@@ -0,0 +1,31 @@
+import { ComponentProps } from "react";
+
+export function UNKN(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/src/tokens/usdt.tsx b/packages/ui/src/tokens/usdt.tsx
new file mode 100755
index 00000000..2baacc20
--- /dev/null
+++ b/packages/ui/src/tokens/usdt.tsx
@@ -0,0 +1,25 @@
+import { ComponentProps } from "react";
+
+export function USDT(props: ComponentProps<"svg">) {
+ return (
+
+ );
+}
diff --git a/packages/ui/tailwind.config.ts b/packages/ui/tailwind.config.ts
new file mode 100644
index 00000000..2327406b
--- /dev/null
+++ b/packages/ui/tailwind.config.ts
@@ -0,0 +1,7 @@
+import { themeConfig } from "../../themeConfig";
+
+export const config = {
+ ...themeConfig,
+ plugins: [require("tailwindcss-animate")],
+};
+export default config;
diff --git a/packages/ui/turbo/generators/config.ts b/packages/ui/turbo/generators/config.ts
deleted file mode 100644
index f8dc6e87..00000000
--- a/packages/ui/turbo/generators/config.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import type { PlopTypes } from "@turbo/gen";
-
-// Learn more about Turborepo Generators at https://turbo.build/repo/docs/core-concepts/monorepos/code-generation
-
-// eslint-disable-next-line import/no-default-export -- Turbo generators require default export
-export default function generator(plop: PlopTypes.NodePlopAPI): void {
- // A simple generator to add a new React component to the internal UI library
- plop.setGenerator("react-component", {
- description: "Adds a new react component",
- prompts: [
- {
- type: "input",
- name: "name",
- message: "What is the name of the component?",
- },
- ],
- actions: [
- {
- type: "add",
- path: "{{pascalCase name}}.tsx",
- templateFile: "templates/component.hbs",
- },
- {
- type: "append",
- path: "index.tsx",
- pattern: /(?\/\/ component exports)/g,
- template: 'export * from "./{{pascalCase name}}";',
- },
- ],
- });
-}
diff --git a/packages/ui/turbo/generators/templates/component.hbs b/packages/ui/turbo/generators/templates/component.hbs
deleted file mode 100644
index cf7b6369..00000000
--- a/packages/ui/turbo/generators/templates/component.hbs
+++ /dev/null
@@ -1,14 +0,0 @@
-import * as React from "react";
-
-interface Props {
- children?: React.ReactNode;
-}
-
-export const {{ pascalCase name }} = ({ children }: Props) => {
- return (
-
-
{{ name }}
- {children}
-
- );
-};
diff --git a/themeConfig.ts b/themeConfig.ts
new file mode 100644
index 00000000..45bba9ac
--- /dev/null
+++ b/themeConfig.ts
@@ -0,0 +1,119 @@
+export const commom = {
+ "primary-base": "#E6007A",
+ "primary-hover": "#EA268E",
+ "primary-pressed": "#9F005F",
+ "primary-ghost": "#EA268E22",
+ "primary-disabled": "#2B303A",
+ "secondary-base": "#252932",
+ "secondary-hover": "#373E4A",
+ "secondary-pressed": "#2B303A",
+ "danger-base": "#EB5757",
+ "danger-hover": "#EE6D6D",
+ "danger-pressed": "#A41313",
+ "success-base": "#02B671",
+ "success-hover": "#02CA7D",
+ "success-pressed": "#018D58",
+ "attention-base": "#F08205",
+ "attention-hover": "#FA8C0F",
+ "attention-pressed": "#DC7704",
+ "info-base": "#077EED",
+ "info-hover": "#4DA6F9",
+ "info-pressed": "#065FB2",
+};
+
+const commomBg = {
+ "level-0": "#0D0D10",
+ "level-1": "#131419",
+ "level-2": "#252932",
+ "level-3": "#1F2229",
+ "level-4": "#2B303A",
+};
+
+export const themeConfig = {
+ theme: {
+ extend: {
+ backgroundImage: {
+ "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
+ "gradient-conic":
+ "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
+ skeleton: `linear-gradient(
+ -90deg,
+ rgba(255, 255, 255, 0.1) 0%,
+ rgba(255, 255, 255, 0.12) 25%,
+ rgba(255, 255, 255, 0.20) 50%,
+ rgba(255, 255, 255, 0.14) 75%,
+ rgba(255, 255, 255, 0.1) 100%
+ )`,
+ },
+ colors: {
+ ...commom,
+ textBase: "#FFFFFF",
+ primary: "#8B909A",
+ secondary: "#575A60",
+ placeholder: "#FFFFFF7F",
+ actionInput: "#FFFFFF33",
+ disabled: "#2B303A",
+ },
+ backgroundColor: {
+ ...commom,
+ ...commomBg,
+ backgroundBase: "#06070A",
+ "overlay-1": "#0000007F",
+ "overlay-2": "##00000033",
+ "overlay-3": "##000000CC",
+ },
+ backgroundSize: {
+ skeletonSize: "400% 400%",
+ },
+ fill: {
+ ...commom,
+ ...commomBg,
+ },
+ boxShadow: {
+ baseShadow: "0px 20px 23px rgba(0, 0, 0, 0.05)",
+ },
+ borderColor: {
+ ...commom,
+ ...commomBg,
+ primary: "#1F2229",
+ secondary: "#2B303A",
+ },
+ backdropBlur: {
+ primary: "5px",
+ secondary: "40px",
+ },
+ maxWidth: {
+ "8xl": "90rem",
+ },
+ fontSize: {
+ heading: "0.95rem",
+ md: "0.9rem",
+ base: "0.80rem",
+ },
+ animation: {
+ infiniteHorizontalScroll: "30s linear infinite infiniteHorizontal ",
+ skeletonAnimation:
+ "skeletonPulse 2s cubic-bezier(0.2, 0.8, 0.2, 1) infinite",
+ },
+ keyframes: {
+ infiniteHorizontal: {
+ "0%": {
+ transform: "translate3d(0px, 0px, 0px)",
+ },
+ "100%": {
+ transform: "translate3d(-50%, 0px, 0px)",
+ },
+ },
+ skeletonPulse: {
+ "0%": {
+ backgroundPosition: "0% 0%",
+ },
+ "100%": {
+ backgroundPosition: "-135% 0%",
+ },
+ },
+ },
+ },
+ },
+ plugins: [],
+};