setIsFlipped((prev) => !prev)}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ setIsFlipped((prev) => !prev);
+ }
+ }}
>
diff --git a/src/shared/components/tab/BottomNav.tsx b/src/shared/components/tab/BottomNav.tsx
index b998b91..baaf72d 100644
--- a/src/shared/components/tab/BottomNav.tsx
+++ b/src/shared/components/tab/BottomNav.tsx
@@ -31,7 +31,7 @@ export const BottomNav = () => {
rounded-[37.07px]
bg-mint-50 border border-mint-300
'
- aria-label='Bottom navigation'
+ aria-label='하단 내비게이션'
>
{NAV_ITEMS.map((item) => {
const isActive =
diff --git a/src/shared/icons/components/icon.tsx b/src/shared/icons/components/icon.tsx
index fe2a3eb..fcd2c72 100644
--- a/src/shared/icons/components/icon.tsx
+++ b/src/shared/icons/components/icon.tsx
@@ -41,6 +41,8 @@ type IconColor =
interface IconProps extends React.SVGProps {
name: IconName;
+ isInteractive?: boolean;
+ pressed?: boolean;
size?: number | string;
width?: number | string;
height?: number | string;
@@ -54,6 +56,8 @@ interface IconProps extends React.SVGProps {
export const Icon = ({
name,
+ isInteractive = false,
+ pressed,
size,
width,
height,
@@ -64,11 +68,21 @@ export const Icon = ({
hasRotateAnimation = false,
ariaHidden = true,
style,
+ onClick,
+ onKeyDown,
...rest
}: IconProps) => {
const w = width ?? size ?? 20;
const h = height ?? size ?? 20;
+ const handleKeyDown = (e: React.KeyboardEvent) => {
+ if (isInteractive && (e.key === 'Enter' || e.key === ' ')) {
+ e.preventDefault();
+ onClick?.(e as unknown as React.MouseEvent);
+ }
+ onKeyDown?.(e);
+ };
+
const rotateClass =
rotate === 90
? 'rotate-90'
@@ -101,7 +115,12 @@ export const Icon = ({
viewBox="0 0 24 24"
className={combined}
style={iconStyle}
+ role={isInteractive ? 'button' : undefined}
+ tabIndex={isInteractive ? 0 : undefined}
+ aria-pressed={isInteractive ? pressed : undefined}
aria-hidden={ariaHidden}
+ onClick={isInteractive ? onClick : undefined}
+ onKeyDown={isInteractive ? handleKeyDown : undefined}
{...rest}
>