Merge pull request #39 from exstake/add-input-and-button-components
Add input and button components
This commit is contained in:
42
app/javascript/src/components/Button/Button.tsx
Normal file
42
app/javascript/src/components/Button/Button.tsx
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import type { MouseEvent } from "react";
|
||||||
|
import React from "react";
|
||||||
|
import cn from "classnames";
|
||||||
|
|
||||||
|
type Props = React.DetailedHTMLProps<
|
||||||
|
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
||||||
|
HTMLButtonElement
|
||||||
|
> & {
|
||||||
|
variant?: "primary" | "dangeour";
|
||||||
|
};
|
||||||
|
|
||||||
|
const baseStyles =
|
||||||
|
"cursor-pointer py-2 px-4 disabled:opacity-50 disabled:cursor-default text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg";
|
||||||
|
|
||||||
|
const Component: React.ForwardRefRenderFunction<unknown, Props> = (props) => {
|
||||||
|
const { className = "", variant = "primary", onClick, ...rest } = props;
|
||||||
|
|
||||||
|
const handleClick = (
|
||||||
|
e: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>
|
||||||
|
) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
if (onClick) {
|
||||||
|
onClick(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const variantStyle =
|
||||||
|
variant === "primary"
|
||||||
|
? "bg-blue-600 hover:bg-blue-700 focus:ring-blue-500 focus:ring-offset-blue-200"
|
||||||
|
: "bg-red-600 hover:bg-red-700 focus:ring-red-500 focus:ring-offset-red-200";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
{...rest}
|
||||||
|
className={cn(baseStyles, className, variantStyle)}
|
||||||
|
onClick={(e) => handleClick(e)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Button = React.forwardRef<unknown, Props>(Component);
|
||||||
1
app/javascript/src/components/Button/index.ts
Normal file
1
app/javascript/src/components/Button/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from "./Button";
|
||||||
30
app/javascript/src/components/Input/Input.tsx
Normal file
30
app/javascript/src/components/Input/Input.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import type { ChangeEvent } from "react";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
type Props = React.DetailedHTMLProps<
|
||||||
|
React.InputHTMLAttributes<HTMLInputElement>,
|
||||||
|
HTMLInputElement
|
||||||
|
>;
|
||||||
|
|
||||||
|
const baseStyles =
|
||||||
|
"rounded-lg border-transparent flex-1 appearance-none border border-gray-300 w-full py-2 px-4 bg-white text-gray-700 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:ring-blue-600 focus:border-transparent mb-3";
|
||||||
|
|
||||||
|
const Component: React.ForwardRefRenderFunction<unknown, Props> = (props) => {
|
||||||
|
const { className = "", onChange, ...rest } = props;
|
||||||
|
|
||||||
|
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (!onChange) return;
|
||||||
|
|
||||||
|
onChange(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<input
|
||||||
|
{...rest}
|
||||||
|
className={`${baseStyles} ${className}`}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Input = React.forwardRef<unknown, Props>(Component);
|
||||||
1
app/javascript/src/components/Input/index.ts
Normal file
1
app/javascript/src/components/Input/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from "./Input";
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
export * from "./Navbar";
|
export * from "./Navbar";
|
||||||
export * from "./SideNav";
|
export * from "./SideNav";
|
||||||
export * from "./Modal";
|
export * from "./Modal";
|
||||||
|
export * from "./Input";
|
||||||
|
export * from "./Button";
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
import BigNumber from "bignumber.js";
|
import BigNumber from "bignumber.js";
|
||||||
import type { ChangeEvent, FC } from "react";
|
import type { ChangeEvent, FC } from "react";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import cx from "classnames";
|
|
||||||
import { useRelayEnvironment } from "react-relay";
|
import { useRelayEnvironment } from "react-relay";
|
||||||
|
|
||||||
import { Modal } from "../../../../components";
|
import { Button, Modal, Input } from "../../../../components";
|
||||||
import { commitCreateStakeRemoveOrderMutation } from "./commitCreateStakeRemoveOrder";
|
import { commitCreateStakeRemoveOrderMutation } from "./commitCreateStakeRemoveOrder";
|
||||||
|
|
||||||
const inputBaseStyles =
|
|
||||||
"rounded-lg border-transparent flex-1 appearance-none border border-gray-300 w-full py-2 px-4 bg-white text-gray-700 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:ring-blue-600 focus:border-transparent mb-3";
|
|
||||||
|
|
||||||
type RemoveStakeModal = {
|
type RemoveStakeModal = {
|
||||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@@ -72,8 +68,7 @@ export const RemoveStakeModal: FC<RemoveStakeModal> = ({
|
|||||||
<span className="mb-2">CAKE disponível: {stakedCake}</span>
|
<span className="mb-2">CAKE disponível: {stakedCake}</span>
|
||||||
<form onSubmit={onSubmit} className="bg-white py-2">
|
<form onSubmit={onSubmit} className="bg-white py-2">
|
||||||
<div className="flex flex-row">
|
<div className="flex flex-row">
|
||||||
<input
|
<Input
|
||||||
className={cx(inputBaseStyles)}
|
|
||||||
type="number"
|
type="number"
|
||||||
value={amountInput}
|
value={amountInput}
|
||||||
onChange={handleInvestInput}
|
onChange={handleInvestInput}
|
||||||
@@ -90,13 +85,9 @@ export const RemoveStakeModal: FC<RemoveStakeModal> = ({
|
|||||||
{avaliableCake.isEqualTo(0) && (
|
{avaliableCake.isEqualTo(0) && (
|
||||||
<span className="text-red-500 mb-1">Você não possuí saldo.</span>
|
<span className="text-red-500 mb-1">Você não possuí saldo.</span>
|
||||||
)}
|
)}
|
||||||
<button
|
<Button variant="dangeour" disabled={!stakeAvaliable} type="submit">
|
||||||
className="cursor-pointer py-2 px-4 disabled:opacity-50 disabled:cursor-default bg-red-600 hover:bg-red-700 focus:ring-red-500 focus:ring-offset-red-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg"
|
|
||||||
disabled={!stakeAvaliable}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Remover Stake
|
Remover Stake
|
||||||
</button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
import type { ChangeEvent, FC } from "react";
|
import type { ChangeEvent, FC } from "react";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import cx from "classnames";
|
|
||||||
import { BigNumber } from "bignumber.js";
|
import { BigNumber } from "bignumber.js";
|
||||||
import { useRelayEnvironment } from "react-relay";
|
import { useRelayEnvironment } from "react-relay";
|
||||||
|
|
||||||
import { Modal } from "../../../components";
|
import { Button, Modal } from "../../../components";
|
||||||
import { commitCreateStakeOrderMutation } from "./createStakeOrder";
|
import { commitCreateStakeOrderMutation } from "./createStakeOrder";
|
||||||
|
import { Input } from "../../../components/Input/Input";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
poolName: string;
|
poolName: string;
|
||||||
balance: string;
|
balance: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const inputBaseStyles =
|
|
||||||
"rounded-lg border-transparent flex-1 appearance-none border border-gray-300 w-full py-2 px-4 bg-white text-gray-700 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:ring-blue-600 focus:border-transparent mb-3";
|
|
||||||
|
|
||||||
export const StakeOrderModal: FC<Props> = ({ poolName, balance }) => {
|
export const StakeOrderModal: FC<Props> = ({ poolName, balance }) => {
|
||||||
const environment = useRelayEnvironment();
|
const environment = useRelayEnvironment();
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
@@ -72,8 +69,7 @@ export const StakeOrderModal: FC<Props> = ({ poolName, balance }) => {
|
|||||||
<span className="mb-2">CAKE disponível: {balance}</span>
|
<span className="mb-2">CAKE disponível: {balance}</span>
|
||||||
<form onSubmit={onSubmit} className="bg-white py-2">
|
<form onSubmit={onSubmit} className="bg-white py-2">
|
||||||
<div className="flex flex-row">
|
<div className="flex flex-row">
|
||||||
<input
|
<Input
|
||||||
className={cx(inputBaseStyles)}
|
|
||||||
type="number"
|
type="number"
|
||||||
value={investAmountInput}
|
value={investAmountInput}
|
||||||
onChange={handleInvestInput}
|
onChange={handleInvestInput}
|
||||||
@@ -90,13 +86,9 @@ export const StakeOrderModal: FC<Props> = ({ poolName, balance }) => {
|
|||||||
{avaliableCake.isEqualTo(0) && (
|
{avaliableCake.isEqualTo(0) && (
|
||||||
<span className="text-red-500 mb-1">Você não possuí saldo.</span>
|
<span className="text-red-500 mb-1">Você não possuí saldo.</span>
|
||||||
)}
|
)}
|
||||||
<button
|
<Button disabled={!stakeAvaliable} type="submit">
|
||||||
className="cursor-pointer py-2 px-4 disabled:opacity-50 disabled:cursor-default bg-blue-600 hover:bg-blue-700 focus:ring-blue-500 focus:ring-offset-blue-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg"
|
|
||||||
disabled={!stakeAvaliable}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Fazer Stake
|
Fazer Stake
|
||||||
</button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import type { ExchangePanel_fiatBalances$key } from "./__generated__/ExchangePan
|
|||||||
import type { ExchangePanel_balances$key } from "./__generated__/ExchangePanel_balances.graphql";
|
import type { ExchangePanel_balances$key } from "./__generated__/ExchangePanel_balances.graphql";
|
||||||
import { commitCreateSellCryptoOrderMutation } from "./createSellCryptoOrder";
|
import { commitCreateSellCryptoOrderMutation } from "./createSellCryptoOrder";
|
||||||
import { commitCreateBuyCryptoOrderMutation } from "./createBuyCryptoOrder";
|
import { commitCreateBuyCryptoOrderMutation } from "./createBuyCryptoOrder";
|
||||||
|
import { Input, Button } from "../../../../components";
|
||||||
|
|
||||||
const tabBaseStyles =
|
const tabBaseStyles =
|
||||||
"w-full text-base font-bold text-black px-4 py-2 focus:ring-blue-500";
|
"w-full text-base font-bold text-black px-4 py-2 focus:ring-blue-500";
|
||||||
@@ -18,9 +19,6 @@ const tabBaseStyles =
|
|||||||
const selectedTabStyles =
|
const selectedTabStyles =
|
||||||
"bg-blue-600 hover:bg-blue-700 rounded-l-frounded-full text-white";
|
"bg-blue-600 hover:bg-blue-700 rounded-l-frounded-full text-white";
|
||||||
|
|
||||||
const inputBaseStyles =
|
|
||||||
"rounded-lg border-transparent flex-1 appearance-none border border-gray-300 w-full py-2 px-4 bg-white text-gray-700 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:ring-blue-600 focus:border-transparent mb-3";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
fiatBalancesRefs: ExchangePanel_fiatBalances$key;
|
fiatBalancesRefs: ExchangePanel_fiatBalances$key;
|
||||||
balancesRefs: ExchangePanel_balances$key;
|
balancesRefs: ExchangePanel_balances$key;
|
||||||
@@ -161,8 +159,7 @@ export const ExchangePanel: FC<Props> = ({
|
|||||||
<div className="flex flex-row">
|
<div className="flex flex-row">
|
||||||
{exchangeOption === "BUY" ? (
|
{exchangeOption === "BUY" ? (
|
||||||
<>
|
<>
|
||||||
<input
|
<Input
|
||||||
className={cx(inputBaseStyles)}
|
|
||||||
type="number"
|
type="number"
|
||||||
value={fiatDock}
|
value={fiatDock}
|
||||||
onChange={handleFiatAmountChange}
|
onChange={handleFiatAmountChange}
|
||||||
@@ -178,8 +175,7 @@ export const ExchangePanel: FC<Props> = ({
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<input
|
<Input
|
||||||
className={cx(inputBaseStyles)}
|
|
||||||
type="number"
|
type="number"
|
||||||
value={cryptoDock}
|
value={cryptoDock}
|
||||||
onChange={handleCryptoAmountChange}
|
onChange={handleCryptoAmountChange}
|
||||||
@@ -196,13 +192,13 @@ export const ExchangePanel: FC<Props> = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<Button
|
||||||
className="cursor-pointer py-2 px-4 disabled:opacity-50 disabled:cursor-default bg-blue-600 hover:bg-blue-700 focus:ring-blue-500 focus:ring-offset-blue-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg"
|
className="cursor-pointer py-2 px-4 disabled:opacity-50 disabled:cursor-default bg-blue-600 hover:bg-blue-700 focus:ring-blue-500 focus:ring-offset-blue-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg"
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={submitDisabled}
|
disabled={submitDisabled}
|
||||||
>
|
>
|
||||||
{exchangeOption === "BUY" ? "Comprar" : "Vender"} CAKE
|
{exchangeOption === "BUY" ? "Comprar" : "Vender"} CAKE
|
||||||
</button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user