@conscience-technology/ctds 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -2
- package/assets/components/AppFrame/AppFrame.module.css +177 -0
- package/assets/components/AppFrame/AppFrame.tsx +93 -0
- package/assets/components/AppFrame/index.ts +6 -0
- package/assets/components/AttachmentChip/AttachmentChip.module.css +71 -0
- package/assets/components/AttachmentChip/AttachmentChip.tsx +74 -0
- package/assets/components/AttachmentChip/index.ts +2 -0
- package/assets/components/AttachmentThumb/AttachmentThumb.module.css +107 -0
- package/assets/components/AttachmentThumb/AttachmentThumb.tsx +91 -0
- package/assets/components/AttachmentThumb/index.ts +2 -0
- package/assets/components/Avatar/Avatar.module.css +167 -0
- package/assets/components/Avatar/Avatar.tsx +228 -0
- package/assets/components/Avatar/index.ts +2 -0
- package/assets/components/AvatarUpload/AvatarUpload.module.css +130 -0
- package/assets/components/AvatarUpload/AvatarUpload.tsx +139 -0
- package/assets/components/AvatarUpload/index.ts +2 -0
- package/assets/components/Badge/Badge.module.css +76 -0
- package/assets/components/Badge/Badge.tsx +68 -0
- package/assets/components/Badge/index.ts +2 -0
- package/assets/components/Breadcrumb/Breadcrumb.module.css +213 -0
- package/assets/components/Breadcrumb/Breadcrumb.tsx +279 -0
- package/assets/components/Breadcrumb/index.ts +8 -0
- package/assets/components/Button/Button.module.css +216 -0
- package/assets/components/Button/Button.tsx +149 -0
- package/assets/components/Button/index.ts +2 -0
- package/assets/components/Callout/Callout.module.css +146 -0
- package/assets/components/Callout/Callout.tsx +138 -0
- package/assets/components/Callout/index.ts +2 -0
- package/assets/components/ChatInput/ChatInput.module.css +254 -0
- package/assets/components/ChatInput/ChatInput.tsx +322 -0
- package/assets/components/ChatInput/ModelSelector.tsx +40 -0
- package/assets/components/ChatInput/SendButton.tsx +41 -0
- package/assets/components/ChatInput/index.ts +10 -0
- package/assets/components/Checkbox/Checkbox.module.css +66 -0
- package/assets/components/Checkbox/Checkbox.tsx +36 -0
- package/assets/components/Checkbox/index.ts +2 -0
- package/assets/components/Chip/Chip.module.css +128 -0
- package/assets/components/Chip/Chip.tsx +103 -0
- package/assets/components/Chip/index.ts +2 -0
- package/assets/components/ChoiceCard/ChoiceCard.module.css +142 -0
- package/assets/components/ChoiceCard/ChoiceCard.tsx +132 -0
- package/assets/components/ChoiceCard/index.ts +2 -0
- package/assets/components/ContextMenu/ContextMenu.module.css +102 -0
- package/assets/components/ContextMenu/ContextMenu.tsx +392 -0
- package/assets/components/ContextMenu/index.ts +9 -0
- package/assets/components/DatePicker/Calendar.tsx +234 -0
- package/assets/components/DatePicker/DESIGN_NOTES.md +106 -0
- package/assets/components/DatePicker/DESIGN_NOTES_TIME.md +125 -0
- package/assets/components/DatePicker/DatePicker.module.css +295 -0
- package/assets/components/DatePicker/DatePicker.tsx +387 -0
- package/assets/components/DatePicker/TimeSelector.tsx +69 -0
- package/assets/components/DatePicker/index.ts +8 -0
- package/assets/components/DatePicker/presets.ts +80 -0
- package/assets/components/DatePicker/utils.ts +148 -0
- package/assets/components/Disclosure/Disclosure.module.css +73 -0
- package/assets/components/Disclosure/Disclosure.tsx +129 -0
- package/assets/components/Disclosure/index.ts +6 -0
- package/assets/components/Drawer/Drawer.module.css +257 -0
- package/assets/components/Drawer/Drawer.tsx +126 -0
- package/assets/components/Drawer/index.ts +7 -0
- package/assets/components/EmptyState/EmptyState.module.css +102 -0
- package/assets/components/EmptyState/EmptyState.tsx +80 -0
- package/assets/components/EmptyState/index.ts +2 -0
- package/assets/components/FileIcon/FileIcon.module.css +66 -0
- package/assets/components/FileIcon/FileIcon.tsx +84 -0
- package/assets/components/FileIcon/fileExtMap.ts +112 -0
- package/assets/components/FileIcon/index.ts +9 -0
- package/assets/components/FilterButton/FilterButton.module.css +130 -0
- package/assets/components/FilterButton/FilterButton.tsx +94 -0
- package/assets/components/FilterButton/index.ts +2 -0
- package/assets/components/GalleryItem/GalleryItem.module.css +220 -0
- package/assets/components/GalleryItem/GalleryItem.tsx +163 -0
- package/assets/components/GalleryItem/index.ts +7 -0
- package/assets/components/Icon/Icon.tsx +616 -0
- package/assets/components/Icon/context.tsx +39 -0
- package/assets/components/Icon/index.ts +4 -0
- package/assets/components/IconButton/IconButton.module.css +109 -0
- package/assets/components/IconButton/IconButton.tsx +110 -0
- package/assets/components/IconButton/index.ts +2 -0
- package/assets/components/Input/Input.module.css +338 -0
- package/assets/components/Input/Input.tsx +371 -0
- package/assets/components/Input/index.ts +2 -0
- package/assets/components/ListItem/ListItem.module.css +318 -0
- package/assets/components/ListItem/ListItem.tsx +262 -0
- package/assets/components/ListItem/index.ts +9 -0
- package/assets/components/MenuItem/MenuItem.module.css +437 -0
- package/assets/components/MenuItem/MenuItem.tsx +529 -0
- package/assets/components/MenuItem/index.ts +8 -0
- package/assets/components/MetricCard/MetricCard.module.css +153 -0
- package/assets/components/MetricCard/MetricCard.tsx +140 -0
- package/assets/components/MetricCard/index.ts +2 -0
- package/assets/components/Modal/Modal.module.css +175 -0
- package/assets/components/Modal/Modal.tsx +98 -0
- package/assets/components/Modal/index.ts +2 -0
- package/assets/components/Onboarding/DocsIndex.tsx +82 -0
- package/assets/components/Onboarding/LayoutBuilder.tsx +160 -0
- package/assets/components/Onboarding/Onboarding.module.css +1394 -0
- package/assets/components/Onboarding/OnboardingAxisPanel.tsx +515 -0
- package/assets/components/Onboarding/OnboardingPage.tsx +1193 -0
- package/assets/components/Onboarding/PresetsGallery.tsx +65 -0
- package/assets/components/Onboarding/actions.ts +250 -0
- package/assets/components/Onboarding/index.ts +8 -0
- package/assets/components/Onboarding/palette.css +40 -0
- package/assets/components/Onboarding/wizardData.ts +265 -0
- package/assets/components/Pagination/Pagination.module.css +82 -0
- package/assets/components/Pagination/Pagination.tsx +248 -0
- package/assets/components/Pagination/index.ts +6 -0
- package/assets/components/ProgressBar/ProgressBar.module.css +64 -0
- package/assets/components/ProgressBar/ProgressBar.tsx +54 -0
- package/assets/components/ProgressBar/index.ts +2 -0
- package/assets/components/QuotationBar/QuotationBar.module.css +61 -0
- package/assets/components/QuotationBar/QuotationBar.tsx +48 -0
- package/assets/components/QuotationBar/index.ts +2 -0
- package/assets/components/Radio/Radio.module.css +63 -0
- package/assets/components/Radio/Radio.tsx +33 -0
- package/assets/components/Radio/index.ts +2 -0
- package/assets/components/Select/Select.module.css +151 -0
- package/assets/components/Select/Select.tsx +425 -0
- package/assets/components/Select/index.ts +10 -0
- package/assets/components/SelectableCard/SelectableCard.module.css +177 -0
- package/assets/components/SelectableCard/SelectableCard.tsx +83 -0
- package/assets/components/SelectableCard/index.ts +2 -0
- package/assets/components/Shortcut/Shortcut.module.css +56 -0
- package/assets/components/Shortcut/Shortcut.tsx +156 -0
- package/assets/components/Shortcut/index.ts +2 -0
- package/assets/components/Sidebar/Sidebar.module.css +242 -0
- package/assets/components/Sidebar/Sidebar.tsx +264 -0
- package/assets/components/Sidebar/index.ts +7 -0
- package/assets/components/SidebarSplit/SidebarSplit.module.css +126 -0
- package/assets/components/SidebarSplit/SidebarSplit.tsx +222 -0
- package/assets/components/SidebarSplit/index.ts +6 -0
- package/assets/components/Slider/Slider.module.css +120 -0
- package/assets/components/Slider/Slider.tsx +88 -0
- package/assets/components/Slider/index.ts +2 -0
- package/assets/components/SplitButton/SplitButton.module.css +190 -0
- package/assets/components/SplitButton/SplitButton.tsx +145 -0
- package/assets/components/SplitButton/index.ts +6 -0
- package/assets/components/Stepper/Stepper.module.css +182 -0
- package/assets/components/Stepper/Stepper.tsx +185 -0
- package/assets/components/Stepper/index.ts +2 -0
- package/assets/components/Switch/Switch.module.css +116 -0
- package/assets/components/Switch/Switch.tsx +58 -0
- package/assets/components/Switch/index.ts +2 -0
- package/assets/components/TableCell/TableCell.module.css +137 -0
- package/assets/components/TableCell/TableCellAvatar.tsx +42 -0
- package/assets/components/TableCell/TableCellBadge.tsx +23 -0
- package/assets/components/TableCell/TableCellIcon.tsx +39 -0
- package/assets/components/TableCell/TableCellImage.tsx +49 -0
- package/assets/components/TableCell/TableCellLink.tsx +33 -0
- package/assets/components/TableCell/TableCellMeter.tsx +55 -0
- package/assets/components/TableCell/TableCellNumber.tsx +43 -0
- package/assets/components/TableCell/TableCellText.tsx +30 -0
- package/assets/components/TableCell/index.ts +23 -0
- package/assets/components/TableHeader/TableHeader.module.css +287 -0
- package/assets/components/TableHeader/TableHeader.tsx +590 -0
- package/assets/components/TableHeader/index.ts +9 -0
- package/assets/components/TableRow/TableRow.module.css +290 -0
- package/assets/components/TableRow/TableRow.tsx +253 -0
- package/assets/components/TableRow/index.ts +8 -0
- package/assets/components/TableRowEdit/TableRowEdit.module.css +126 -0
- package/assets/components/TableRowEdit/TableRowEdit.tsx +247 -0
- package/assets/components/TableRowEdit/index.ts +2 -0
- package/assets/components/TableRowSelect/TableRowSelect.module.css +23 -0
- package/assets/components/TableRowSelect/TableRowSelect.tsx +175 -0
- package/assets/components/TableRowSelect/index.ts +2 -0
- package/assets/components/Tabs/Tabs.module.css +234 -0
- package/assets/components/Tabs/Tabs.tsx +426 -0
- package/assets/components/Tabs/index.ts +9 -0
- package/assets/components/Textarea/Textarea.module.css +318 -0
- package/assets/components/Textarea/Textarea.tsx +426 -0
- package/assets/components/Textarea/index.ts +7 -0
- package/assets/components/ThemeController.tsx +271 -0
- package/assets/components/TimePicker/TimePicker.module.css +317 -0
- package/assets/components/TimePicker/TimePicker.tsx +821 -0
- package/assets/components/TimePicker/index.ts +8 -0
- package/assets/components/TimePicker/utils.ts +115 -0
- package/assets/components/Toast/Toast.module.css +264 -0
- package/assets/components/Toast/Toast.tsx +243 -0
- package/assets/components/Toast/index.ts +15 -0
- package/assets/components/Toolbar/Toolbar.module.css +72 -0
- package/assets/components/Toolbar/Toolbar.tsx +75 -0
- package/assets/components/Toolbar/index.ts +2 -0
- package/assets/components/Tooltip/Tooltip.module.css +42 -0
- package/assets/components/Tooltip/Tooltip.tsx +332 -0
- package/assets/components/Tooltip/index.ts +2 -0
- package/assets/components/Topbar/Topbar.module.css +26 -0
- package/assets/components/Topbar/Topbar.tsx +47 -0
- package/assets/components/Topbar/index.ts +2 -0
- package/assets/components/_cn.ts +3 -0
- package/assets/components/_color.ts +48 -0
- package/assets/components/_data.ts +659 -0
- package/assets/components/_utils.css +19 -0
- package/assets/components/axisOptions.ts +24 -0
- package/assets/components/tokens.css +742 -0
- package/assets/prompts/GUIDE.md +251 -0
- package/assets/prompts/OVERRIDE.md +170 -0
- package/assets/prompts/PRINCIPLES.md +130 -0
- package/assets/prompts/axes/density.md +38 -0
- package/assets/prompts/axes/font.md +36 -0
- package/assets/prompts/axes/hue.md +36 -0
- package/assets/prompts/axes/icon.md +48 -0
- package/assets/prompts/axes/mode.md +50 -0
- package/assets/prompts/axes/motion.md +77 -0
- package/assets/prompts/axes/palette.md +35 -0
- package/assets/prompts/axes/shape.md +33 -0
- package/assets/prompts/axes/voice.md +54 -0
- package/assets/prompts/components/README.md +84 -0
- package/assets/prompts/components/app-frame.md +94 -0
- package/assets/prompts/components/attachment-chip.md +46 -0
- package/assets/prompts/components/attachment-thumb.md +49 -0
- package/assets/prompts/components/avatar.md +86 -0
- package/assets/prompts/components/badge.md +104 -0
- package/assets/prompts/components/breadcrumb.md +77 -0
- package/assets/prompts/components/button.md +99 -0
- package/assets/prompts/components/callout.md +81 -0
- package/assets/prompts/components/chat-input.md +84 -0
- package/assets/prompts/components/checkbox.md +46 -0
- package/assets/prompts/components/chip.md +84 -0
- package/assets/prompts/components/choice-card.md +127 -0
- package/assets/prompts/components/context-menu.md +145 -0
- package/assets/prompts/components/date-picker.md +104 -0
- package/assets/prompts/components/drawer.md +152 -0
- package/assets/prompts/components/empty-state.md +69 -0
- package/assets/prompts/components/file-icon.md +73 -0
- package/assets/prompts/components/filter-button.md +42 -0
- package/assets/prompts/components/form-field.md +74 -0
- package/assets/prompts/components/gallery-item.md +158 -0
- package/assets/prompts/components/icon-button.md +82 -0
- package/assets/prompts/components/icon.md +68 -0
- package/assets/prompts/components/input.md +95 -0
- package/assets/prompts/components/list-item.md +235 -0
- package/assets/prompts/components/menu-item.md +234 -0
- package/assets/prompts/components/metric-card.md +132 -0
- package/assets/prompts/components/modal.md +131 -0
- package/assets/prompts/components/pagination.md +92 -0
- package/assets/prompts/components/progress-bar.md +61 -0
- package/assets/prompts/components/quotation-bar.md +39 -0
- package/assets/prompts/components/radio.md +41 -0
- package/assets/prompts/components/select.md +104 -0
- package/assets/prompts/components/selectable-card.md +67 -0
- package/assets/prompts/components/shortcut.md +76 -0
- package/assets/prompts/components/sidebar.md +107 -0
- package/assets/prompts/components/slider.md +89 -0
- package/assets/prompts/components/split-button.md +71 -0
- package/assets/prompts/components/stepper.md +93 -0
- package/assets/prompts/components/switch.md +86 -0
- package/assets/prompts/components/table-cell.md +87 -0
- package/assets/prompts/components/table-header.md +157 -0
- package/assets/prompts/components/table-row-edit.md +129 -0
- package/assets/prompts/components/table-row-select.md +82 -0
- package/assets/prompts/components/table-row.md +156 -0
- package/assets/prompts/components/tabs.md +122 -0
- package/assets/prompts/components/textarea.md +105 -0
- package/assets/prompts/components/toast.md +149 -0
- package/assets/prompts/components/tooltip.md +71 -0
- package/assets/prompts/components/topbar.md +148 -0
- package/assets/prompts/primitives/emerge.md +43 -0
- package/assets/prompts/primitives/fade.md +31 -0
- package/assets/prompts/primitives/scale.md +32 -0
- package/assets/prompts/primitives/scroll.md +75 -0
- package/assets/prompts/primitives/slide.md +31 -0
- package/assets/prompts/themes/_SCHEMA.md +135 -0
- package/assets/prompts/themes/_TEMPLATE.md +73 -0
- package/assets/prompts/themes/expressive.md +118 -0
- package/assets/prompts/themes/pure.md +87 -0
- package/assets/prompts/themes/spare.md +73 -0
- package/assets/prompts/tokens/breakpoint.md +29 -0
- package/assets/prompts/tokens/color.md +78 -0
- package/assets/prompts/tokens/radius.md +33 -0
- package/assets/prompts/tokens/shadow.md +35 -0
- package/assets/prompts/tokens/spacing.md +86 -0
- package/assets/prompts/tokens/typography.md +76 -0
- package/assets/prompts/tokens/z-index.md +35 -0
- package/assets/public/expressive.png +0 -0
- package/assets/public/pure.png +0 -0
- package/assets/public/spare.png +0 -0
- package/assets/skill/SKILL.md +36 -0
- package/bin/ctds.js +76 -0
- package/package.json +35 -4
- package/src/commands/init.js +215 -0
- package/src/commands/update.js +275 -0
- package/src/utils/assets.js +78 -0
- package/src/utils/deps.js +51 -0
- package/src/utils/detect.js +47 -0
- package/src/utils/diff.js +52 -0
- package/src/utils/hash.js +16 -0
- package/src/utils/log.js +41 -0
- package/src/utils/meta.js +73 -0
- package/src/utils/prompt.js +28 -0
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 의미 기반 Icon 컴포넌트.
|
|
5
|
+
*
|
|
6
|
+
* 설계 원칙 — "family별 독립 세트":
|
|
7
|
+
* - 각 family(phosphor/solar/lucide)는 자기만의 아이콘 세트를 가진다.
|
|
8
|
+
* - 서로 다른 라이브러리 간의 "의미 매핑"은 하지 않는다.
|
|
9
|
+
* (search 하나를 phosphor·solar·lucide 세 군데에서 억지로 연결하지 않음)
|
|
10
|
+
* - 활성 family에 해당 이름이 없으면 그 family 전용 placeholder 아이콘을 렌더.
|
|
11
|
+
* (레이아웃 공간 유지 + 축 전환 시 "어떤 아이콘이 그 family엔 없다"는 사실이 시각적으로 드러남)
|
|
12
|
+
*
|
|
13
|
+
* weight(regular/fill) 반응:
|
|
14
|
+
* phosphor → weight prop으로 반응
|
|
15
|
+
* solar → Linear(regular) / Bold(fill) 두 컴포넌트 분기
|
|
16
|
+
* lucide → regular만 (fill 요청 시 regular 그대로)
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import * as React from "react";
|
|
20
|
+
import type { IconFamily, IconWeight } from "../_data";
|
|
21
|
+
import { useIconAxis } from "./context";
|
|
22
|
+
|
|
23
|
+
// Phosphor ─────────────────────────────────────────────────────────
|
|
24
|
+
import {
|
|
25
|
+
Check as PhCheck,
|
|
26
|
+
Warning as PhWarning,
|
|
27
|
+
Star as PhStar,
|
|
28
|
+
Heart as PhHeart,
|
|
29
|
+
User as PhUser,
|
|
30
|
+
MagnifyingGlass as PhSearch,
|
|
31
|
+
Gear as PhGear,
|
|
32
|
+
Trash as PhTrash,
|
|
33
|
+
ArrowRight as PhArrowRight,
|
|
34
|
+
X as PhX,
|
|
35
|
+
Sun as PhSun,
|
|
36
|
+
Moon as PhMoon,
|
|
37
|
+
CaretDown as PhCaretDown,
|
|
38
|
+
CaretLeft as PhCaretLeft,
|
|
39
|
+
CaretRight as PhCaretRight,
|
|
40
|
+
CaretUp as PhCaretUp,
|
|
41
|
+
CaretUpDown as PhCaretUpDown,
|
|
42
|
+
CaretDoubleLeft as PhCaretDoubleLeft,
|
|
43
|
+
CaretDoubleRight as PhCaretDoubleRight,
|
|
44
|
+
Columns as PhColumns,
|
|
45
|
+
House as PhHouse,
|
|
46
|
+
Palette as PhPalette,
|
|
47
|
+
Ruler as PhRuler,
|
|
48
|
+
Square as PhSquare,
|
|
49
|
+
TextAa as PhTextAa,
|
|
50
|
+
PaintBucket as PhPaintBucket,
|
|
51
|
+
Stack as PhStack,
|
|
52
|
+
Waveform as PhWaveform,
|
|
53
|
+
Devices as PhDevices,
|
|
54
|
+
SquaresFour as PhSquaresFour,
|
|
55
|
+
CursorClick as PhCursorClick,
|
|
56
|
+
SplitVertical as PhSplitVertical,
|
|
57
|
+
Rectangle as PhRectangle,
|
|
58
|
+
List as PhList,
|
|
59
|
+
Rows as PhRows,
|
|
60
|
+
SealCheck as PhSealCheck,
|
|
61
|
+
UserCircle as PhUserCircle,
|
|
62
|
+
Info as PhInfo,
|
|
63
|
+
Tag as PhTag,
|
|
64
|
+
Minus as PhMinus,
|
|
65
|
+
Plus as PhPlus,
|
|
66
|
+
Placeholder as PhPlaceholder,
|
|
67
|
+
Textbox as PhTextbox,
|
|
68
|
+
Keyboard as PhKeyboard,
|
|
69
|
+
Article as PhArticle,
|
|
70
|
+
Selection as PhSelection,
|
|
71
|
+
CheckSquare as PhCheckSquare,
|
|
72
|
+
RadioButton as PhRadioButton,
|
|
73
|
+
ToggleRight as PhToggleRight,
|
|
74
|
+
ToggleLeft as PhToggleLeft,
|
|
75
|
+
Sliders as PhSliders,
|
|
76
|
+
Calendar as PhCalendar,
|
|
77
|
+
CalendarBlank as PhCalendarBlank,
|
|
78
|
+
CalendarDots as PhCalendarDots,
|
|
79
|
+
Clock as PhClock,
|
|
80
|
+
UploadSimple as PhUploadSimple,
|
|
81
|
+
IdentificationCard as PhIdentificationCard,
|
|
82
|
+
Table as PhTable,
|
|
83
|
+
GridFour as PhGridFour,
|
|
84
|
+
ListBullets as PhListBullets,
|
|
85
|
+
Cards as PhCards,
|
|
86
|
+
ChartLine as PhChartLine,
|
|
87
|
+
TrendUp as PhTrendUp,
|
|
88
|
+
TrendDown as PhTrendDown,
|
|
89
|
+
Empty as PhEmpty,
|
|
90
|
+
ListDashes as PhListDashes,
|
|
91
|
+
LineSegments as PhLineSegments,
|
|
92
|
+
Tabs as PhTabs,
|
|
93
|
+
Path as PhPath,
|
|
94
|
+
Sidebar as PhSidebar,
|
|
95
|
+
SidebarSimple as PhSidebarSimple,
|
|
96
|
+
DotsThree as PhDotsThree,
|
|
97
|
+
Compass as PhCompass,
|
|
98
|
+
Steps as PhSteps,
|
|
99
|
+
WarningCircle as PhWarningCircle,
|
|
100
|
+
CheckCircle as PhCheckCircle,
|
|
101
|
+
SquareHalf as PhSquareHalf,
|
|
102
|
+
ChatCircle as PhChatCircle,
|
|
103
|
+
ChatText as PhChatText,
|
|
104
|
+
Broadcast as PhBroadcast,
|
|
105
|
+
Bell as PhBell,
|
|
106
|
+
Megaphone as PhMegaphone,
|
|
107
|
+
Speedometer as PhSpeedometer,
|
|
108
|
+
CircleNotch as PhCircleNotch,
|
|
109
|
+
DotsThreeOutline as PhDotsThreeOutline,
|
|
110
|
+
CaretCircleDown as PhCaretCircleDown,
|
|
111
|
+
Command as PhCommand,
|
|
112
|
+
RowsPlusBottom as PhRowsPlusBottom,
|
|
113
|
+
MinusSquare as PhMinusSquare,
|
|
114
|
+
BracketsSquare as PhBracketsSquare,
|
|
115
|
+
GridNine as PhGridNine,
|
|
116
|
+
ArrowsVertical as PhArrowsVertical,
|
|
117
|
+
SplitHorizontal as PhSplitHorizontal,
|
|
118
|
+
Layout as PhLayout,
|
|
119
|
+
Envelope as PhEnvelope,
|
|
120
|
+
Eye as PhEye,
|
|
121
|
+
EyeSlash as PhEyeSlash,
|
|
122
|
+
ArrowSquareOut as PhArrowSquareOut,
|
|
123
|
+
PencilSimple as PhPencilSimple,
|
|
124
|
+
ShareNetwork as PhShareNetwork,
|
|
125
|
+
Copy as PhCopy,
|
|
126
|
+
CopySimple as PhCopySimple,
|
|
127
|
+
Scissors as PhScissors,
|
|
128
|
+
ClipboardText as PhClipboardText,
|
|
129
|
+
Camera as PhCamera,
|
|
130
|
+
} from "@phosphor-icons/react";
|
|
131
|
+
|
|
132
|
+
// Solar (Linear = regular, Bold = fill) ───────────────────────────
|
|
133
|
+
import {
|
|
134
|
+
DangerTriangleLinear as SoWarningL, DangerTriangleBold as SoWarningB,
|
|
135
|
+
StarLinear as SoStarL, StarBold as SoStarB,
|
|
136
|
+
HeartLinear as SoHeartL, HeartBold as SoHeartB,
|
|
137
|
+
UserLinear as SoUserL, UserBold as SoUserB,
|
|
138
|
+
MagniferLinear as SoSearchL, MagniferBold as SoSearchB,
|
|
139
|
+
SettingsLinear as SoGearL, SettingsBold as SoGearB,
|
|
140
|
+
TrashBinMinimalisticLinear as SoTrashL, TrashBinMinimalisticBold as SoTrashB,
|
|
141
|
+
ArrowRightLinear as SoArrowRightL, ArrowRightBold as SoArrowRightB,
|
|
142
|
+
SunLinear as SoSunL, SunBold as SoSunB,
|
|
143
|
+
MoonLinear as SoMoonL, MoonBold as SoMoonB,
|
|
144
|
+
AltArrowDownLinear as SoCaretDownL, AltArrowDownBold as SoCaretDownB,
|
|
145
|
+
AltArrowLeftLinear as SoCaretLeftL, AltArrowLeftBold as SoCaretLeftB,
|
|
146
|
+
AltArrowRightLinear as SoCaretRightL, AltArrowRightBold as SoCaretRightB,
|
|
147
|
+
AltArrowUpLinear as SoCaretUpL, AltArrowUpBold as SoCaretUpB,
|
|
148
|
+
SortVerticalLinear as SoCaretUpDownL, SortVerticalBold as SoCaretUpDownB,
|
|
149
|
+
DoubleAltArrowLeftLinear as SoCaretDoubleLeftL, DoubleAltArrowLeftBold as SoCaretDoubleLeftB,
|
|
150
|
+
DoubleAltArrowRightLinear as SoCaretDoubleRightL, DoubleAltArrowRightBold as SoCaretDoubleRightB,
|
|
151
|
+
ScissorsLinear as SoScissorsL, ScissorsBold as SoScissorsB,
|
|
152
|
+
CopyLinear as SoCopyL, CopyBold as SoCopyB,
|
|
153
|
+
ClipboardTextLinear as SoClipboardTextL, ClipboardTextBold as SoClipboardTextB,
|
|
154
|
+
ShareLinear as SoShareL, ShareBold as SoShareB,
|
|
155
|
+
SquareTopUpLinear as SoSquareTopUpL, SquareTopUpBold as SoSquareTopUpB,
|
|
156
|
+
PenLinear as SoPenL, PenBold as SoPenB,
|
|
157
|
+
DocumentTextLinear as SoDocumentTextL, DocumentTextBold as SoDocumentTextB,
|
|
158
|
+
InfoCircleLinear as SoInfoCircleL, InfoCircleBold as SoInfoCircleB,
|
|
159
|
+
ListLinear as SoListL, ListBold as SoListB,
|
|
160
|
+
Widget5Linear as SoWidget5L, Widget5Bold as SoWidget5B,
|
|
161
|
+
Widget2Linear as SoWidget2L, Widget2Bold as SoWidget2B,
|
|
162
|
+
} from "solar-icon-set";
|
|
163
|
+
|
|
164
|
+
// Lucide ──────────────────────────────────────────────────────────
|
|
165
|
+
import {
|
|
166
|
+
Check as LuCheck,
|
|
167
|
+
AlertTriangle as LuWarning,
|
|
168
|
+
Star as LuStar,
|
|
169
|
+
Heart as LuHeart,
|
|
170
|
+
User as LuUser,
|
|
171
|
+
Search as LuSearch,
|
|
172
|
+
Settings as LuGear,
|
|
173
|
+
Trash as LuTrash,
|
|
174
|
+
ArrowRight as LuArrowRight,
|
|
175
|
+
X as LuX,
|
|
176
|
+
Sun as LuSun,
|
|
177
|
+
Moon as LuMoon,
|
|
178
|
+
ChevronDown as LuCaretDown,
|
|
179
|
+
ChevronLeft as LuCaretLeft,
|
|
180
|
+
ChevronRight as LuCaretRight,
|
|
181
|
+
ChevronUp as LuCaretUp,
|
|
182
|
+
ChevronsUpDown as LuCaretUpDown,
|
|
183
|
+
ChevronsLeft as LuCaretDoubleLeft,
|
|
184
|
+
ChevronsRight as LuCaretDoubleRight,
|
|
185
|
+
Columns as LuColumns,
|
|
186
|
+
Scissors as LuScissors,
|
|
187
|
+
Copy as LuCopy,
|
|
188
|
+
Files as LuFiles,
|
|
189
|
+
ClipboardType as LuClipboardType,
|
|
190
|
+
Share2 as LuShare,
|
|
191
|
+
ExternalLink as LuExternalLink,
|
|
192
|
+
Pencil as LuPencil,
|
|
193
|
+
FileText as LuFileText,
|
|
194
|
+
Info as LuInfo,
|
|
195
|
+
List as LuList,
|
|
196
|
+
LayoutGrid as LuLayoutGrid,
|
|
197
|
+
Grid3X3 as LuGrid3X3,
|
|
198
|
+
Square as LuSquare,
|
|
199
|
+
} from "lucide-react";
|
|
200
|
+
|
|
201
|
+
// 표준 아이콘 이름. family별 세트가 서로 완전히 겹칠 필요 없음 — 각 family에
|
|
202
|
+
// 있는 것만 렌더하고 나머지는 family별 placeholder로 떨어진다.
|
|
203
|
+
export type IconName =
|
|
204
|
+
| "check"
|
|
205
|
+
| "warning"
|
|
206
|
+
| "star"
|
|
207
|
+
| "heart"
|
|
208
|
+
| "user"
|
|
209
|
+
| "search"
|
|
210
|
+
| "gear"
|
|
211
|
+
| "trash"
|
|
212
|
+
| "arrow-right"
|
|
213
|
+
| "arrows-down-up"
|
|
214
|
+
| "x"
|
|
215
|
+
| "sun"
|
|
216
|
+
| "moon"
|
|
217
|
+
| "caret-down"
|
|
218
|
+
| "caret-left"
|
|
219
|
+
| "caret-right"
|
|
220
|
+
| "caret-up"
|
|
221
|
+
| "caret-up-down"
|
|
222
|
+
| "caret-double-left"
|
|
223
|
+
| "caret-double-right"
|
|
224
|
+
| "columns"
|
|
225
|
+
| "house"
|
|
226
|
+
| "palette"
|
|
227
|
+
| "ruler"
|
|
228
|
+
| "square"
|
|
229
|
+
| "text-aa"
|
|
230
|
+
| "paint-bucket"
|
|
231
|
+
| "stack"
|
|
232
|
+
| "waveform"
|
|
233
|
+
| "devices"
|
|
234
|
+
| "squares-four"
|
|
235
|
+
| "cursor-click"
|
|
236
|
+
| "split-vertical"
|
|
237
|
+
| "rectangle"
|
|
238
|
+
| "list"
|
|
239
|
+
| "rows"
|
|
240
|
+
| "seal-check"
|
|
241
|
+
| "user-circle"
|
|
242
|
+
| "info"
|
|
243
|
+
| "tag"
|
|
244
|
+
| "minus"
|
|
245
|
+
| "plus"
|
|
246
|
+
| "placeholder"
|
|
247
|
+
| "textbox"
|
|
248
|
+
| "keyboard"
|
|
249
|
+
| "article"
|
|
250
|
+
| "selection"
|
|
251
|
+
| "check-square"
|
|
252
|
+
| "radio-button"
|
|
253
|
+
| "toggle-right"
|
|
254
|
+
| "toggle-left"
|
|
255
|
+
| "sliders"
|
|
256
|
+
| "calendar"
|
|
257
|
+
| "calendar-blank"
|
|
258
|
+
| "calendar-dots"
|
|
259
|
+
| "clock"
|
|
260
|
+
| "upload-simple"
|
|
261
|
+
| "identification-card"
|
|
262
|
+
| "table"
|
|
263
|
+
| "grid-four"
|
|
264
|
+
| "list-bullets"
|
|
265
|
+
| "cards"
|
|
266
|
+
| "chart-line"
|
|
267
|
+
| "trend-up"
|
|
268
|
+
| "trend-down"
|
|
269
|
+
| "empty"
|
|
270
|
+
| "list-dashes"
|
|
271
|
+
| "line-segments"
|
|
272
|
+
| "tabs"
|
|
273
|
+
| "path"
|
|
274
|
+
| "sidebar"
|
|
275
|
+
| "sidebar-simple"
|
|
276
|
+
| "dots-three"
|
|
277
|
+
| "compass"
|
|
278
|
+
| "steps"
|
|
279
|
+
| "warning-circle"
|
|
280
|
+
| "check-circle"
|
|
281
|
+
| "square-half"
|
|
282
|
+
| "chat-circle"
|
|
283
|
+
| "chat-text"
|
|
284
|
+
| "broadcast"
|
|
285
|
+
| "bell"
|
|
286
|
+
| "megaphone"
|
|
287
|
+
| "speedometer"
|
|
288
|
+
| "circle-notch"
|
|
289
|
+
| "dots-three-outline"
|
|
290
|
+
| "caret-circle-down"
|
|
291
|
+
| "command"
|
|
292
|
+
| "rows-plus-bottom"
|
|
293
|
+
| "minus-square"
|
|
294
|
+
| "brackets-square"
|
|
295
|
+
| "grid-nine"
|
|
296
|
+
| "arrows-vertical"
|
|
297
|
+
| "split-horizontal"
|
|
298
|
+
| "layout"
|
|
299
|
+
| "envelope"
|
|
300
|
+
| "eye"
|
|
301
|
+
| "eye-slash"
|
|
302
|
+
| "arrow-square-out"
|
|
303
|
+
| "pencil-simple"
|
|
304
|
+
| "share-network"
|
|
305
|
+
| "copy"
|
|
306
|
+
| "copy-simple"
|
|
307
|
+
| "scissors"
|
|
308
|
+
| "clipboard-text"
|
|
309
|
+
| "camera";
|
|
310
|
+
|
|
311
|
+
type AnyComp = React.ComponentType<any>;
|
|
312
|
+
// Solar는 weight별 두 컴포넌트가 필요. 다른 family는 단일 컴포넌트.
|
|
313
|
+
type SolarPair = { regular: AnyComp; fill: AnyComp };
|
|
314
|
+
|
|
315
|
+
/* phosphor 세트 — 가장 풍부. 지금까지 쓰던 아이콘 전원 보유. */
|
|
316
|
+
const phosphorSet: Partial<Record<IconName, AnyComp>> = {
|
|
317
|
+
check: PhCheck,
|
|
318
|
+
warning: PhWarning,
|
|
319
|
+
star: PhStar,
|
|
320
|
+
heart: PhHeart,
|
|
321
|
+
user: PhUser,
|
|
322
|
+
search: PhSearch,
|
|
323
|
+
gear: PhGear,
|
|
324
|
+
trash: PhTrash,
|
|
325
|
+
"arrow-right": PhArrowRight,
|
|
326
|
+
x: PhX,
|
|
327
|
+
sun: PhSun,
|
|
328
|
+
moon: PhMoon,
|
|
329
|
+
"caret-down": PhCaretDown,
|
|
330
|
+
"caret-left": PhCaretLeft,
|
|
331
|
+
"caret-right": PhCaretRight,
|
|
332
|
+
"caret-up": PhCaretUp,
|
|
333
|
+
"caret-up-down": PhCaretUpDown,
|
|
334
|
+
"caret-double-left": PhCaretDoubleLeft,
|
|
335
|
+
"caret-double-right": PhCaretDoubleRight,
|
|
336
|
+
columns: PhColumns,
|
|
337
|
+
house: PhHouse,
|
|
338
|
+
palette: PhPalette,
|
|
339
|
+
ruler: PhRuler,
|
|
340
|
+
square: PhSquare,
|
|
341
|
+
"text-aa": PhTextAa,
|
|
342
|
+
"paint-bucket": PhPaintBucket,
|
|
343
|
+
stack: PhStack,
|
|
344
|
+
waveform: PhWaveform,
|
|
345
|
+
devices: PhDevices,
|
|
346
|
+
"squares-four": PhSquaresFour,
|
|
347
|
+
"cursor-click": PhCursorClick,
|
|
348
|
+
"split-vertical": PhSplitVertical,
|
|
349
|
+
rectangle: PhRectangle,
|
|
350
|
+
list: PhList,
|
|
351
|
+
rows: PhRows,
|
|
352
|
+
"seal-check": PhSealCheck,
|
|
353
|
+
"user-circle": PhUserCircle,
|
|
354
|
+
info: PhInfo,
|
|
355
|
+
tag: PhTag,
|
|
356
|
+
minus: PhMinus,
|
|
357
|
+
plus: PhPlus,
|
|
358
|
+
placeholder: PhPlaceholder,
|
|
359
|
+
textbox: PhTextbox,
|
|
360
|
+
keyboard: PhKeyboard,
|
|
361
|
+
article: PhArticle,
|
|
362
|
+
selection: PhSelection,
|
|
363
|
+
"check-square": PhCheckSquare,
|
|
364
|
+
"radio-button": PhRadioButton,
|
|
365
|
+
"toggle-right": PhToggleRight,
|
|
366
|
+
"toggle-left": PhToggleLeft,
|
|
367
|
+
sliders: PhSliders,
|
|
368
|
+
calendar: PhCalendar,
|
|
369
|
+
"calendar-blank": PhCalendarBlank,
|
|
370
|
+
"calendar-dots": PhCalendarDots,
|
|
371
|
+
clock: PhClock,
|
|
372
|
+
"upload-simple": PhUploadSimple,
|
|
373
|
+
"identification-card": PhIdentificationCard,
|
|
374
|
+
table: PhTable,
|
|
375
|
+
"grid-four": PhGridFour,
|
|
376
|
+
"list-bullets": PhListBullets,
|
|
377
|
+
cards: PhCards,
|
|
378
|
+
"chart-line": PhChartLine,
|
|
379
|
+
"trend-up": PhTrendUp,
|
|
380
|
+
"trend-down": PhTrendDown,
|
|
381
|
+
empty: PhEmpty,
|
|
382
|
+
"list-dashes": PhListDashes,
|
|
383
|
+
"line-segments": PhLineSegments,
|
|
384
|
+
tabs: PhTabs,
|
|
385
|
+
path: PhPath,
|
|
386
|
+
sidebar: PhSidebar,
|
|
387
|
+
"sidebar-simple": PhSidebarSimple,
|
|
388
|
+
"dots-three": PhDotsThree,
|
|
389
|
+
compass: PhCompass,
|
|
390
|
+
steps: PhSteps,
|
|
391
|
+
"warning-circle": PhWarningCircle,
|
|
392
|
+
"check-circle": PhCheckCircle,
|
|
393
|
+
"square-half": PhSquareHalf,
|
|
394
|
+
"chat-circle": PhChatCircle,
|
|
395
|
+
"chat-text": PhChatText,
|
|
396
|
+
broadcast: PhBroadcast,
|
|
397
|
+
bell: PhBell,
|
|
398
|
+
megaphone: PhMegaphone,
|
|
399
|
+
speedometer: PhSpeedometer,
|
|
400
|
+
"circle-notch": PhCircleNotch,
|
|
401
|
+
"dots-three-outline": PhDotsThreeOutline,
|
|
402
|
+
"caret-circle-down": PhCaretCircleDown,
|
|
403
|
+
command: PhCommand,
|
|
404
|
+
"rows-plus-bottom": PhRowsPlusBottom,
|
|
405
|
+
"minus-square": PhMinusSquare,
|
|
406
|
+
"brackets-square": PhBracketsSquare,
|
|
407
|
+
"grid-nine": PhGridNine,
|
|
408
|
+
"arrows-vertical": PhArrowsVertical,
|
|
409
|
+
"split-horizontal": PhSplitHorizontal,
|
|
410
|
+
layout: PhLayout,
|
|
411
|
+
envelope: PhEnvelope,
|
|
412
|
+
eye: PhEye,
|
|
413
|
+
"eye-slash": PhEyeSlash,
|
|
414
|
+
"arrow-square-out": PhArrowSquareOut,
|
|
415
|
+
"pencil-simple": PhPencilSimple,
|
|
416
|
+
"share-network": PhShareNetwork,
|
|
417
|
+
copy: PhCopy,
|
|
418
|
+
"copy-simple": PhCopySimple,
|
|
419
|
+
scissors: PhScissors,
|
|
420
|
+
"clipboard-text": PhClipboardText,
|
|
421
|
+
camera: PhCamera,
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
/* solar 세트 — 라이브러리에 자연스러운 1:1 대응이 있는 것만.
|
|
425
|
+
매핑 안 된 이름은 solar family에서 placeholder로 떨어진다. */
|
|
426
|
+
const solarSet: Partial<Record<IconName, SolarPair>> = {
|
|
427
|
+
warning: { regular: SoWarningL, fill: SoWarningB },
|
|
428
|
+
star: { regular: SoStarL, fill: SoStarB },
|
|
429
|
+
heart: { regular: SoHeartL, fill: SoHeartB },
|
|
430
|
+
user: { regular: SoUserL, fill: SoUserB },
|
|
431
|
+
search: { regular: SoSearchL, fill: SoSearchB },
|
|
432
|
+
gear: { regular: SoGearL, fill: SoGearB },
|
|
433
|
+
trash: { regular: SoTrashL, fill: SoTrashB },
|
|
434
|
+
"arrow-right": { regular: SoArrowRightL, fill: SoArrowRightB },
|
|
435
|
+
sun: { regular: SoSunL, fill: SoSunB },
|
|
436
|
+
moon: { regular: SoMoonL, fill: SoMoonB },
|
|
437
|
+
"caret-down": { regular: SoCaretDownL, fill: SoCaretDownB },
|
|
438
|
+
"caret-left": { regular: SoCaretLeftL, fill: SoCaretLeftB },
|
|
439
|
+
"caret-right": { regular: SoCaretRightL, fill: SoCaretRightB },
|
|
440
|
+
"caret-up": { regular: SoCaretUpL, fill: SoCaretUpB },
|
|
441
|
+
"caret-up-down": { regular: SoCaretUpDownL, fill: SoCaretUpDownB },
|
|
442
|
+
"caret-double-left": { regular: SoCaretDoubleLeftL, fill: SoCaretDoubleLeftB },
|
|
443
|
+
"caret-double-right": { regular: SoCaretDoubleRightL, fill: SoCaretDoubleRightB },
|
|
444
|
+
"squares-four": { regular: SoWidget5L, fill: SoWidget5B },
|
|
445
|
+
list: { regular: SoListL, fill: SoListB },
|
|
446
|
+
info: { regular: SoInfoCircleL, fill: SoInfoCircleB },
|
|
447
|
+
article: { regular: SoDocumentTextL, fill: SoDocumentTextB },
|
|
448
|
+
"grid-four": { regular: SoWidget2L, fill: SoWidget2B },
|
|
449
|
+
"arrow-square-out": { regular: SoSquareTopUpL, fill: SoSquareTopUpB },
|
|
450
|
+
"pencil-simple": { regular: SoPenL, fill: SoPenB },
|
|
451
|
+
"share-network": { regular: SoShareL, fill: SoShareB },
|
|
452
|
+
copy: { regular: SoCopyL, fill: SoCopyB },
|
|
453
|
+
"copy-simple": { regular: SoCopyL, fill: SoCopyB },
|
|
454
|
+
scissors: { regular: SoScissorsL, fill: SoScissorsB },
|
|
455
|
+
"clipboard-text": { regular: SoClipboardTextL, fill: SoClipboardTextB },
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
/* lucide 세트 — 자연스러운 대응이 있는 것만. */
|
|
459
|
+
const lucideSet: Partial<Record<IconName, AnyComp>> = {
|
|
460
|
+
check: LuCheck,
|
|
461
|
+
warning: LuWarning,
|
|
462
|
+
star: LuStar,
|
|
463
|
+
heart: LuHeart,
|
|
464
|
+
user: LuUser,
|
|
465
|
+
search: LuSearch,
|
|
466
|
+
gear: LuGear,
|
|
467
|
+
trash: LuTrash,
|
|
468
|
+
"arrow-right": LuArrowRight,
|
|
469
|
+
x: LuX,
|
|
470
|
+
sun: LuSun,
|
|
471
|
+
moon: LuMoon,
|
|
472
|
+
"caret-down": LuCaretDown,
|
|
473
|
+
"caret-left": LuCaretLeft,
|
|
474
|
+
"caret-right": LuCaretRight,
|
|
475
|
+
"caret-up": LuCaretUp,
|
|
476
|
+
"caret-up-down": LuCaretUpDown,
|
|
477
|
+
"caret-double-left": LuCaretDoubleLeft,
|
|
478
|
+
"caret-double-right": LuCaretDoubleRight,
|
|
479
|
+
columns: LuColumns,
|
|
480
|
+
square: LuSquare,
|
|
481
|
+
"squares-four": LuGrid3X3,
|
|
482
|
+
list: LuList,
|
|
483
|
+
info: LuInfo,
|
|
484
|
+
article: LuFileText,
|
|
485
|
+
"grid-four": LuLayoutGrid,
|
|
486
|
+
"arrow-square-out": LuExternalLink,
|
|
487
|
+
"pencil-simple": LuPencil,
|
|
488
|
+
"share-network": LuShare,
|
|
489
|
+
copy: LuCopy,
|
|
490
|
+
"copy-simple": LuFiles,
|
|
491
|
+
scissors: LuScissors,
|
|
492
|
+
"clipboard-text": LuClipboardType,
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
/* family 공통 fallback — 매핑 없는 아이콘 호출 시 "사각형 + 대각선" 금지표시 느낌.
|
|
496
|
+
family별 라이브러리 아이콘("빈 네모")보다 "이 아이콘은 없음" 신호가 명확하도록
|
|
497
|
+
전용 SVG로 그린다. stroke는 currentColor, size는 phosphor/lucide와 동일하게 size prop을
|
|
498
|
+
받는 형태로 흉내낸다. */
|
|
499
|
+
function MissingIcon({
|
|
500
|
+
size = 20,
|
|
501
|
+
...rest
|
|
502
|
+
}: React.SVGAttributes<SVGSVGElement> & { size?: number | string }) {
|
|
503
|
+
return (
|
|
504
|
+
<svg
|
|
505
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
506
|
+
width={size}
|
|
507
|
+
height={size}
|
|
508
|
+
viewBox="0 0 256 256"
|
|
509
|
+
fill="none"
|
|
510
|
+
stroke="currentColor"
|
|
511
|
+
strokeWidth={16}
|
|
512
|
+
strokeLinecap="round"
|
|
513
|
+
strokeLinejoin="round"
|
|
514
|
+
{...rest}
|
|
515
|
+
>
|
|
516
|
+
<rect x="40" y="40" width="176" height="176" rx="8" />
|
|
517
|
+
<line x1="216" y1="40" x2="40" y2="216" />
|
|
518
|
+
</svg>
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/* arrows-down-up: table header sort indicator 전용 커스텀 아이콘.
|
|
523
|
+
phosphor ArrowsDownUp과 동일한 모양이지만 두 path를 각각 분리해 class를 걸어
|
|
524
|
+
호출 쪽에서 "위 path(=desc 방향)"와 "아래 path(=asc 방향)"의 톤을 독립 제어할 수 있게 함.
|
|
525
|
+
icon family 축에 영향받지 않고 항상 동일 모양. */
|
|
526
|
+
function ArrowsDownUpIcon({
|
|
527
|
+
size = 20,
|
|
528
|
+
upClassName,
|
|
529
|
+
downClassName,
|
|
530
|
+
...rest
|
|
531
|
+
}: React.SVGAttributes<SVGSVGElement> & {
|
|
532
|
+
size?: number | string;
|
|
533
|
+
/** 상단 path (아래 방향 ↓, desc 지시). */
|
|
534
|
+
upClassName?: string;
|
|
535
|
+
/** 하단 path (위 방향 ↑, asc 지시). */
|
|
536
|
+
downClassName?: string;
|
|
537
|
+
}) {
|
|
538
|
+
return (
|
|
539
|
+
<svg
|
|
540
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
541
|
+
width={size}
|
|
542
|
+
height={size}
|
|
543
|
+
viewBox="0 0 256 256"
|
|
544
|
+
fill="currentColor"
|
|
545
|
+
{...rest}
|
|
546
|
+
>
|
|
547
|
+
<path
|
|
548
|
+
className={upClassName}
|
|
549
|
+
d="M117.66,170.34a8,8,0,0,1,0,11.32l-32,32a8,8,0,0,1-11.32,0l-32-32a8,8,0,0,1,11.32-11.32L72,188.69V48a8,8,0,0,1,16,0V188.69l18.34-18.35A8,8,0,0,1,117.66,170.34Z"
|
|
550
|
+
/>
|
|
551
|
+
<path
|
|
552
|
+
className={downClassName}
|
|
553
|
+
d="M213.66,74.34l-32-32a8,8,0,0,0-11.32,0l-32,32a8,8,0,0,0,11.32,11.32L168,67.31V208a8,8,0,0,0,16,0V67.31l18.34,18.35a8,8,0,0,0,11.32-11.32Z"
|
|
554
|
+
/>
|
|
555
|
+
</svg>
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
export interface IconProps extends React.SVGAttributes<SVGSVGElement> {
|
|
560
|
+
name: IconName;
|
|
561
|
+
/** 축 기본값(html data-icon-family) 오버라이드 */
|
|
562
|
+
family?: IconFamily;
|
|
563
|
+
/** phosphor·solar에서 실제 반응. lucide는 무시(regular 유지). */
|
|
564
|
+
weight?: IconWeight;
|
|
565
|
+
size?: number | string;
|
|
566
|
+
/** arrows-down-up 전용: 상/하 path 톤을 각기 제어. 다른 아이콘에서는 무시. */
|
|
567
|
+
upClassName?: string;
|
|
568
|
+
downClassName?: string;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
export function Icon({
|
|
572
|
+
name,
|
|
573
|
+
family: familyProp,
|
|
574
|
+
weight: weightProp,
|
|
575
|
+
size = 20,
|
|
576
|
+
upClassName,
|
|
577
|
+
downClassName,
|
|
578
|
+
...rest
|
|
579
|
+
}: IconProps) {
|
|
580
|
+
const axis = useIconAxis();
|
|
581
|
+
const family = familyProp ?? axis.family;
|
|
582
|
+
const weight = weightProp ?? axis.weight;
|
|
583
|
+
|
|
584
|
+
/* family와 무관하게 늘 같은 모양으로 나와야 하는 커스텀 아이콘 분기. */
|
|
585
|
+
if (name === "arrows-down-up") {
|
|
586
|
+
return (
|
|
587
|
+
<ArrowsDownUpIcon
|
|
588
|
+
size={size}
|
|
589
|
+
upClassName={upClassName}
|
|
590
|
+
downClassName={downClassName}
|
|
591
|
+
{...rest}
|
|
592
|
+
/>
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
let Component: AnyComp;
|
|
597
|
+
let familyProps: Record<string, unknown> = {};
|
|
598
|
+
|
|
599
|
+
if (family === "solar") {
|
|
600
|
+
const entry = solarSet[name];
|
|
601
|
+
if (!entry) return <MissingIcon size={size} {...rest} />;
|
|
602
|
+
Component = entry[weight];
|
|
603
|
+
} else if (family === "lucide") {
|
|
604
|
+
const entry = lucideSet[name];
|
|
605
|
+
if (!entry) return <MissingIcon size={size} {...rest} />;
|
|
606
|
+
Component = entry;
|
|
607
|
+
} else {
|
|
608
|
+
// phosphor (기본)
|
|
609
|
+
const entry = phosphorSet[name];
|
|
610
|
+
if (!entry) return <MissingIcon size={size} {...rest} />;
|
|
611
|
+
Component = entry;
|
|
612
|
+
familyProps = { weight };
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
return <Component size={size} {...familyProps} {...rest} />;
|
|
616
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Icon 축 컨텍스트.
|
|
5
|
+
*
|
|
6
|
+
* Icon 컴포넌트가 프로젝트 내 어디에서 렌더링되든 현재 축 값(family/weight)을
|
|
7
|
+
* 참조할 수 있게 해준다. 프로젝트에서는 앱 루트에서 <IconAxisProvider>로 감싸고,
|
|
8
|
+
* 축이 바뀔 때 value만 갈아끼우면 됨.
|
|
9
|
+
*
|
|
10
|
+
* Icon 라이브러리는 컴포넌트별 MutationObserver 대신 이 컨텍스트로 축을 소비 —
|
|
11
|
+
* O(N)개 관찰자 → 0개.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { createContext, useContext } from "react";
|
|
15
|
+
|
|
16
|
+
/** Icon 라이브러리는 앱 코드에 의존하지 않도록 축 타입을 자체 선언한다.
|
|
17
|
+
* 값은 app/data.ts의 IconFamily/IconWeight와 동일해야 함. */
|
|
18
|
+
export type IconAxisFamily = "phosphor" | "solar" | "lucide";
|
|
19
|
+
export type IconAxisWeight = "regular" | "fill";
|
|
20
|
+
export type IconAxis = { family: IconAxisFamily; weight: IconAxisWeight };
|
|
21
|
+
|
|
22
|
+
export const IconAxisContext = createContext<IconAxis>({
|
|
23
|
+
family: "phosphor",
|
|
24
|
+
weight: "regular",
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export function IconAxisProvider({
|
|
28
|
+
value,
|
|
29
|
+
children,
|
|
30
|
+
}: {
|
|
31
|
+
value: IconAxis;
|
|
32
|
+
children: React.ReactNode;
|
|
33
|
+
}) {
|
|
34
|
+
return <IconAxisContext.Provider value={value}>{children}</IconAxisContext.Provider>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function useIconAxis(): IconAxis {
|
|
38
|
+
return useContext(IconAxisContext);
|
|
39
|
+
}
|