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

닉네임, 제목이 길 때 UI 깨지는 문제 #662

Merged
merged 2 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 All @@ -27,22 +38,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>
);
}
Loading