Skip to content

Commit

Permalink
feat: update input styles (#975)
Browse files Browse the repository at this point in the history
* feat: update input styles

- [x] Update input styles for the application
- [x] Add manual import for identity

* fix: add missing exports

---------

Co-authored-by: 0xmad <0xmad@users.noreply.github.com>
  • Loading branch information
0xmad and 0xmad authored Oct 10, 2023
1 parent 4be9117 commit 591a345
Show file tree
Hide file tree
Showing 28 changed files with 644 additions and 335 deletions.
5 changes: 5 additions & 0 deletions packages/app/src/config/mock/zk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ export const defaultMerkleProof: IMerkleProof = {

export const mockDefaultIdentityCommitment = "219ea1ec38a6fffb63e2a591fec619fe9dc850d345f6d4d8823a4f72a6f729a6";

export const mockDefaultIdentitySecret =
"18581243383539966831792047417781846056480615829070187698258804610596815513832";

export const mockDefaultIdentitySecretHex = "0x29149c6e74dad2c21c8405b4c7d415f26cbadce0fba1b8a58ce1247623bc28e8";

export const mockDefaultIdentity: IIdentityData & { secret?: string } = {
commitment: mockDefaultIdentityCommitment,
secret: "1234",
Expand Down
67 changes: 67 additions & 0 deletions packages/app/src/ui/components/BigNumberInput/BigNumberInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import Box from "@mui/material/Box";
import InputAdornment from "@mui/material/InputAdornment";
import Tooltip from "@mui/material/Tooltip";
import Typography from "@mui/material/Typography";
import { bigintToHex } from "bigint-conversion";
import omit from "lodash/omit";
import { forwardRef, type Ref } from "react";

import { ellipsify } from "@src/util/account";

import type { TextFieldProps } from "@mui/material/TextField";

import { Input } from "../Input";

import { useBigNumberInput } from "./useBigNumberInput";

export interface IBigNumberInputProps extends TextFieldProps<"filled"> {
label: string;
errorMessage?: string;
}

const BigNumberInputUI = (
{
id,
label,
value,
onBlur: onBlurHandler = undefined,
onFocus: onFocusHandler = undefined,
...rest
}: IBigNumberInputProps,
inputRef: Ref<HTMLInputElement | HTMLDivElement>,
): JSX.Element => {
const { isFocused, isInitialized, isHex, onBlur, onFocus, onToggleHex } = useBigNumberInput({
onBlurHandler,
onFocusHandler,
});
const formattedValue = isHex && typeof value === "string" ? bigintToHex(BigInt(value)) : (value as string);

return (
<Box>
<Tooltip title={!isFocused ? formattedValue : ""}>
<Input
id={id}
inputRef={isInitialized ? inputRef : undefined}
label={label}
value={!isFocused ? ellipsify(formattedValue) : formattedValue}
onBlur={onBlur}
onFocus={onFocus}
{...omit(rest, ["ref"])}
InputProps={{
...rest.InputProps,
readOnly: isHex || rest.InputProps?.readOnly,
endAdornment: (
<InputAdornment position="end">
<Typography color="primary.main" sx={{ cursor: "pointer" }} onClick={onToggleHex}>
{isHex ? "Dec" : "Hex"}
</Typography>
</InputAdornment>
),
}}
/>
</Tooltip>
</Box>
);
};

export const BigNumberInput = forwardRef<HTMLInputElement | HTMLDivElement, IBigNumberInputProps>(BigNumberInputUI);
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* @jest-environment jsdom
*/

import { render } from "@testing-library/react";
import { bigintToHex } from "bigint-conversion";

import { mockDefaultIdentitySecret, mockDefaultIdentitySecretHex } from "@src/config/mock/zk";
import { ellipsify } from "@src/util/account";

import { IBigNumberInputProps, BigNumberInput } from "../BigNumberInput";
import { IUseBigNumberInputData, useBigNumberInput } from "../useBigNumberInput";

jest.mock("bigint-conversion", (): unknown => ({
bigintToHex: jest.fn(),
}));

jest.mock("../useBigNumberInput", (): unknown => ({
useBigNumberInput: jest.fn(),
}));

describe("ui/components/BigNumberInput", () => {
const defaultProps: IBigNumberInputProps = {
label: "Label",
value: mockDefaultIdentitySecret,
variant: "filled",
};

const defaultHookData: IUseBigNumberInputData = {
isFocused: false,
isInitialized: true,
isHex: false,
onBlur: jest.fn(),
onFocus: jest.fn(),
onToggleHex: jest.fn(),
};

beforeEach(() => {
(bigintToHex as jest.Mock).mockReturnValue(mockDefaultIdentitySecretHex);

(useBigNumberInput as jest.Mock).mockReturnValue(defaultHookData);
});

afterEach(() => {
jest.clearAllMocks();
});

test("should render focused state properly", async () => {
(useBigNumberInput as jest.Mock).mockReturnValue({ ...defaultHookData, isFocused: true, isInitialized: false });

const { findByText, findByDisplayValue } = render(<BigNumberInput {...defaultProps} />);

const label = await findByText(defaultProps.label);
const hex = await findByText("Hex");
const value = await findByDisplayValue(mockDefaultIdentitySecret);

expect(label).toBeInTheDocument();
expect(hex).toBeInTheDocument();
expect(value).toBeInTheDocument();
});

test("should render dec properly", async () => {
const { findByText, findByDisplayValue } = render(<BigNumberInput {...defaultProps} />);

const label = await findByText(defaultProps.label);
const hex = await findByText("Hex");
const value = await findByDisplayValue(ellipsify(mockDefaultIdentitySecret));

expect(label).toBeInTheDocument();
expect(hex).toBeInTheDocument();
expect(value).toBeInTheDocument();
});

test("should render hex properly", async () => {
(useBigNumberInput as jest.Mock).mockReturnValue({ ...defaultHookData, isHex: true });

const { findByText, findByDisplayValue } = render(<BigNumberInput {...defaultProps} />);

const label = await findByText(defaultProps.label);
const hex = await findByText("Dec");
const value = await findByDisplayValue(ellipsify(mockDefaultIdentitySecretHex));

expect(label).toBeInTheDocument();
expect(hex).toBeInTheDocument();
expect(value).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @jest-environment jsdom
*/

import { act, renderHook, waitFor } from "@testing-library/react";
import { type FocusEvent as ReactFocusEvent } from "react";

import { IUseBigNumberInputArgs, useBigNumberInput } from "../useBigNumberInput";

describe("ui/components/BigNumberInput/useBigNumberInput", () => {
const defaultArgs: IUseBigNumberInputArgs = {
onBlurHandler: jest.fn(),
onFocusHandler: jest.fn(),
};

afterEach(() => {
jest.clearAllMocks();
});

test("should return initial data", async () => {
const { result } = renderHook(() => useBigNumberInput(defaultArgs));
await waitFor(() => result.current.isInitialized);

expect(result.current.isFocused).toBe(false);
expect(result.current.isHex).toBe(false);
});

test("should toogle dec/hex value properly", async () => {
const { result } = renderHook(() => useBigNumberInput(defaultArgs));
await waitFor(() => result.current.isInitialized);

act(() => result.current.onToggleHex());

expect(result.current.isHex).toBe(true);
});

test("should toogle focus value properly", async () => {
const { result } = renderHook(() => useBigNumberInput(defaultArgs));
await waitFor(() => result.current.isInitialized);

act(() => result.current.onFocus({} as ReactFocusEvent<HTMLInputElement | HTMLTextAreaElement>));
expect(result.current.isFocused).toBe(true);

act(() => result.current.onBlur({} as ReactFocusEvent<HTMLInputElement | HTMLTextAreaElement>));
expect(result.current.isFocused).toBe(false);
});
});
1 change: 1 addition & 0 deletions packages/app/src/ui/components/BigNumberInput/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { BigNumberInput } from "./BigNumberInput";
59 changes: 59 additions & 0 deletions packages/app/src/ui/components/BigNumberInput/useBigNumberInput.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useCallback, useState, type FocusEvent as ReactFocusEvent, useEffect } from "react";

type FocusEventType = ReactFocusEvent<HTMLInputElement | HTMLTextAreaElement>;

export interface IUseBigNumberInputArgs {
onBlurHandler?: (event: FocusEventType) => void;
onFocusHandler?: (event: FocusEventType) => void;
}

export interface IUseBigNumberInputData {
isFocused: boolean;
isInitialized: boolean;
isHex: boolean;
onBlur: (event: FocusEventType) => void;
onFocus: (event: FocusEventType) => void;
onToggleHex: () => void;
}

export const useBigNumberInput = ({
onBlurHandler,
onFocusHandler,
}: IUseBigNumberInputArgs): IUseBigNumberInputData => {
const [isInitialized, setIsInitialized] = useState(false);
const [isHex, setIsHex] = useState(false);
const [isFocused, setIsFocused] = useState(false);

const onFocus = useCallback(
(event: FocusEventType) => {
setIsFocused(true);
onFocusHandler?.(event);
},
[setIsFocused, onFocusHandler],
);

const onBlur = useCallback(
(event: FocusEventType) => {
setIsFocused(false);
onBlurHandler?.(event);
},
[setIsFocused, onBlurHandler],
);

const onToggleHex = useCallback(() => {
setIsHex((value) => !value);
}, [setIsHex]);

useEffect(() => {
setIsInitialized(true);
}, [setIsInitialized]);

return {
isFocused,
isInitialized,
isHex,
onBlur,
onFocus,
onToggleHex,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,34 @@ export const RlnProofModal = ({
className="w-full mb-2"
defaultValue={payload?.rlnIdentifier.toString()}
label="Rln Identifier"
variant="filled"
/>

<Input readOnly className="w-full mb-2" defaultValue={payload?.message} label="Message" />
<Input readOnly className="w-full mb-2" defaultValue={payload?.message} label="Message" variant="filled" />

<Input readOnly className="w-full mb-2" defaultValue={payload?.messageId.toString()} label="Message Id" />
<Input
readOnly
className="w-full mb-2"
defaultValue={payload?.messageId.toString()}
label="Message Id"
variant="filled"
/>

<Input readOnly className="w-full mb-2" defaultValue={payload?.messageLimit.toString()} label="Message Limit" />
<Input
readOnly
className="w-full mb-2"
defaultValue={payload?.messageLimit.toString()}
label="Message Limit"
variant="filled"
/>

<Input readOnly className="w-full mb-2" defaultValue={payload?.epoch.toString()} label="Epoch" />
<Input
readOnly
className="w-full mb-2"
defaultValue={payload?.epoch.toString()}
label="Epoch"
variant="filled"
/>
</FullModalContent>

{error && <div className="text-xs text-red-500 text-center pb-1">{error}</div>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,15 @@ export const SemaphoreProofModal = ({
</div>
</div>

<Input readOnly className="w-full mb-2" defaultValue={payload?.externalNullifier} label="External Nullifier" />

<Input readOnly className="w-full mb-2" defaultValue={payload?.signal} label="Signal" />
<Input
readOnly
className="w-full mb-2"
defaultValue={payload?.externalNullifier}
label="External Nullifier"
variant="filled"
/>

<Input readOnly className="w-full mb-2" defaultValue={payload?.signal} label="Signal" variant="filled" />
</FullModalContent>

{error && <div className="text-xs text-red-500 text-center pb-1">{error}</div>}
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/ui/components/IdentityList/Item/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export const IdentityItem = ({
id="identityRename"
label=""
type="text"
variant="filled"
{...register("name", { required: "Name is required" })}
/>

Expand Down
Loading

0 comments on commit 591a345

Please sign in to comment.