Skip to content

Commit

Permalink
Merge pull request #662 from woowacourse-teams/fix/#655
Browse files Browse the repository at this point in the history
닉네임, 제목이 길 때 UI 깨지는 문제
  • Loading branch information
jaeml06 authored Oct 17, 2024
2 parents b3b6002 + 0f7c7a4 commit 510799e
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 39 deletions.
30 changes: 16 additions & 14 deletions frontend/src/components/ProfileFrame/ProfileFrame.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@ type Size = number;

export const profileBox = () => {
return css`
width: fit-content;
position: relative;
`;
};

export const profileCrown = (width: Size) => {
return css`
position: absolute;
top: -14px;
left: 50%;
transform: translateX(-50%);
width: ${3 * (width / 8)}rem;
`;
};

Expand Down Expand Up @@ -38,22 +49,13 @@ export const profileImage = (
props: { isLoaded?: boolean } = { isLoaded: true },
) => {
return css`
${!props.isLoaded && 'display: none;'}
${!props.isLoaded && 'display: none;'};
width: 100%;
height: 100%;
object-fit: cover;
background-image: url(${EmptyProfile});
background-size: cover;
background-position: center;
object-fit: cover;
`;
};

// 크라운 이미지를 가운데 정렬하기 위한 css
export const profileCrown = (width: Size) => {
return css`
position: relative;
top: 1rem;
left: ${width / 2 - (3 * (width / 8)) / 2}rem;
width: ${3 * (width / 8)}rem;
background-size: cover;
`;
};
32 changes: 32 additions & 0 deletions frontend/src/hooks/useNicknameWidthEffect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useEffect, useRef, useState } from 'react';

export default function useNicknameWidthEffect({
nickname,
maxNicknameWidth,
}: {
nickname: string;
maxNicknameWidth: number;
}) {
const nicknameRef = useRef<HTMLDivElement>(null);
const [formattedNickname, setFormattedNickname] = useState(nickname);

useEffect(() => {
const nicknameEl = nicknameRef.current;
if (!nicknameEl) {
return;
}

const nicknameWidth = nicknameEl.offsetWidth;
if (nicknameWidth > maxNicknameWidth) {
const midpoint = Math.ceil(nickname.length / 2);
const firstPart = nickname.slice(0, midpoint);
const secondPart = nickname.slice(midpoint);
setFormattedNickname(`${firstPart}\n${secondPart}`);
}
}, [nickname, maxNicknameWidth]);

return {
nicknameRef,
formattedNickname,
};
}
5 changes: 3 additions & 2 deletions frontend/src/pages/Bet/BetDetailPage/BetDetailPage.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ export const containerStyle = css`

export const titleBox = () => css`
display: flex;
gap: 1rem;
align-items: center;
flex-direction: column;
gap: 4px;
align-items: flex-start;
`;

export const title = (props: { theme: Theme }) => css`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { css, Theme } from '@emotion/react';

