Skip to content

Commit

Permalink
Merge pull request #33 from Nexters/style/ticker-input
Browse files Browse the repository at this point in the history
style: apply design qa on ticker-input page
  • Loading branch information
JinleeJeong authored Feb 27, 2024
2 parents 49ba1ea + e40ee62 commit f1ffb65
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/app/(main)/stock/[id]/_components/stock-drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface StockInfoDrawerProps {

export const StockInfoDrawer = React.memo(({ handleInfoClick }: StockInfoDrawerProps) => {
return (
<DrawerContent className="mx-auto max-w-[--max-width] ">
<DrawerContent className="mx-auto max-w-screen-md">
<DrawerHeader>
<DrawerTitle className="mb-6 flex flex-col">
<p className=" text-h3 font-semibold text-grey-900">{"Latest Price"}</p>
Expand Down
2 changes: 1 addition & 1 deletion src/app/(main)/ticker/_components/intro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Intro = () => {
const { stocks } = useStocksStore();
const hasStock = stocks.length > 0;
return (
<div className={`${hasStock && "border-b border-b-grey-100"} px-4`}>
<div className={`${hasStock && "border-b border-b-grey-100"} sticky top-0 w-full bg-white px-4`}>
<h2 className="pt-4 text-h2">
You added <span className="text-main-700">{stocks.length}</span> {`${hasStock ? "stocks" : "stock"}`}.
</h2>
Expand Down
22 changes: 21 additions & 1 deletion src/app/(main)/ticker/_components/ticker-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@ const TickerContent = React.memo(() => {
isDrawerOpenChange(false);
}, [editStock, isDrawerOpenChange, resetData, selectedStock, tickerCount]);

const handleOverlayClick = React.useCallback(() => {
isDrawerOpenChange(false);

if (drawerType === "edit") {
resetData();
}
}, [drawerType, isDrawerOpenChange, resetData]);

React.useEffect(() => {
// 컴포넌트가 마운트될 때 body 스타일 변경
document.body.style.setProperty("margin", "auto", "important");
document.body.style.setProperty("padding", "0");

// 컴포넌트가 언마운트될 때 body 스타일 복원
return () => {
document.body.style.removeProperty("margin");
document.body.style.removeProperty("padding");
};
}, []);

return (
<DrawerPrimitive
open={isDrawerOpen}
Expand All @@ -125,7 +145,7 @@ const TickerContent = React.memo(() => {
<Intro />
<TickerList data={stocks} hasShares onClick={handleSelectedTickerClick} />
</div>
<DrawerOverlay onClick={() => isDrawerOpenChange(false)} />
<DrawerOverlay onClick={handleOverlayClick} />
<TickerDrawer
drawerType={drawerType}
tickerCount={tickerCount}
Expand Down
10 changes: 7 additions & 3 deletions src/app/(main)/ticker/_components/ticker-drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const TickerDrawer = React.memo(
}, [drawerType]);

return (
<DrawerContent className="mx-auto h-[calc(100%-100px)] max-w-[--max-width] ">
<DrawerContent className="mx-auto h-[calc(100%-100px)] max-w-screen-md">
<DrawerHeader>
<DrawerTitle className="mb-10 text-h3 font-semibold text-grey-900">{title}</DrawerTitle>
<Input
Expand All @@ -73,9 +73,11 @@ export const TickerDrawer = React.memo(
clearInput={() => handleInputClear("name")}
/>

<div className="mb-5" />

{drawerType !== "name" && (
<Input
value={String(tickerCount)}
value={tickerCount === 0 ? "" : String(tickerCount)}
label="Shares"
type="number"
errorDescription="You can enter 1 or more."
Expand All @@ -86,7 +88,9 @@ export const TickerDrawer = React.memo(
)}
</DrawerHeader>

{drawerType === "name" && !!data && <TickerList data={data} onClick={handleTickerClick} />}
{drawerType === "name" && !!data && (
<TickerList data={data} tickerName={tickerName} onClick={handleTickerClick} />
)}

{drawerType === "count" && (
<DrawerFooter>
Expand Down
4 changes: 2 additions & 2 deletions src/app/(main)/ticker/_components/ticker-footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ export default function TickerFooter() {

return (
<div
className="fixed bottom-4 flex w-full justify-center p-5 pt-12"
className="sticky bottom-0 flex w-full justify-center p-5 pb-4 pt-0 "
style={{
backgroundImage: "linear-gradient(0deg, var(--color-white) 52.78%, rgba(255, 255, 255, 0.00) 100%)",
maxWidth: 768,
}}
>
<Button
variant={"default"}
className="mx-5 h-14 w-full rounded-lg bg-main-700 p-4"
className="mt-14 h-14 w-full rounded-lg bg-main-700 p-4"
style={{
backgroundColor: "#4F6AFC",
color: "#fff",
Expand Down
52 changes: 42 additions & 10 deletions src/app/(main)/ticker/_components/ticker-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,54 @@ interface TickerProps {
onClick: (stock: Stock) => void;
}

const TickerList = React.memo(({ data, hasShares, onClick }: TickerProps) => {
const TickerList = React.memo(({ data, tickerName, hasShares, onClick }: TickerProps) => {
const getHighlightText = React.useCallback(
(text?: string) => {
if (!tickerName || !text) return text;
const regex = new RegExp(tickerName, "gi");

return text.split(regex).reduce((acc: (string | React.ReactElement)[], cur = "", idx, arr) => {
acc.push(cur);
// 마지막 배열 순번이 아닐 경우에만 하이라이트 워딩 추가
if (arr.length - 1 > idx) {
const match = text.match(regex);
const ticker = match ? match[idx] : tickerName;

acc.push(
<span className="text-main-700" key={idx}>
{ticker}
</span>
);
}
return acc;
}, []);
},
[tickerName]
);

return (
<div className="flex h-full w-full flex-1 flex-col items-start">
<div className="flex w-full flex-1 flex-col items-start gap-4 overflow-scroll px-4 py-6">
<div className="flex h-full w-full flex-1 flex-col items-start" style={{}}>
<div
className={`flex w-full flex-1 flex-col items-start ${
hasShares ? "gap-6" : "gap-5"
} overflow-scroll px-4 pb-1 pt-6`}
>
{data.map((item, index) => (
<div key={index} className="flex w-full justify-between" onClick={() => onClick(item)}>
<div className="flex">
<div className="mr-4 flex h-10 w-10 items-center justify-center rounded-full border border-grey-100 bg-grey-50" />
<div>
<p className="text-left text-h3 text-grey-900">{item.ticker}</p>
<p className="line-clamp-1 break-all text-body3 text-grey-600">{item.companyName}</p>
<div className="flex items-center">
<div className="mr-4 flex h-10 min-w-10 max-w-10 items-center justify-center rounded-full border border-grey-100 bg-grey-50" />
<div className="flex flex-col justify-between gap-1">
<span className="mb-1 line-clamp-1 break-all text-left text-h5 text-grey-900">
{getHighlightText(item.ticker)}
</span>
<span className="line-clamp-1 break-all text-body3 text-grey-600">
{getHighlightText(item.companyName)}
</span>
</div>
</div>
{hasShares && (
<div className="ml-2 text-nowrap">
<p className="text-body1 text-main-900">{`${item.count} Shares`}</p>
<div className="ml-2 max-w-20">
<p className="truncate text-body1 text-main-900">{`${item.count} Shares`}</p>
</div>
)}
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/components/common/dialog/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ interface DialogProps {
export const Dialog = React.memo(({ title }: DialogProps) => {
const { isDialogOpenChange } = useDialogStore();
return (
<DialogContent className="w-4/5 rounded-xl bg-white">
<DialogContent className="w-4/5 rounded-xl bg-white p-5">
<DialogHeader>
<DialogTitle className="my-4 text-h5">{title}</DialogTitle>
<DialogTitle className="my-5 text-h5">{title}</DialogTitle>
</DialogHeader>
<DialogFooter>
<Button className="mt-5 rounded-lg bg-main-700" onClick={() => isDialogOpenChange(false)}>
<Button className="mt-5 h-12 rounded-lg bg-main-700 py-4" onClick={() => isDialogOpenChange(false)}>
<DialogDescription className="text-h6 text-white">Ok</DialogDescription>
</Button>
</DialogFooter>
Expand Down
11 changes: 6 additions & 5 deletions src/components/common/toast/toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ const Toast = React.memo(({ t, title, isRevertable, handleUndo, ...props }: Toas

return (
<div
className={cn(
"flex items-center justify-between rounded bg-grey-900 px-4 py-3 text-white shadow",
props.className
)}
className={cn("flex items-center justify-between rounded bg-grey-900 py-3.5 text-white shadow", props.className)}
style={{
paddingLeft: "1.125rem",
paddingRight: "1.125rem",
}}
{...props}
>
<p>{title}</p>
<p className="text-body3">{title}</p>
{isRevertable && <UndoButton onClick={onUndo} />}
</div>
);
Expand Down
10 changes: 2 additions & 8 deletions src/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
"bg-background fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
"bg-background fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] border p-5 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className
)}
{...props}
Expand All @@ -63,13 +63,7 @@ DialogFooter.displayName = "DialogFooter";
const DialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold leading-none tracking-tight", className)}
{...props}
/>
));
>(({ className, ...props }, ref) => <DialogPrimitive.Title ref={ref} className={className} {...props} />);
DialogTitle.displayName = DialogPrimitive.Title.displayName;

const DialogDescription = React.forwardRef<
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const DrawerContent = React.forwardRef<
DrawerContent.displayName = "DrawerContent";

const DrawerHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
<div className={cn("grid gap-1.5 p-4 text-h3 text-grey-900", className)} {...props} />
<div className={cn("grid p-4 text-h3 text-grey-900", className)} {...props} />
);
DrawerHeader.displayName = "DrawerHeader";

Expand Down
4 changes: 2 additions & 2 deletions src/components/ui/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
onBlur={handleBlur}
{...props}
/>
{!props.disabled && props.value && (
{inputState === "focused" && !props.disabled && props.value ? (
<div className="flex items-center pl-4 ">
<button
className="flex h-5 w-5 items-center justify-center rounded-full bg-grey-300"
Expand All @@ -84,7 +84,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
<IcXCircle color={"#f9fafb"} />
</button>
</div>
)}
) : null}
</div>
{inputState === "error" && errorDescription && <p className="mt-1 text-body4 text-error">{errorDescription}</p>}
</div>
Expand Down

0 comments on commit f1ffb65

Please sign in to comment.