feat: 시안이 지정한 아이콘 버튼 복구 — 행 관리 4화면 + 테마 토글
아이콘이 없어 텍스트로 대체돼 있던 자리를 시안대로 되돌린다. `@fox`에 Phosphor 전량이 들어왔으므로 더 이상 막힐 이유가 없다. - students: 돋보기(FoxMagnifyingGlassIcon) — "조회" 텍스트 버튼을 대체 - admins · boards · decoration-items: 연필(FoxPencilSimpleIcon)·휴지통(FoxTrashIcon) - 테마 토글: 손으로 그린 monitor/moon/sun 3종을 @fox 아이콘으로 교체하고 components/ui/icons/ 디렉터리를 제거했다(다른 사용처 없음) 버튼을 `components/ui/button`이 아니라 `FoxIconButton`으로 쓴 이유 — @fox 아이콘은 스스로 크기를 갖지 않고 감싼 슬롯이 정하는 규약인데, 그 슬롯 크기를 실제로 정의하는 CSS가 있는 건 @fox 쪽뿐이다. Tailwind 제거(e3d3133)가 빌드 설정만 바꾸고 components/ui 19개 파일은 그대로 둔 탓에 `size-9`·`inline-flex` 같은 클래스가 전부 무효라, 그쪽에 아이콘을 넣으면 SVG가 기본 300×150으로 그려진다. 테마 토글은 같은 이유로 실제 버그였다 — 표시 전환을 Tailwind의 `hidden theme-*:contents`에 기대고 있어서 세 아이콘이 한꺼번에 보이고 있었다. 같은 동작을 CSS 모듈로 다시 세웠고, `aria-label` 대신 `sr-only` 텍스트로 현재 선택을 읽히는 기존 접근성 설계는 그대로 유지했다 (IconButton에 label을 넘기면 aria-label이 내용을 덮어쓴다). 검증 — 컴파일된 CSS를 주입해 `` 3상태를 실제로 전환했다. 속성 없음→system, light→light, dark→dark로 **매번 하나만** 표시되고 20×20px(--fox-icon-4)로 그려진다. FoxIconButton은 sm/ghost에서 28px 버튼에 24×24 아이콘이다. 남은 것 — sidebar-group.tsx의 셰브론은 손으로 그린 채로 뒀다. 회전(`rotate-90`)과 크기(`size-4`)를 Tailwind 클래스에 기대고 있어 그 둘을 실재하는 CSS로 옮기기 전에는 글리프만 바꿔도 나아지지 않는다. components/ui 전체 리스타일과 함께 처리한다. Co-Authored-By: Claude Opus 5
@ef3a937d145e5b6a29d57e39b2a2c044795ca83a
--- app/(protected)/(basic)/admins/_components/admin-member-row-actions.tsx
+++ app/(protected)/(basic)/admins/_components/admin-member-row-actions.tsx
... | ... | @@ -2,6 +2,8 @@ |
| 2 | 2 |
|
| 3 | 3 |
import { useState, useTransition } from 'react';
|
| 4 | 4 |
import { Button } from '@/components/ui/button';
|
| 5 |
+import { FoxIconButton } from '@fox/core/components/fox-icon-button';
|
|
| 6 |
+import { FoxPencilSimpleIcon, FoxTrashIcon } from '@fox/core/icons';
|
|
| 5 | 7 |
import { useFeedback } from '@/app/_hooks/use-feedback';
|
| 6 | 8 |
import type { AdminMember } from '@/lib/domain/admin-member';
|
| 7 | 9 |
import { deleteAdminMemberAction } from '../_actions';
|
... | ... | @@ -25,9 +27,12 @@ |
| 25 | 27 |
* **본인 계정 삭제는 막는다**(시안 ⑤). 화면에서 버튼을 비활성으로 두되, 실제 차단은 Server |
| 26 | 28 |
* Action이 세션의 adminId와 대조해 수행한다 — 화면 비활성은 안내일 뿐 신뢰 경계가 아니다. |
| 27 | 29 |
* |
| 28 |
- * 시안은 연필·휴지통 아이콘 버튼을 지정하지만 `components/ui/icons/`에 두 아이콘이 아직 없다 |
|
| 29 |
- * (신규 아이콘 추가는 공용 컴포넌트 신설이라 design 레인 소관). 로직 우선 단계라 텍스트 |
|
| 30 |
- * 버튼으로 대체했고, 아이콘 부재는 별도로 보고한다. |
|
| 30 |
+ * 시안의 연필·휴지통 아이콘 버튼이다. 버튼은 `components/ui/button`이 아니라 `FoxIconButton`을 |
|
| 31 |
+ * 쓴다 — 아이콘은 스스로 크기를 갖지 않고 감싼 슬롯이 정하는데, 그 슬롯 크기를 실제로 정의하는 |
|
| 32 |
+ * 건 @fox 쪽뿐이다(components/ui는 Tailwind 제거 이후 무스타일이다). |
|
| 33 |
+ * |
|
| 34 |
+ * 본인 계정 안내는 `<span title>`로 감싸 남긴다 — FoxIconButton은 `label`을 `aria-label`로만 |
|
| 35 |
+ * 쓰고 네이티브 툴팁을 렌더하지 않으며, 비활성 버튼은 스스로 hover 이벤트를 받지 못한다. |
|
| 31 | 36 |
*/ |
| 32 | 37 |
export function AdminMemberRowActions({
|
| 33 | 38 |
member, |
... | ... | @@ -72,24 +77,23 @@ |
| 72 | 77 |
|
| 73 | 78 |
return ( |
| 74 | 79 |
<div className="flex items-center gap-1"> |
| 75 |
- <Button |
|
| 76 |
- type="button" |
|
| 77 |
- variant="ghost" |
|
| 80 |
+ <FoxIconButton |
|
| 81 |
+ type="ghost" |
|
| 78 | 82 |
size="sm" |
| 79 |
- onClick={() => setIsEditOpen(true)}
|
|
| 80 |
- > |
|
| 81 |
- 수정 |
|
| 82 |
- </Button> |
|
| 83 |
- <Button |
|
| 84 |
- type="button" |
|
| 85 |
- variant="ghost" |
|
| 86 |
- size="sm" |
|
| 87 |
- onClick={confirmDelete}
|
|
| 88 |
- disabled={isSelf || isDeleting}
|
|
| 89 |
- title={isSelf ? SELF_DELETE_HINT : undefined}
|
|
| 90 |
- > |
|
| 91 |
- {isDeleting ? '삭제 중...' : '삭제'}
|
|
| 92 |
- </Button> |
|
| 83 |
+ icon={<FoxPencilSimpleIcon />}
|
|
| 84 |
+ label="수정" |
|
| 85 |
+ onAction={() => setIsEditOpen(true)}
|
|
| 86 |
+ /> |
|
| 87 |
+ <span title={isSelf ? SELF_DELETE_HINT : undefined}>
|
|
| 88 |
+ <FoxIconButton |
|
| 89 |
+ type="ghost" |
|
| 90 |
+ size="sm" |
|
| 91 |
+ icon={<FoxTrashIcon />}
|
|
| 92 |
+ label={isDeleting ? '삭제 중' : '삭제'}
|
|
| 93 |
+ disabled={isSelf || isDeleting}
|
|
| 94 |
+ onAction={confirmDelete}
|
|
| 95 |
+ /> |
|
| 96 |
+ </span> |
|
| 93 | 97 |
|
| 94 | 98 |
{isEditOpen && (
|
| 95 | 99 |
<AdminMemberEditModal |
--- app/(protected)/(basic)/boards/_components/board-row-actions.tsx
+++ app/(protected)/(basic)/boards/_components/board-row-actions.tsx
... | ... | @@ -2,6 +2,8 @@ |
| 2 | 2 |
|
| 3 | 3 |
import { useState, useTransition } from 'react';
|
| 4 | 4 |
import { Button } from '@/components/ui/button';
|
| 5 |
+import { FoxIconButton } from '@fox/core/components/fox-icon-button';
|
|
| 6 |
+import { FoxPencilSimpleIcon, FoxTrashIcon } from '@fox/core/icons';
|
|
| 5 | 7 |
import { useFeedback } from '@/app/_hooks/use-feedback';
|
| 6 | 8 |
import type { BoardPost, BoardType } from '@/lib/domain/board-post';
|
| 7 | 9 |
import { deleteBoardPostAction } from '../_actions';
|
... | ... | @@ -20,8 +22,9 @@ |
| 20 | 22 |
* 표시만 바꾸지만, 관리자 화면에서 다시 볼 방법이 없으므로 사용자에게는 되돌릴 수 없는 동작으로 |
| 21 | 23 |
* 안내한다. |
| 22 | 24 |
* |
| 23 |
- * 시안은 연필·휴지통 아이콘 버튼을 지정하지만 `components/ui/icons/`에 두 아이콘이 아직 없어 |
|
| 24 |
- * (신규 아이콘 추가는 design 레인 소관) 텍스트 버튼으로 대체했다 — 관리자 회원 목록과 같은 처리다. |
|
| 25 |
+ * 시안의 연필·휴지통 아이콘 버튼이다. 버튼은 `components/ui/button`이 아니라 `FoxIconButton`을 |
|
| 26 |
+ * 쓴다 — 아이콘은 스스로 크기를 갖지 않고 감싼 슬롯이 정하는데, 그 슬롯 크기를 실제로 정의하는 |
|
| 27 |
+ * 건 @fox 쪽뿐이다(components/ui는 Tailwind 제거 이후 무스타일이다). |
|
| 25 | 28 |
*/ |
| 26 | 29 |
export function BoardRowActions({ boardType, post }: BoardRowActionsProps) {
|
| 27 | 30 |
const { showAlert, hideAlert, showToast } = useFeedback();
|
... | ... | @@ -63,23 +66,21 @@ |
| 63 | 66 |
|
| 64 | 67 |
return ( |
| 65 | 68 |
<div className="flex items-center gap-1"> |
| 66 |
- <Button |
|
| 67 |
- type="button" |
|
| 68 |
- variant="ghost" |
|
| 69 |
+ <FoxIconButton |
|
| 70 |
+ type="ghost" |
|
| 69 | 71 |
size="sm" |
| 70 |
- onClick={() => setIsEditOpen(true)}
|
|
| 71 |
- > |
|
| 72 |
- 수정 |
|
| 73 |
- </Button> |
|
| 74 |
- <Button |
|
| 75 |
- type="button" |
|
| 76 |
- variant="ghost" |
|
| 72 |
+ icon={<FoxPencilSimpleIcon />}
|
|
| 73 |
+ label="수정" |
|
| 74 |
+ onAction={() => setIsEditOpen(true)}
|
|
| 75 |
+ /> |
|
| 76 |
+ <FoxIconButton |
|
| 77 |
+ type="ghost" |
|
| 77 | 78 |
size="sm" |
| 78 |
- onClick={confirmDelete}
|
|
| 79 |
+ icon={<FoxTrashIcon />}
|
|
| 80 |
+ label={isDeleting ? '삭제 중' : '삭제'}
|
|
| 79 | 81 |
disabled={isDeleting}
|
| 80 |
- > |
|
| 81 |
- {isDeleting ? '삭제 중...' : '삭제'}
|
|
| 82 |
- </Button> |
|
| 82 |
+ onAction={confirmDelete}
|
|
| 83 |
+ /> |
|
| 83 | 84 |
|
| 84 | 85 |
{isEditOpen && (
|
| 85 | 86 |
<BoardPostFormModal |
--- app/(protected)/(basic)/decoration-items/_components/decoration-item-row-actions.tsx
+++ app/(protected)/(basic)/decoration-items/_components/decoration-item-row-actions.tsx
... | ... | @@ -2,6 +2,8 @@ |
| 2 | 2 |
|
| 3 | 3 |
import { useState, useTransition } from 'react';
|
| 4 | 4 |
import { Button } from '@/components/ui/button';
|
| 5 |
+import { FoxIconButton } from '@fox/core/components/fox-icon-button';
|
|
| 6 |
+import { FoxPencilSimpleIcon, FoxTrashIcon } from '@fox/core/icons';
|
|
| 5 | 7 |
import { useFeedback } from '@/app/_hooks/use-feedback';
|
| 6 | 8 |
import type { DecorationItem } from '@/lib/domain/decoration-item';
|
| 7 | 9 |
import { deleteDecorationItemAction } from '../_actions';
|
... | ... | @@ -21,8 +23,9 @@ |
| 21 | 23 |
* 슬롯에 직접 [취소]/[삭제] 버튼을 넣어 구성한다. 삭제는 되돌릴 수 없는 동작이라 얼럿 문구에 |
| 22 | 24 |
* 명시한다. |
| 23 | 25 |
* |
| 24 |
- * 시안은 연필·휴지통 아이콘 버튼을 지정하지만 `components/ui/icons/`에 아직 없어(신규 아이콘 |
|
| 25 |
- * 추가는 공용 컴포넌트 신설이라 design 레인 소관) admins와 동일하게 텍스트 버튼으로 대체했다. |
|
| 26 |
+ * 시안의 연필·휴지통 아이콘 버튼이다. 버튼은 `components/ui/button`이 아니라 `FoxIconButton`을 |
|
| 27 |
+ * 쓴다 — 아이콘은 스스로 크기를 갖지 않고 감싼 슬롯이 정하는데, 그 슬롯 크기를 실제로 정의하는 |
|
| 28 |
+ * 건 @fox 쪽뿐이다(components/ui는 Tailwind 제거 이후 무스타일이다). |
|
| 26 | 29 |
*/ |
| 27 | 30 |
export function DecorationItemRowActions({
|
| 28 | 31 |
item, |
... | ... | @@ -67,23 +70,21 @@ |
| 67 | 70 |
|
| 68 | 71 |
return ( |
| 69 | 72 |
<div className="flex items-center gap-1"> |
| 70 |
- <Button |
|
| 71 |
- type="button" |
|
| 72 |
- variant="ghost" |
|
| 73 |
+ <FoxIconButton |
|
| 74 |
+ type="ghost" |
|
| 73 | 75 |
size="sm" |
| 74 |
- onClick={() => setIsEditOpen(true)}
|
|
| 75 |
- > |
|
| 76 |
- 수정 |
|
| 77 |
- </Button> |
|
| 78 |
- <Button |
|
| 79 |
- type="button" |
|
| 80 |
- variant="ghost" |
|
| 76 |
+ icon={<FoxPencilSimpleIcon />}
|
|
| 77 |
+ label="수정" |
|
| 78 |
+ onAction={() => setIsEditOpen(true)}
|
|
| 79 |
+ /> |
|
| 80 |
+ <FoxIconButton |
|
| 81 |
+ type="ghost" |
|
| 81 | 82 |
size="sm" |
| 82 |
- onClick={confirmDelete}
|
|
| 83 |
+ icon={<FoxTrashIcon />}
|
|
| 84 |
+ label={isDeleting ? '삭제 중' : '삭제'}
|
|
| 83 | 85 |
disabled={isDeleting}
|
| 84 |
- > |
|
| 85 |
- {isDeleting ? '삭제 중...' : '삭제'}
|
|
| 86 |
- </Button> |
|
| 86 |
+ onAction={confirmDelete}
|
|
| 87 |
+ /> |
|
| 87 | 88 |
|
| 88 | 89 |
{isEditOpen && (
|
| 89 | 90 |
<DecorationItemEditModal |
--- app/(protected)/(basic)/students/_components/student-row-actions.tsx
+++ app/(protected)/(basic)/students/_components/student-row-actions.tsx
... | ... | @@ -1,7 +1,8 @@ |
| 1 | 1 |
'use client'; |
| 2 | 2 |
|
| 3 | 3 |
import { useState } from 'react';
|
| 4 |
-import { Button } from '@/components/ui/button';
|
|
| 4 |
+import { FoxIconButton } from '@fox/core/components/fox-icon-button';
|
|
| 5 |
+import { FoxMagnifyingGlassIcon } from '@fox/core/icons';
|
|
| 5 | 6 |
import type { StudentMember } from '@/lib/domain/student-member';
|
| 6 | 7 |
import { StudentDetailModal } from './student-detail-modal';
|
| 7 | 8 |
|
... | ... | @@ -14,23 +15,22 @@ |
| 14 | 15 |
* 클라이언트로 내리지 않기 위해 이 셀만 분리했다 — §2.4 "'use client'는 최말단에만"). 팝업에 |
| 15 | 16 |
* 필요한 데이터는 이미 이 행이 갖고 있는 member를 그대로 전달한다(재조회 없음). |
| 16 | 17 |
* |
| 17 |
- * 기획 시안은 "돋보기 아이콘 버튼"을 지정하지만 `components/ui/icons/`에 아직 돋보기 아이콘이 |
|
| 18 |
- * 없다(신규 아이콘 추가는 공용 컴포넌트 신설이라 design 레인 소관, §4.2). 로직 우선 단계라 |
|
| 19 |
- * 아이콘 대신 텍스트 버튼("조회")으로 대체했고, 아이콘 부재는 별도로 보고한다.
|
|
| 18 |
+ * 시안의 "돋보기 아이콘 버튼"이다. 버튼은 `components/ui/button`이 아니라 `FoxIconButton`을 |
|
| 19 |
+ * 쓴다 — 아이콘은 스스로 크기를 갖지 않고 감싼 슬롯이 정하는데, 그 슬롯 크기를 실제로 |
|
| 20 |
+ * 정의하는 건 @fox 쪽뿐이다(components/ui는 Tailwind 제거 이후 무스타일이다). |
|
| 20 | 21 |
*/ |
| 21 | 22 |
export function StudentRowActions({ member }: StudentRowActionsProps) {
|
| 22 | 23 |
const [isDetailOpen, setIsDetailOpen] = useState(false); |
| 23 | 24 |
|
| 24 | 25 |
return ( |
| 25 | 26 |
<> |
| 26 |
- <Button |
|
| 27 |
- type="button" |
|
| 28 |
- variant="ghost" |
|
| 27 |
+ <FoxIconButton |
|
| 28 |
+ type="ghost" |
|
| 29 | 29 |
size="sm" |
| 30 |
- onClick={() => setIsDetailOpen(true)}
|
|
| 31 |
- > |
|
| 32 |
- 조회 |
|
| 33 |
- </Button> |
|
| 30 |
+ icon={<FoxMagnifyingGlassIcon />}
|
|
| 31 |
+ label="조회" |
|
| 32 |
+ onAction={() => setIsDetailOpen(true)}
|
|
| 33 |
+ /> |
|
| 34 | 34 |
{isDetailOpen && (
|
| 35 | 35 |
<StudentDetailModal |
| 36 | 36 |
member={member}
|
--- components/ui/icons/monitor-icon.tsx
... | ... | @@ -1,34 +0,0 @@ |
| 1 | -interface MonitorIconProps { | |
| 2 | - /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-system:contents`) — | |
| 3 | - * 감싸는 `<span>`에 적용된다(`display: contents`는 CSS 스펙상 대체 요소인 `<svg>` | |
| 4 | - * 루트에는 적용되지 않고 `none`으로 계산되므로, 아이콘 자체가 아니라 span에 | |
| 5 | - * 걸어야 실제로 전환이 동작한다). 디자인 값(색상·치수 등) 주입은 금지 — 색은 | |
| 6 | - * 상위 요소의 currentColor를 상속한다. */ | |
| 7 | - className?: string; | |
| 8 | -} | |
| 9 | - | |
| 10 | -/** | |
| 11 | - * 시스템(OS) 테마를 상징하는 모니터 아이콘(화면 사각형 + 받침). 직접 작도한 인라인 SVG. | |
| 12 | - * `stroke="currentColor"`라 버튼 등 상위 요소의 text 색 토큰을 그대로 상속하며, | |
| 13 | - * 장식용이므로 `aria-hidden`을 부여한다 — 접근성 이름은 소비처(IconButton)가 책임진다. | |
| 14 | - */ | |
| 15 | -export function MonitorIcon({ className }: MonitorIconProps) { | |
| 16 | - return ( | |
| 17 | - <span className={className}> | |
| 18 | - <svg | |
| 19 | - viewBox="0 0 24 24" | |
| 20 | - fill="none" | |
| 21 | - stroke="currentColor" | |
| 22 | - strokeWidth="2" | |
| 23 | - strokeLinecap="round" | |
| 24 | - strokeLinejoin="round" | |
| 25 | - aria-hidden="true" | |
| 26 | - className="size-5" | |
| 27 | - > | |
| 28 | - <rect x="3" y="4" width="18" height="13" rx="1.5" /> | |
| 29 | - <path d="M8 21h8" /> | |
| 30 | - <path d="M12 17v4" /> | |
| 31 | - </svg> | |
| 32 | - </span> | |
| 33 | - ); | |
| 34 | -} |
--- components/ui/icons/moon-icon.tsx
... | ... | @@ -1,34 +0,0 @@ |
| 1 | -interface MoonIconProps { | |
| 2 | - /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-dark:contents`) — | |
| 3 | - * 감싸는 `<span>`에 적용된다(`display: contents`는 CSS 스펙상 대체 요소인 `<svg>` | |
| 4 | - * 루트에는 적용되지 않고 `none`으로 계산되므로, 아이콘 자체가 아니라 span에 | |
| 5 | - * 걸어야 실제로 전환이 동작한다). 디자인 값(색상·치수 등) 주입은 금지 — 색은 | |
| 6 | - * 상위 요소의 currentColor를 상속한다. */ | |
| 7 | - className?: string; | |
| 8 | -} | |
| 9 | - | |
| 10 | -/** | |
| 11 | - * 다크 테마를 상징하는 초승달 아이콘(단일 path). 직접 작도한 인라인 SVG — 큰 원호(외곽)와 | |
| 12 | - * 작은 원호(안쪽 오려내기)를 이어 붙인 표준 초승달 구성법을 사용했다(외부 아이콘 | |
| 13 | - * 저작물 복제 없음). | |
| 14 | - * `stroke="currentColor"`라 버튼 등 상위 요소의 text 색 토큰을 그대로 상속하며, | |
| 15 | - * 장식용이므로 `aria-hidden`을 부여한다 — 접근성 이름은 소비처(IconButton)가 책임진다. | |
| 16 | - */ | |
| 17 | -export function MoonIcon({ className }: MoonIconProps) { | |
| 18 | - return ( | |
| 19 | - <span className={className}> | |
| 20 | - <svg | |
| 21 | - viewBox="0 0 24 24" | |
| 22 | - fill="none" | |
| 23 | - stroke="currentColor" | |
| 24 | - strokeWidth="2" | |
| 25 | - strokeLinecap="round" | |
| 26 | - strokeLinejoin="round" | |
| 27 | - aria-hidden="true" | |
| 28 | - className="size-5" | |
| 29 | - > | |
| 30 | - <path d="M20 14.5A8.5 8.5 0 1 1 9.5 4A6.5 6.5 0 0 0 20 14.5Z" /> | |
| 31 | - </svg> | |
| 32 | - </span> | |
| 33 | - ); | |
| 34 | -} |
--- components/ui/icons/sun-icon.tsx
... | ... | @@ -1,40 +0,0 @@ |
| 1 | -interface SunIconProps { | |
| 2 | - /** 표시 제어용 클래스 패스스루(예: 테마 CSS 변형자 `hidden theme-light:contents`) — | |
| 3 | - * 감싸는 `<span>`에 적용된다(`display: contents`는 CSS 스펙상 대체 요소인 `<svg>` | |
| 4 | - * 루트에는 적용되지 않고 `none`으로 계산되므로, 아이콘 자체가 아니라 span에 | |
| 5 | - * 걸어야 실제로 전환이 동작한다). 디자인 값(색상·치수 등) 주입은 금지 — 색은 | |
| 6 | - * 상위 요소의 currentColor를 상속한다. */ | |
| 7 | - className?: string; | |
| 8 | -} | |
| 9 | - | |
| 10 | -/** | |
| 11 | - * 라이트 테마를 상징하는 해 아이콘(중심 원 + 8방향 광선). 직접 작도한 인라인 SVG. | |
| 12 | - * `stroke="currentColor"`라 버튼 등 상위 요소의 text 색 토큰을 그대로 상속하며, | |
| 13 | - * 장식용이므로 `aria-hidden`을 부여한다 — 접근성 이름은 소비처(IconButton)가 책임진다. | |
| 14 | - */ | |
| 15 | -export function SunIcon({ className }: SunIconProps) { | |
| 16 | - return ( | |
| 17 | - <span className={className}> | |
| 18 | - <svg | |
| 19 | - viewBox="0 0 24 24" | |
| 20 | - fill="none" | |
| 21 | - stroke="currentColor" | |
| 22 | - strokeWidth="2" | |
| 23 | - strokeLinecap="round" | |
| 24 | - strokeLinejoin="round" | |
| 25 | - aria-hidden="true" | |
| 26 | - className="size-5" | |
| 27 | - > | |
| 28 | - <circle cx="12" cy="12" r="4" /> | |
| 29 | - <path d="M12 2v2.5" /> | |
| 30 | - <path d="M12 19.5V22" /> | |
| 31 | - <path d="M2 12h2.5" /> | |
| 32 | - <path d="M19.5 12H22" /> | |
| 33 | - <path d="M4.93 4.93l1.77 1.77" /> | |
| 34 | - <path d="M17.3 17.3l1.77 1.77" /> | |
| 35 | - <path d="M4.93 19.07l1.77-1.77" /> | |
| 36 | - <path d="M17.3 6.7l1.77-1.77" /> | |
| 37 | - </svg> | |
| 38 | - </span> | |
| 39 | - ); | |
| 40 | -} |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?