Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[KEPLR-503] Add Reject bottom button on user interaction required page #1232

Merged
merged 8 commits into from
Nov 11, 2024
3 changes: 0 additions & 3 deletions apps/extension/src/components/button/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,5 @@ export const Styles = {
align-items: center;

position: absolute;
svg {
fill: none;
}
`,
};
1 change: 1 addition & 0 deletions apps/extension/src/components/icon/check.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const CheckIcon: FunctionComponent<IconProps> = ({
strokeWidth="2.5"
strokeLinecap="round"
strokeLinejoin="round"
fill="none"
/>
</svg>
);
Expand Down
3 changes: 3 additions & 0 deletions apps/extension/src/components/special-button/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ export const Styles = {
display: flex;
align-items: center;
margin-right: 0.25rem;
svg {
fill: ${ColorPalette["transparent"]};
}
`,
Right: styled.span`
height: 100%;
Expand Down
24 changes: 17 additions & 7 deletions apps/extension/src/hooks/interaction.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
import { useEffect, useMemo, useRef } from "react";
import { useSearchParams } from "react-router-dom";

export const useInteractionInfo = (cleanUp?: () => void) => {
export const useInteractionInfo = ({
onUnmount,
onWindowClose,
}: {
onUnmount?: () => void;
onWindowClose?: () => void;
}) => {
const [searchParams] = useSearchParams();

const cleanUpRef = useRef<(() => void) | undefined>(cleanUp);
cleanUpRef.current = cleanUp;
const onUnmountRef = useRef<(() => void) | undefined>(onUnmount);
onUnmountRef.current = onUnmount;

const onWindowCloseRef = useRef<(() => void) | undefined>(onWindowClose);
onWindowCloseRef.current = onWindowClose;

const result = {
interaction: searchParams.get("interaction") === "true",
interactionInternal: searchParams.get("interactionInternal") === "true",
};

useEffect(() => {
// Execute the clean-up function when unmounting.
return () => {
if (cleanUpRef.current) {
cleanUpRef.current();
if (onUnmountRef.current) {
onUnmountRef.current();
}
};
}, []);

useEffect(() => {
// Execute the clean-up function when closing window.
const beforeunload = async () => {
if (cleanUpRef.current) {
cleanUpRef.current();
if (onWindowCloseRef.current) {
onWindowCloseRef.current();
}
};

Expand Down
77 changes: 41 additions & 36 deletions apps/extension/src/layouts/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ import { HeaderProps } from "./types";
import { Subtitle1 } from "../../components/typography";
import { ColorPalette } from "../../styles";
import { Box } from "../../components/box";
import { Button, getButtonHeightRem } from "../../components/button";
import {
Button,
ButtonProps,
getButtonHeightRem,
} from "../../components/button";
import { Skeleton } from "../../components/skeleton";
import {
SpecialButton,
SpecialButtonProps,
getSpecialButtonHeightRem,
} from "../../components/special-button";

Expand Down Expand Up @@ -182,7 +187,7 @@ export const HeaderLayout: FunctionComponent<
title,
left,
right,
bottomButton,
bottomButtons,
displayFlex,
fixedHeight,
fixedMinHeight,
Expand All @@ -197,6 +202,9 @@ export const HeaderLayout: FunctionComponent<
const [height, setHeight] = React.useState(() => pxToRem(600));
const lastSetHeight = useRef(-1);

const hasBottomButton = bottomButtons && bottomButtons.length > 0;
const hasMultipleBottomButton = bottomButtons && bottomButtons.length > 1;

useLayoutEffect(() => {
function handleResize() {
if (window.visualViewport) {
Expand All @@ -217,22 +225,37 @@ export const HeaderLayout: FunctionComponent<
}, []);

const bottomPadding = (() => {
if (!bottomButton) {
if (!hasBottomButton) {
return "0";
}

if (bottomButton.isSpecial) {
return (
bottomButtonPaddingRem * 2 +
getSpecialButtonHeightRem(bottomButton.size) +
"rem"
);
const buttonHeights = bottomButtons.map((button) => {
return button.isSpecial
? getSpecialButtonHeightRem(button.size)
: getButtonHeightRem(button.size);
});

const maxButtonHeightRem = Math.max(...buttonHeights);

return `${bottomButtonPaddingRem * 2 + maxButtonHeightRem}rem`;
})();

const renderButton = (
button:
| ({ isSpecial?: false } & ButtonProps)
| ({ isSpecial: true } & SpecialButtonProps),
index: number
) => {
if (button.isSpecial) {
return <SpecialButton key={index} {...button} />;
}

return (
bottomButtonPaddingRem * 2 + getButtonHeightRem(bottomButton.size) + "rem"
<Skeleton isNotReady={isNotReady} type="button" key={index}>
<Button {...button} />
</Skeleton>
);
})();
};

return (
<Styles.Container as={onSubmit ? "form" : undefined} onSubmit={onSubmit}>
Expand Down Expand Up @@ -277,14 +300,19 @@ export const HeaderLayout: FunctionComponent<
{children}
</Styles.ContentContainer>

{bottomButton ? (
{hasBottomButton ? (
<Box
padding={bottomButtonPaddingRem + "rem"}
position="fixed"
style={{
left: 0,
right: 0,
bottom: additionalPaddingBottom || "0",
display: hasMultipleBottomButton ? "grid" : undefined,
gridTemplateColumns: hasMultipleBottomButton
? `${"auto ".repeat(bottomButtons.length - 1)}1fr` // 마지막 버튼이 남은 공간을 다 채우도록 함
: undefined,
gap: hasMultipleBottomButton ? "0.75rem" : undefined,
}}
>
{/*
Expand All @@ -304,30 +332,7 @@ export const HeaderLayout: FunctionComponent<
}}
/>
) : null}
{(() => {
if (bottomButton.isSpecial) {
// isSpecial is not used.
const { isSpecial, ...other } = bottomButton;
return <SpecialButton {...other} />;
} else {
// isSpecial is not used.
const { isSpecial, type, ...other } = bottomButton;

// onSubmit prop이 존재한다면 기본적으로 type="submit"으로 설정한다
// TODO: 만약에 bottomButton이 배열을 받을 수 있도록 수정된다면 이 부분도 수정되어야함.

const props = {
...other,
type: type || onSubmit ? ("submit" as const) : undefined,
};

return (
<Skeleton isNotReady={isNotReady} type="button">
<Button {...props} />
</Skeleton>
);
}
})()}
{bottomButtons.map(renderButton)}
</Box>
) : null}
</Styles.Container>
Expand Down
6 changes: 3 additions & 3 deletions apps/extension/src/layouts/header/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ export interface HeaderProps {
left?: ReactNode;
right?: ReactNode;

// TODO: 나중에 아래 버튼이 여러개 필요해지면 배열로 만들자...
bottomButton?:
bottomButtons?: (
| ({ isSpecial?: false } & ButtonProps)
| ({ isSpecial: true } & SpecialButtonProps);
| ({ isSpecial: true } & SpecialButtonProps)
)[];

displayFlex?: boolean;
fixedHeight?: boolean;
Expand Down
Loading
Loading