export const ProfileCard = css`
export const profileCard = css`
display: flex;
flex-direction: column;
gap: 0.4rem;
align-items: center;
justify-content: flex-end;
justify-content: flex-start;
width: auto;
width: fit-content;
`;

export const ProfileName = (props: { theme: Theme }) => css`
${props.theme.typography.s2}
export const profileNickname = (props: { theme: Theme }) => css`
${props.theme.typography.c2}
text-align: center;
white-space: pre-line;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,27 @@ import * as S from './ProfileCard.style';
import { useTheme } from '@emotion/react';
import { Participant } from '@_types/index';
import ProfileFrame from '../../../../../../components/ProfileFrame/ProfileFrame';
import useNicknameWidthEffect from '@_hooks/useNicknameWidthEffect';

interface ProfileCardProps {
info: Participant;
}
export default function ProfileCard(props: ProfileCardProps) {
const { info } = props;

const { nicknameRef, formattedNickname } = useNicknameWidthEffect({
nickname: info.nickname,
maxNicknameWidth: 70,
});

const theme = useTheme();

return (
<div css={S.ProfileCard}>
<div css={S.profileCard}>
<ProfileFrame width={7} height={7} src={info.profileUrl} />
<div css={S.ProfileName({ theme })}>{info.nickname}</div>
<div ref={nicknameRef} css={S.profileNickname({ theme })}>
{formattedNickname}
</div>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,10 @@ export const count = ({ theme }: { theme: Theme }) => css`
${theme.typography.b3}
color: ${theme.colorPalette.black[30]};
`;

export const tagBox = css`
display: flex;
align-items: flex-start;
justify-content: flex-end;
min-width: 80px;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function BetCard(props: BetCardProps) {
<div css={S.title({ theme })}>{bet.title}</div>
<div css={S.count({ theme })}>현재 {bet.currentParticipants}</div>
</div>
<div>
<div css={S.tagBox}>
<Tag isAnnounced={bet.isAnnounced} deadline={bet.deadline} />
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const commnetBox = () => css`
export const commnetHeader = () => css`
display: flex;
gap: 5px;
align-items: center;
align-items: flex-start;
justify-content: space-between;
width: 100%;
Expand All @@ -42,7 +42,11 @@ export const commnetHeader = () => css`
export const commentHeaderLeft = () => css`
display: flex;
gap: 0.7rem;
align-items: center;
align-items: flex-start;
`;

export const commentNickname = () => css`
white-space: pre-line;
`;

export const commentHeaderRight = (props: { theme: Theme }) => css`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Comment } from '@_types/index';
import { HTMLProps } from 'react';
import { useTheme } from '@emotion/react';
import ProfileFrame from '@_components/ProfileFrame/ProfileFrame';
import useNicknameWidthEffect from '@_hooks/useNicknameWidthEffect';

export interface CommentCardProps extends HTMLProps<HTMLDivElement> {
comment: Comment;
Expand All @@ -13,27 +14,34 @@ export interface CommentCardProps extends HTMLProps<HTMLDivElement> {
}

export default function CommentCard(props: CommentCardProps) {
const theme = useTheme();
const {
comment: { profile, nickname, dateTime, content, children },
onWriteClick,
isChecked = false,
isChild = false,
} = props;

const { nicknameRef, formattedNickname } = useNicknameWidthEffect({
nickname,
maxNicknameWidth: 100,
});

const theme = useTheme();

return (
<div css={S.commentContainer()}>
<div css={S.commentWrapper({ theme, isChecked })}>
<ProfileFrame
width={3}
height={3}
borderWidth={0}
src={profile}
></ProfileFrame>
<ProfileFrame width={3} height={3} borderWidth={0} src={profile} />

<div css={S.commnetBox()}>
<div css={S.commnetHeader}>
<div css={S.commentHeaderLeft}>
<div css={theme.typography.small}>{nickname}</div>
<div
ref={nicknameRef}
css={[S.commentNickname, theme.typography.small]}
>
{formattedNickname}
</div>
<div css={S.timestamp({ theme })}>{dateTime}</div>
</div>
{!isChild && (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { css, Theme } from '@emotion/react';

export const ProfileCard = css`
export const profileCard = css`
display: flex;
flex-direction: column;
gap: 0.4rem;
align-items: center;
justify-content: flex-end;
justify-content: flex-start;
width: auto;
width: fit-content;
padding-top: 14px;
`;

export const ProfileName = (props: { theme: Theme }) => css`
${props.theme.typography.s2}
export const profileName = (props: { theme: Theme }) => css`
${props.theme.typography.c2}
text-align: center;
white-space: pre-line;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,27 @@ import * as S from './ProfileCard.style';
import { useTheme } from '@emotion/react';
import { Participation } from '@_types/index';
import ProfileFrame from '../../../../../../components/ProfileFrame/ProfileFrame';
import useNicknameWidthEffect from '@_hooks/useNicknameWidthEffect';

interface ProfileCardProps {
info: Participation;
}
export default function ProfileCard(props: ProfileCardProps) {
const { info } = props;

const { nicknameRef, formattedNickname } = useNicknameWidthEffect({
nickname: info.nickname,
maxNicknameWidth: 70,
});

const theme = useTheme();

return (
<div css={S.ProfileCard}>
<div css={S.profileCard}>
<ProfileFrame width={7} height={7} src={info.profile} role={info.role} />
<div css={S.ProfileName({ theme })}>{info.nickname}</div>
<div ref={nicknameRef} css={S.profileName({ theme })}>
{formattedNickname}
</div>
</div>
);
}

0 comments on commit 510799e

Please sign in to comment.