Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
c38c939
refactor: tailwind setting migration
sumi-0011 Jan 14, 2026
bfb5740
feat: landing 페이지 개선
sumi-0011 Jan 14, 2026
e6a0d2c
feat: custom token error fix
sumi-0011 Jan 14, 2026
9875ff1
refactor: ui panda 참조 제거
sumi-0011 Jan 14, 2026
fac5c95
fix: dialog 수정
sumi-0011 Jan 14, 2026
91aff0f
feat: tailwind 패키지 스토리북 추가
sumi-0011 Jan 14, 2026
33ade45
feat: text-glyph-* 유틸리티에 Product Sans fontFamily 자동 적용 플러그인 추가
sumi-0011 Mar 12, 2026
4f94218
Merge branch 'main' into dev
Mar 30, 2026
6b958ea
Merge branch 'dev' into chore/tailwind-mi
Mar 30, 2026
7708797
fix: ui-tailwind Dialog에 TopSlot, Body, scrollable 추가 및 ConfirmDialog 생성
Mar 30, 2026
89a2461
Merge branch 'chore/tailwind-mi' into feat/tailwind-storybook
Mar 30, 2026
361962d
fix: exclude stories files from ui-tailwind type-check
Mar 30, 2026
16ad68c
fix: layout fix
Mar 30, 2026
f612c68
docs: my-pet 페이지 동작 정리 및 진화 모달 미사용 코드 제거
sumi-0011 Mar 31, 2026
6dc0fab
refactor: PersonaListToolbar를 ui-tailwind SearchBar·Select로 전환 (Panda…
sumi-0011 Mar 31, 2026
c0e3735
refactor: PersonaItem을 ui-tailwind Banner·LevelBanner로 전환 (Panda 제거)
sumi-0011 Mar 31, 2026
a15ee67
fix: 판매 확인 Dialog 푸터 버튼 겹침 (flex 레이아웃)
sumi-0011 Mar 31, 2026
d62b8dd
refactor: FSD-inspired 하이브리드 폴더 구조로 apps/web 리팩토링
sumi-0011 Mar 31, 2026
b707ea2
docs: FSD 아키텍처 가이드 문서 및 Cursor rule 추가
sumi-0011 Mar 31, 2026
97d85c6
fix: next-intl i18n request 경로를 shared/i18n/으로 수정
sumi-0011 Mar 31, 2026
09d4264
fix: i18n messages 동적 import 상대 경로 수정
sumi-0011 Mar 31, 2026
c2a9856
Merge branch 'dev' into feat/tailwind-dev
sumi-0011 Apr 1, 2026
827ac67
refactor: Spring 랜딩 페이지 PandaCSS → Tailwind CSS 마이그레이션
sumi-0011 Apr 1, 2026
da3a83b
fix: cherry-blossom 데모 PandaCSS 제거 및 SelectPersonaList 중복 함수 수정
sumi-0011 Apr 1, 2026
0ecb98d
refactor: ConfirmDialog/AlertDialog를 ui-tailwind 공통 컴포넌트로 승격
sumi-0011 Apr 1, 2026
955369a
refactor: 미사용 InterceptingDialog 컴포넌트 삭제
sumi-0011 Apr 1, 2026
cf4ac6b
refactor: RouteModal에 gap prop 추가 (InterceptingDialog 통합)
sumi-0011 Apr 1, 2026
48b7d34
feat: ConfirmDialog, AlertDialog 스토리북 스토리 추가
sumi-0011 Apr 1, 2026
e8645da
feat: Chromatic 스토리북 배포 설정 추가
sumi-0011 Apr 1, 2026
da42fc8
refactor: ConfirmDialog/AlertDialog 스토리 기본 열림 상태로 변경
sumi-0011 Apr 1, 2026
1c6fa3c
refactor: AlertDialog 디자인을 ConfirmDialog와 동일하게 통일
sumi-0011 Apr 1, 2026
4a89d78
fix: button reset의 border: transparent가 Tailwind border 유틸리티 무효화하는 문제 수정
sumi-0011 Apr 1, 2026
4a87860
feat: DialogV2 core - size context + responsive content variants
sumi-0011 Apr 1, 2026
f7457d6
feat: AlertDialogV2, ConfirmDialogV2 - size prop 지원
sumi-0011 Apr 1, 2026
808c648
feat: DialogV2 컴포넌트 export 추가
sumi-0011 Apr 1, 2026
300623e
feat: DialogV2 스토리북 - SM/MD/LG/Full 사이즈 스토리
sumi-0011 Apr 1, 2026
8ddf75b
feat: AlertDialogV2, ConfirmDialogV2 스토리북 스토리 추가
sumi-0011 Apr 1, 2026
b6a06af
feat: DialogV2Body에 ScrollArea 적용
sumi-0011 Apr 1, 2026
cdb8787
feat: ScrollArea 스토리북 스토리 추가
sumi-0011 Apr 1, 2026
1a5addb
fix: DialogV2Body에 min-h-0 추가하여 flex 내 ScrollArea 스크롤 동작 보장
sumi-0011 Apr 1, 2026
436f7b1
fix: ScrollArea에 horizontal ScrollBar 추가
sumi-0011 Apr 1, 2026
7df6960
fix: apps/web에서 삭제된 panda codegen prepare/prebuild 스크립트 제거
sumi-0011 Apr 1, 2026
9233ad7
fix: apps/web에서 삭제된 panda codegen prepare/prebuild 스크립트 제거
sumi-0011 Apr 1, 2026
180d170
Merge branch 'feat/tailwind-dev' into feat/ui-checkbox
sumi-0011 Apr 1, 2026
58bb4c9
Merge remote-tracking branch 'origin/dev' into feat/ui-checkbox
sumi-0011 Apr 2, 2026
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,4 @@ apps/admin-main/.env.local
apps/admin-main/docs/superpowers
.omc

docs/superpowers
2 changes: 1 addition & 1 deletion apps/web/src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

button {
cursor: pointer;
border: transparent;
border-color: transparent;
background-color: transparent;
padding: 0;
outline: none;
Expand Down
2 changes: 1 addition & 1 deletion apps/webview/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

button {
cursor: pointer;
border: transparent;
border-color: transparent;
background-color: transparent;
padding: 0;
outline: none;
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/tailwind/.storybook/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

button {
cursor: pointer;
border: transparent;
border-color: transparent;
background-color: transparent;
padding: 0;
outline: none;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import type { Meta, StoryObj } from '@storybook/react';
import { AlertDialogV2 } from './alert-dialog-v2';

const meta: Meta<typeof AlertDialogV2> = {
title: 'UI/AlertDialogV2',
component: AlertDialogV2,
parameters: { layout: 'centered' },
tags: ['autodocs'],
args: {
isOpen: true,
onClose: () => {},
},
argTypes: {
title: { control: 'text' },
description: { control: 'text' },
closeText: { control: 'text' },
size: { control: 'select', options: ['sm', 'md', 'lg', 'full'] },
},
};
export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
title: 'Notice',
description: 'Your pet has leveled up!',
closeText: 'OK',
},
};

export const ErrorAlert: Story = {
args: {
title: 'Error',
description: 'Failed to complete the action. Please try again later.',
closeText: 'Close',
},
};

export const WithChildren: Story = {
args: {
title: 'Monthly Summary',
description: 'Here is your activity for this month:',
closeText: 'Got it',
children: (
<ul className="text-white/70 list-disc pl-4 space-y-1">
<li>Contribution streak: 30 days</li>
<li>Pets earned: 3</li>
<li>Total points: 1,500</li>
</ul>
),
},
};

export const MediumSize: Story = {
args: {
title: 'Update Available',
description: 'A new version is ready. Please review the changelog below.',
closeText: 'Dismiss',
size: 'md',
children: (
<div className="bg-white/10 text-white rounded-md p-3 space-y-1 text-sm">
<p>- Improved pet animation performance</p>
<p>- Fixed streak calculation bug</p>
<p>- Added new pet skins for top contributors</p>
</div>
),
},
};
42 changes: 42 additions & 0 deletions packages/ui/tailwind/src/components/ui/alert-dialog-v2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use client';

import type { ReactNode } from 'react';
import { DialogV2, type DialogV2Size } from './dialog-v2';
import { Button } from './button';

export interface AlertDialogV2Props {
isOpen: boolean;
onClose: () => void;
title: string;
description?: ReactNode;
closeText?: string;
children?: ReactNode;
size?: DialogV2Size;
}

export function AlertDialogV2({
isOpen,
onClose,
title,
description,
closeText = 'Close',
children,
size = 'sm',
}: AlertDialogV2Props) {
const buttonSize = size === 'sm' ? 's' : size === 'full' ? 'l' : 'm';

return (
<DialogV2 open={isOpen} onOpenChange={onClose}>
<DialogV2.Content size={size}>
<DialogV2.Title>{title}</DialogV2.Title>
{description && <DialogV2.Description>{description}</DialogV2.Description>}
{children && <div className="w-full">{children}</div>}
<DialogV2.Footer>
<Button onClick={onClose} variant="primary" size={buttonSize}>
{closeText}
</Button>
</DialogV2.Footer>
</DialogV2.Content>
</DialogV2>
);
}
6 changes: 2 additions & 4 deletions packages/ui/tailwind/src/components/ui/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ const Checkbox = React.forwardRef<
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/25 focus-visible:ring-offset-2',
'disabled:cursor-not-allowed disabled:opacity-50',
'data-[state=checked]:bg-[#fafafa] data-[state=checked]:text-black',
className
className,
)}
{...props}
>
<CheckboxPrimitive.Indicator
className={cn('flex items-center justify-center text-current')}
>
<CheckboxPrimitive.Indicator className={cn('flex items-center justify-center text-current')}>
<Check className="h-4 w-4" />
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import type { Meta, StoryObj } from '@storybook/react';
import { ConfirmDialogV2 } from './confirm-dialog-v2';

