-
Notifications
You must be signed in to change notification settings - Fork 2
feat: 마비노기 테마 팔레트 추가 #8
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,3 +42,7 @@ next-env.d.ts | |
|
||
# editor | ||
.cursor | ||
|
||
# development principles | ||
DEVELOPMENT_PRINCIPLES.md | ||
GIT_COMMIT_CONVENTION.md |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import { themeColors, colorCategories } from '@/lib/theme'; | ||
|
||
export default function ColorPalettePage() { | ||
return ( | ||
<div className="container mx-auto p-6"> | ||
<h1 className="text-3xl font-bold mb-8">프로젝트 테마 색상</h1> | ||
|
||
<div className="space-y-12"> | ||
{/* 기본 색상 */} | ||
<section> | ||
<h2 className="text-2xl font-semibold mb-6">기본 색상</h2> | ||
<div className="grid grid-cols-2 md:grid-cols-4 gap-6"> | ||
{Object.entries(colorCategories.neutral).map(([name, color]) => ( | ||
<div key={name} className="text-center"> | ||
<div | ||
className="w-20 h-20 rounded-lg border border-gray-300 shadow-sm mx-auto mb-3" | ||
style={{ backgroundColor: color }} | ||
/> | ||
<p className="font-medium">{name}</p> | ||
<p className="text-sm text-gray-600">{color}</p> | ||
</div> | ||
))} | ||
</div> | ||
</section> | ||
|
||
{/* 주요 색상 */} | ||
<section> | ||
<h2 className="text-2xl font-semibold mb-6">주요 색상</h2> | ||
<div className="grid grid-cols-2 md:grid-cols-3 gap-6"> | ||
{Object.entries(colorCategories.primary).map(([name, color]) => ( | ||
<div key={name} className="text-center"> | ||
<div | ||
className="w-20 h-20 rounded-lg border border-gray-300 shadow-sm mx-auto mb-3" | ||
style={{ backgroundColor: color }} | ||
/> | ||
<p className="font-medium">{name}</p> | ||
<p className="text-sm text-gray-600">{color}</p> | ||
</div> | ||
))} | ||
</div> | ||
</section> | ||
|
||
{/* 확장 색상 */} | ||
<section> | ||
<h2 className="text-2xl font-semibold mb-6">확장 색상</h2> | ||
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-6"> | ||
{Object.entries(colorCategories.accent).map(([name, color]) => ( | ||
<div key={name} className="text-center"> | ||
<div | ||
className="w-20 h-20 rounded-lg border border-gray-300 shadow-sm mx-auto mb-3" | ||
style={{ backgroundColor: color }} | ||
/> | ||
<p className="font-medium">{name}</p> | ||
<p className="text-sm text-gray-600">{color}</p> | ||
</div> | ||
))} | ||
</div> | ||
</section> | ||
|
||
{/* 사용 방법 */} | ||
<section className="bg-gray-50 p-6 rounded-lg"> | ||
<h2 className="text-2xl font-semibold mb-4">사용 방법</h2> | ||
<div className="space-y-4"> | ||
<div> | ||
<h3 className="text-lg font-medium mb-2">CSS 클래스</h3> | ||
<div className="bg-white p-3 rounded border"> | ||
<code className="text-sm"> | ||
<div className="text-theme-blue bg-theme-red"> | ||
</code> | ||
</div> | ||
</div> | ||
|
||
<div> | ||
<h3 className="text-lg font-medium mb-2">CSS 변수</h3> | ||
<div className="bg-white p-3 rounded border"> | ||
<code className="text-sm"> | ||
color: var(--color-blue);<br /> | ||
background-color: var(--color-red); | ||
</code> | ||
</div> | ||
</div> | ||
|
||
<div> | ||
<h3 className="text-lg font-medium mb-2">TypeScript</h3> | ||
<div className="bg-white p-3 rounded border"> | ||
<code className="text-sm"> | ||
import {'{'} themeColors {'}'} from '@/lib/theme';<br /> | ||
const buttonColor = themeColors.blue; | ||
</code> | ||
</div> | ||
</div> | ||
</div> | ||
</section> | ||
</div> | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,6 +76,21 @@ | |
--sidebar-accent-foreground: oklch(0.205 0 0); | ||
--sidebar-border: oklch(0.922 0 0); | ||
--sidebar-ring: oklch(0.708 0 0); | ||
--color-white: #FFFFFF; | ||
--color-black: #000000; | ||
--color-blue: #0000C0; | ||
--color-red: #C00000; | ||
--color-yellow: #FFFF00; | ||
--color-light-gray: #D3D3D3; | ||
--color-dark-gray: #282828; | ||
--color-cobalt-blue: #3678F1; | ||
--color-bright-red: #CF1414; | ||
--color-banana-yellow: #FFE062; | ||
--color-ivory-ice: #DEBA86; | ||
--color-hydran-pink: #FFBFCA; | ||
--color-choco-brown: #4E2E28; | ||
--color-delegate-green: #7DDCC4; | ||
--color-purple: #800080; | ||
} | ||
|
||
.dark { | ||
|
@@ -138,3 +153,53 @@ | |
-ms-overflow-style: none; | ||
} | ||
} | ||
|
||
/* 다크 모드 지원 (선택사항) */ | ||
@media (prefers-color-scheme: dark) { | ||
:root { | ||
/* 다크 모드에서 색상 조정이 필요한 경우 여기에 추가 */ | ||
} | ||
} | ||
|
||
/* 기본 스타일 */ | ||
body { | ||
color: var(--color-black); | ||
background: var(--color-white); | ||
} | ||
|
||
/* 유틸리티 클래스 */ | ||
.text-theme-blue { color: var(--color-blue); } | ||
.text-theme-red { color: var(--color-red); } | ||
.text-theme-yellow { color: var(--color-yellow); } | ||
.text-theme-cobalt-blue { color: var(--color-cobalt-blue); } | ||
.text-theme-bright-red { color: var(--color-bright-red); } | ||
.text-theme-banana-yellow { color: var(--color-banana-yellow); } | ||
.text-theme-ivory-ice { color: var(--color-ivory-ice); } | ||
.text-theme-hydran-pink { color: var(--color-hydran-pink); } | ||
.text-theme-choco-brown { color: var(--color-choco-brown); } | ||
.text-theme-delegate-green { color: var(--color-delegate-green); } | ||
.text-theme-purple { color: var(--color-purple); } | ||
|
||
.bg-theme-blue { background-color: var(--color-blue); } | ||
.bg-theme-red { background-color: var(--color-red); } | ||
.bg-theme-yellow { background-color: var(--color-yellow); } | ||
.bg-theme-cobalt-blue { background-color: var(--color-cobalt-blue); } | ||
.bg-theme-bright-red { background-color: var(--color-bright-red); } | ||
.bg-theme-banana-yellow { background-color: var(--color-banana-yellow); } | ||
.bg-theme-ivory-ice { background-color: var(--color-ivory-ice); } | ||
.bg-theme-hydran-pink { background-color: var(--color-hydran-pink); } | ||
.bg-theme-choco-brown { background-color: var(--color-choco-brown); } | ||
.bg-theme-delegate-green { background-color: var(--color-delegate-green); } | ||
.bg-theme-purple { background-color: var(--color-purple); } | ||
|
||
.border-theme-blue { border-color: var(--color-blue); } | ||
.border-theme-red { border-color: var(--color-red); } | ||
.border-theme-yellow { border-color: var(--color-yellow); } | ||
.border-theme-cobalt-blue { border-color: var(--color-cobalt-blue); } | ||
.border-theme-bright-red { border-color: var(--color-bright-red); } | ||
.border-theme-banana-yellow { border-color: var(--color-banana-yellow); } | ||
.border-theme-ivory-ice { border-color: var(--color-ivory-ice); } | ||
.border-theme-hydran-pink { border-color: var(--color-hydran-pink); } | ||
.border-theme-choco-brown { border-color: var(--color-choco-brown); } | ||
.border-theme-delegate-green { border-color: var(--color-delegate-green); } | ||
.border-theme-purple { border-color: var(--color-purple); } | ||
Comment on lines
+171
to
+205
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tailwind를 사용중이라 동일한 색상을 사용중일 경우 이렇게 직접 border, text별로 하나하나 설정할 필요 없이 tailwind.config에서 테마 컬러를 설정해주면 색상별 유틸리티 글래스를 자동으로 생성해줍니다 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아앗 이 방법을 몰랐습니다. 참고해서 수정하도록 하겠습니다. 혹시 다음 PR에서 수정해도 괜찮을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 브랜치를 급하게 머지해야하거나 충돌하는 부분이 없는데 지금 수정하지 않고 다음 PR에서 수정하려는 이유가 있나요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 디스코드에서 이야기 진행 |
mental-disaster marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// 프로젝트 테마 색상 정의 | ||
export const themeColors = { | ||
// 기본 색상 | ||
white: '#FFFFFF', | ||
black: '#000000', | ||
|
||
// 주요 색상 | ||
blue: '#0000C0', | ||
red: '#C00000', | ||
yellow: '#FFFF00', | ||
|
||
// 그레이 톤 | ||
lightGray: '#D3D3D3', | ||
darkGray: '#282828', | ||
|
||
// 확장 색상 | ||
cobaltBlue: '#3678F1', | ||
brightRed: '#CF1414', | ||
bananaYellow: '#FFE062', | ||
ivoryIce: '#DEBA86', | ||
hydranPink: '#FFBFCA', | ||
chocoBrown: '#4E2E28', | ||
delegateGreen: '#7DDCC4', | ||
purple: '#800080', | ||
Comment on lines
+4
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. global.css에서 이미 정의된 테마를 재정의하고 있는데 이유가 뭔가요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Theme 색상을 사용할지가 확실하지 않아 우선은 분리해두었습니다. 팔레트 page 만들어두었는데, 색상 한번 리뷰해주시면 이번 PR에서 합치도록 하겠습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 수정 후 resolve 부탁드려요 |
||
} as const; | ||
|
||
// 색상 타입 정의 | ||
export type ThemeColor = keyof typeof themeColors; | ||
export type ThemeColorValue = typeof themeColors[ThemeColor]; | ||
|
||
// 색상 카테고리별 그룹화 | ||
export const colorCategories = { | ||
primary: { | ||
blue: themeColors.blue, | ||
red: themeColors.red, | ||
yellow: themeColors.yellow, | ||
}, | ||
neutral: { | ||
white: themeColors.white, | ||
black: themeColors.black, | ||
lightGray: themeColors.lightGray, | ||
darkGray: themeColors.darkGray, | ||
}, | ||
accent: { | ||
cobaltBlue: themeColors.cobaltBlue, | ||
brightRed: themeColors.brightRed, | ||
bananaYellow: themeColors.bananaYellow, | ||
ivoryIce: themeColors.ivoryIce, | ||
hydranPink: themeColors.hydranPink, | ||
chocoBrown: themeColors.chocoBrown, | ||
delegateGreen: themeColors.delegateGreen, | ||
purple: themeColors.purple, | ||
}, | ||
} as const; | ||
|
||
// CSS 변수 이름 생성 함수 | ||
export const getCssVariableName = (colorName: ThemeColor): string => { | ||
return `--color-${colorName.replace(/([A-Z])/g, '-$1').toLowerCase()}`; | ||
}; | ||
|
||
// 색상 값 가져오기 함수 | ||
export const getThemeColor = (colorName: ThemeColor): ThemeColorValue => { | ||
return themeColors[colorName]; | ||
}; | ||
|
||
// CSS 변수로 색상 가져오기 함수 | ||
export const getCssVariableColor = (colorName: ThemeColor): string => { | ||
return `var(${getCssVariableName(colorName)})`; | ||
}; | ||
|
||
// 색상 유효성 검사 함수 | ||
export const isValidThemeColor = (color: string): color is ThemeColorValue => { | ||
return Object.values(themeColors).includes(color as ThemeColorValue); | ||
}; | ||
|
||
// 색상 이름으로 색상 찾기 함수 | ||
export const findColorByName = (colorValue: string): ThemeColor | null => { | ||
const entry = Object.entries(themeColors).find(([_, value]) => value === colorValue); | ||
return entry ? (entry[0] as ThemeColor) : null; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
클래스 기반 컬러 설정 외의 컬러 설정 방법을 소개하고 있는데 모든 방법을 소개할 필요는 없고 오히려 데모 페이지에서 프로젝트에서 사용하지 않는 방법까지 보여주면 이후 프로젝트에 참여한 팀원이 헛깔릴 것 같습니다.
현재는 클래스기반 스타일링을 사용하고 있으니 해당 방법만 남기는것이 어떨까 싶습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
문제없으면 머지하기 전에 resolve해주세요