const meta: Meta<typeof ConfirmDialogV2> = {
title: 'UI/ConfirmDialogV2',
component: ConfirmDialogV2,
parameters: { layout: 'centered' },
tags: ['autodocs'],
args: {
isOpen: true,
onClose: () => {},
onConfirm: () => {},
},
argTypes: {
title: { control: 'text' },
description: { control: 'text' },
confirmText: { control: 'text' },
cancelText: { control: 'text' },
isLoading: { control: 'boolean' },
size: { control: 'select', options: ['sm', 'md', 'lg', 'full'] },
},
};
export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
title: 'Delete Item?',
description: 'Are you sure you want to delete this item? This action cannot be undone.',
confirmText: 'Delete',
cancelText: 'Cancel',
},
};

export const CustomButtonText: Story = {
args: {
title: 'Merge Pet?',
description: 'This will merge two pets into one stronger pet.',
confirmText: 'Yes, merge',
cancelText: 'No, keep them',
},
};

export const Loading: Story = {
args: {
title: 'Save Changes?',
description: 'Click confirm to save your changes.',
confirmText: 'Save',
cancelText: 'Discard',
isLoading: true,
},
};

export const WithChildren: Story = {
args: {
title: 'Sell this pet?',
description: 'The following pet will be sold:',
confirmText: 'Sell',
cancelText: 'Cancel',
children: (
<div className="bg-white/10 text-white rounded-md p-3 text-sm">
Pet: Golden Retriever (Lv.5)
</div>
),
},
};

export const MediumSize: Story = {
args: {
title: 'Transfer Pet',
description: 'Select a user to transfer this pet to.',
confirmText: 'Transfer',
cancelText: 'Cancel',
size: 'md',
children: (
<div className="space-y-2">
<input
className="w-full bg-white/10 text-white rounded-md px-3 py-2 text-sm outline-none placeholder:text-white/40"
placeholder="Search users..."
/>
<ul className="space-y-1">
<li className="bg-white/10 text-white rounded-md px-3 py-2 text-sm cursor-pointer hover:bg-white/20">
user_alpha
</li>
<li className="bg-white/10 text-white rounded-md px-3 py-2 text-sm cursor-pointer hover:bg-white/20">
user_beta
</li>
<li className="bg-white/10 text-white rounded-md px-3 py-2 text-sm cursor-pointer hover:bg-white/20">
user_gamma
</li>
</ul>
</div>
),
},
};
64 changes: 64 additions & 0 deletions packages/ui/tailwind/src/components/ui/confirm-dialog-v2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
'use client';

import type { ReactNode } from 'react';
import { useState } from 'react';
import { DialogV2, type DialogV2Size } from './dialog-v2';
import { Button } from './button';

export interface ConfirmDialogV2Props {
isOpen: boolean;
onClose: () => void;
onConfirm: () => void | Promise<void>;
title: string;
description?: ReactNode;
confirmText?: string;
cancelText?: string;
isLoading?: boolean;
children?: ReactNode;
size?: DialogV2Size;
}

export function ConfirmDialogV2({
isOpen,
onClose,
onConfirm,
title,
description,
confirmText = 'Confirm',
cancelText = 'Cancel',
isLoading: externalLoading,
children,
size = 'sm',
}: ConfirmDialogV2Props) {
const [internalLoading, setInternalLoading] = useState(false);
const isLoading = externalLoading ?? internalLoading;
const buttonSize = size === 'sm' ? 's' : size === 'full' ? 'l' : 'm';

const handleConfirm = async () => {
if (isLoading) return;
setInternalLoading(true);
try {
await onConfirm();
} finally {
setInternalLoading(false);
}
};

return (
<DialogV2 open={isOpen} onOpenChange={onClose}>
<DialogV2.Content size={size}>
<DialogV2.Title>{title}</DialogV2.Title>
{description && <DialogV2.Description>{description}</DialogV2.Description>}
{children && <div className="w-full">{children}</div>}
<DialogV2.Footer>
<Button onClick={onClose} variant="secondary" size={buttonSize}>
{cancelText}
</Button>
<Button onClick={handleConfirm} variant="primary" size={buttonSize} disabled={isLoading}>
{confirmText}
</Button>
</DialogV2.Footer>
</DialogV2.Content>
</DialogV2>
);
}
Loading
Loading