@coffic/cosy-ui 0.8.12 → 0.8.16

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.
Files changed (179) hide show
  1. package/README.md +31 -0
  2. package/dist/app.css +1 -1
  3. package/dist/index-astro.ts +18 -10
  4. package/dist/index-vue.ts +2 -2
  5. package/dist/{vue → src}/utils/language.ts +1 -1
  6. package/dist/src/utils/link.ts +250 -0
  7. package/dist/{vue → src}/utils/path.ts +1 -1
  8. package/dist/src-astro/article/index.ts +1 -1
  9. package/dist/src-astro/assets/iconData.ts +5 -0
  10. package/dist/src-astro/banner/index.ts +1 -1
  11. package/dist/src-astro/code-container/CodeContainer.astro +6 -91
  12. package/dist/src-astro/confirm-dialog/ConfirmDialog.astro +119 -0
  13. package/dist/src-astro/confirm-dialog/index.ts +2 -0
  14. package/dist/src-astro/confirm-dialog/types.ts +47 -0
  15. package/dist/src-astro/cosy.ts +1 -1
  16. package/dist/src-astro/database/index.ts +3 -0
  17. package/dist/src-astro/entities/BlogDoc.ts +1 -1
  18. package/dist/src-astro/entities/CourseDoc.ts +1 -1
  19. package/dist/src-astro/entities/ExperimentDoc.ts +1 -1
  20. package/dist/src-astro/entities/LessonDoc.ts +1 -1
  21. package/dist/src-astro/entities/MetaDoc.ts +1 -1
  22. package/dist/src-astro/entities/Tag.ts +1 -1
  23. package/dist/src-astro/errors/403.astro +1 -1
  24. package/dist/src-astro/errors/404.astro +1 -1
  25. package/dist/src-astro/errors/500.astro +1 -1
  26. package/dist/src-astro/errors/503.astro +1 -1
  27. package/dist/src-astro/flex/index.ts +1 -1
  28. package/dist/src-astro/footer/Footer.astro +1 -1
  29. package/dist/src-astro/grid/index.ts +1 -1
  30. package/dist/src-astro/heading/index.ts +1 -1
  31. package/dist/src-astro/icons/LogOut.astro +28 -0
  32. package/dist/src-astro/icons/index.ts +1 -0
  33. package/dist/src-astro/image/index.ts +1 -1
  34. package/dist/src-astro/language-switcher/index.ts +1 -1
  35. package/dist/src-astro/layout-basic/index.ts +1 -1
  36. package/dist/src-astro/layout-dashboard/DashboardLayout.astro +76 -1
  37. package/dist/src-astro/layout-dashboard/tools.ts +158 -0
  38. package/dist/src-astro/layout-dashboard/types.ts +1 -154
  39. package/dist/src-astro/link/index.ts +1 -1
  40. package/dist/src-astro/login/Login.astro +251 -0
  41. package/dist/src-astro/login/index.ts +2 -0
  42. package/dist/src-astro/logout/Logout.astro +117 -0
  43. package/dist/src-astro/logout/index.ts +2 -0
  44. package/dist/src-astro/module/index.ts +1 -1
  45. package/dist/src-astro/nav-item/NavItems.astro +1 -1
  46. package/dist/src-astro/nav-item/index.ts +1 -1
  47. package/dist/src-astro/nav-section/index.ts +1 -1
  48. package/dist/src-astro/register/Register.astro +289 -0
  49. package/dist/src-astro/register/index.ts +2 -0
  50. package/dist/src-astro/sidebar/Sidebar.astro +1 -1
  51. package/dist/src-astro/sidebar/index.ts +1 -1
  52. package/dist/src-astro/sidebar-nav/SidebarNav.astro +1 -1
  53. package/dist/src-astro/sidebar-nav/index.ts +1 -1
  54. package/dist/src-astro/speak/index.ts +1 -1
  55. package/dist/src-astro/stack/index.ts +1 -1
  56. package/dist/src-astro/team-member/TeamMemberBasic.astro +1 -1
  57. package/dist/src-astro/team-member/TeamMemberCustomStyle.astro +1 -1
  58. package/dist/src-astro/team-member/TeamMemberGroup.astro +1 -1
  59. package/dist/src-astro/team-member/TeamMemberWithSocial.astro +1 -1
  60. package/dist/src-astro/team-member/index.ts +1 -1
  61. package/dist/src-astro/text/index.ts +1 -1
  62. package/dist/src-astro/theme-switcher/ThemeSwitcher.astro +1 -1
  63. package/dist/src-astro/theme-switcher/index.ts +1 -1
  64. package/dist/src-astro/toast/Toast.astro +114 -0
  65. package/dist/src-astro/toast/ToastContainer.astro +249 -0
  66. package/dist/src-astro/toast/index.ts +4 -0
  67. package/dist/src-astro/toast/types.ts +78 -0
  68. package/dist/src-astro/toc/TableOfContents.astro +2 -2
  69. package/dist/src-astro/toc/index.ts +1 -1
  70. package/dist/src-astro/types/nav.ts +26 -1
  71. package/dist/{vue/buttons-vue → src-vue/buttons}/Button.vue +14 -19
  72. package/dist/{vue/icons-vue → src-vue/icons}/VueIcon.vue +3 -13
  73. package/dist/src-vue/utils/link.ts +250 -0
  74. package/package.json +1 -1
  75. package/dist/src-astro/utils/link.ts +0 -250
  76. package/dist/vue/utils/link.ts +0 -250
  77. /package/dist/{vue → src}/utils/component.ts +0 -0
  78. /package/dist/{vue → src}/utils/i18n.ts +0 -0
  79. /package/dist/{vue → src}/utils/image.ts +0 -0
  80. /package/dist/{vue → src}/utils/lang_entry.ts +0 -0
  81. /package/dist/{vue → src}/utils/lang_package.ts +0 -0
  82. /package/dist/{vue → src}/utils/logger.ts +0 -0
  83. /package/dist/{vue → src}/utils/social.ts +0 -0
  84. /package/dist/{vue → src}/utils/theme.ts +0 -0
  85. /package/dist/{vue → src}/utils/url.ts +0 -0
  86. /package/dist/{vue → src-vue}/SmartLink.vue +0 -0
  87. /package/dist/{vue → src-vue}/TagList.vue +0 -0
  88. /package/dist/{vue → src-vue}/alert-dialog-vue/AlertDialog.vue +0 -0
  89. /package/dist/{vue → src-vue}/alert-dialog-vue/Basic.vue +0 -0
  90. /package/dist/{vue → src-vue}/alert-dialog-vue/Multilang.vue +0 -0
  91. /package/dist/{vue → src-vue}/alert-dialog-vue/index.ts +0 -0
  92. /package/dist/{vue → src-vue}/banner-box-vue/BannerBox.vue +0 -0
  93. /package/dist/{vue → src-vue}/banner-box-vue/DownloadButton.vue +0 -0
  94. /package/dist/{vue → src-vue}/banner-box-vue/ExampleBasic.vue +0 -0
  95. /package/dist/{vue → src-vue}/banner-box-vue/ExampleCustomBg.vue +0 -0
  96. /package/dist/{vue → src-vue}/banner-box-vue/ExampleDisplayModeAlways.vue +0 -0
  97. /package/dist/{vue → src-vue}/banner-box-vue/ExampleDisplayModeHover.vue +0 -0
  98. /package/dist/{vue → src-vue}/banner-box-vue/ExampleDisplayModeNever.vue +0 -0
  99. /package/dist/{vue → src-vue}/banner-box-vue/ExampleImageExport.vue +0 -0
  100. /package/dist/{vue → src-vue}/banner-box-vue/ExampleSizePreset.vue +0 -0
  101. /package/dist/{vue → src-vue}/banner-box-vue/FeatureCard.vue +0 -0
  102. /package/dist/{vue → src-vue}/banner-box-vue/SmartBanner.vue +0 -0
  103. /package/dist/{vue → src-vue}/banner-box-vue/bgStyles.ts +0 -0
  104. /package/dist/{vue → src-vue}/banner-box-vue/index.ts +0 -0
  105. /package/dist/{vue → src-vue}/banner-box-vue/sizePresets.ts +0 -0
  106. /package/dist/{vue → src-vue}/blog-vue/Basic.vue +0 -0
  107. /package/dist/{vue → src-vue}/blog-vue/BlogList.vue +0 -0
  108. /package/dist/{vue → src-vue}/blog-vue/Empty.vue +0 -0
  109. /package/dist/{vue → src-vue}/blog-vue/EmptyEnglish.vue +0 -0
  110. /package/dist/{vue → src-vue}/blog-vue/English.vue +0 -0
  111. /package/dist/{vue → src-vue}/blog-vue/index.ts +0 -0
  112. /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonBasic.vue +0 -0
  113. /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonFeature.vue +0 -0
  114. /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonFeatureBasic.vue +0 -0
  115. /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonFeatureWithTips.vue +0 -0
  116. /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonLink.vue +0 -0
  117. /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonSizes.vue +0 -0
  118. /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonVariants.vue +0 -0
  119. /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonWithIcons.vue +0 -0
  120. /package/dist/{vue/buttons-vue → src-vue/buttons}/index.ts +0 -0
  121. /package/dist/{vue → src-vue}/confirm-dialog-vue/Basic.vue +0 -0
  122. /package/dist/{vue → src-vue}/confirm-dialog-vue/ConfirmDialog.vue +0 -0
  123. /package/dist/{vue → src-vue}/confirm-dialog-vue/CustomButtons.vue +0 -0
  124. /package/dist/{vue → src-vue}/confirm-dialog-vue/index.ts +0 -0
  125. /package/dist/{vue → src-vue}/cosy.ts +0 -0
  126. /package/dist/{vue → src-vue}/counter-vue/VueCounter.vue +0 -0
  127. /package/dist/{vue → src-vue}/counter-vue/index.ts +0 -0
  128. /package/dist/{vue → src-vue}/iPhone-vue/Basic.vue +0 -0
  129. /package/dist/{vue → src-vue}/iPhone-vue/CustomBackground.vue +0 -0
  130. /package/dist/{vue → src-vue}/iPhone-vue/NoFrame.vue +0 -0
  131. /package/dist/{vue → src-vue}/iPhone-vue/WeatherApp.vue +0 -0
  132. /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Deep Purple - Landscape.png +0 -0
  133. /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Deep Purple - Portrait.png +0 -0
  134. /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Gold - Landscape.png +0 -0
  135. /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Gold - Portrait.png +0 -0
  136. /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Silver - Landscape.png +0 -0
  137. /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Silver - Portrait.png +0 -0
  138. /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Space Black - Landscape.png +0 -0
  139. /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Space Black - Portrait.png +0 -0
  140. /package/dist/{vue → src-vue}/iPhone-vue/iPhoneWindow.vue +0 -0
  141. /package/dist/{vue → src-vue}/iPhone-vue/index.ts +0 -0
  142. /package/dist/{vue/icons-vue → src-vue/icons}/AlertTriangleIcon.vue +0 -0
  143. /package/dist/{vue/icons-vue → src-vue/icons}/CalendarIcon.vue +0 -0
  144. /package/dist/{vue/icons-vue → src-vue/icons}/CheckCircleIcon.vue +0 -0
  145. /package/dist/{vue/icons-vue → src-vue/icons}/CheckIcon.vue +0 -0
  146. /package/dist/{vue/icons-vue → src-vue/icons}/ChevronDownIcon.vue +0 -0
  147. /package/dist/{vue/icons-vue → src-vue/icons}/ClipboardIcon.vue +0 -0
  148. /package/dist/{vue/icons-vue → src-vue/icons}/CloseIcon.vue +0 -0
  149. /package/dist/{vue/icons-vue → src-vue/icons}/InboxArchiveIcon.vue +0 -0
  150. /package/dist/{vue/icons-vue → src-vue/icons}/InfoCircleIcon.vue +0 -0
  151. /package/dist/{vue/icons-vue → src-vue/icons}/InfoIcon.vue +0 -0
  152. /package/dist/{vue/icons-vue → src-vue/icons}/LinkIcon.vue +0 -0
  153. /package/dist/{vue/icons-vue → src-vue/icons}/MenuIcon.vue +0 -0
  154. /package/dist/{vue/icons-vue → src-vue/icons}/SearchIcon.vue +0 -0
  155. /package/dist/{vue/icons-vue → src-vue/icons}/SettingsIcon.vue +0 -0
  156. /package/dist/{vue/icons-vue → src-vue/icons}/UserIcon.vue +0 -0
  157. /package/dist/{vue/icons-vue → src-vue/icons}/XCircleIcon.vue +0 -0
  158. /package/dist/{vue/icons-vue → src-vue/icons}/index.ts +0 -0
  159. /package/dist/{vue → src-vue}/list-vue/ListItem.vue +0 -0
  160. /package/dist/{vue → src-vue}/list-vue/index.ts +0 -0
  161. /package/dist/{vue → src-vue}/mac-window-vue/Basic.vue +0 -0
  162. /package/dist/{vue → src-vue}/mac-window-vue/CustomHeight.vue +0 -0
  163. /package/dist/{vue → src-vue}/mac-window-vue/MacWindow.vue +0 -0
  164. /package/dist/{vue → src-vue}/mac-window-vue/WithEvents.vue +0 -0
  165. /package/dist/{vue → src-vue}/mac-window-vue/WithSidebar.vue +0 -0
  166. /package/dist/{vue → src-vue}/mac-window-vue/WithTabs.vue +0 -0
  167. /package/dist/{vue → src-vue}/mac-window-vue/WithToolbar.vue +0 -0
  168. /package/dist/{vue → src-vue}/mac-window-vue/index.ts +0 -0
  169. /package/dist/{src-astro → src-vue}/utils/component.ts +0 -0
  170. /package/dist/{src-astro → src-vue}/utils/i18n.ts +0 -0
  171. /package/dist/{src-astro → src-vue}/utils/image.ts +0 -0
  172. /package/dist/{src-astro → src-vue}/utils/lang_entry.ts +0 -0
  173. /package/dist/{src-astro → src-vue}/utils/lang_package.ts +0 -0
  174. /package/dist/{src-astro → src-vue}/utils/language.ts +0 -0
  175. /package/dist/{src-astro → src-vue}/utils/logger.ts +0 -0
  176. /package/dist/{src-astro → src-vue}/utils/path.ts +0 -0
  177. /package/dist/{src-astro → src-vue}/utils/social.ts +0 -0
  178. /package/dist/{src-astro → src-vue}/utils/theme.ts +0 -0
  179. /package/dist/{src-astro → src-vue}/utils/url.ts +0 -0
@@ -0,0 +1,249 @@
1
+ ---
2
+ /**
3
+ * @component ToastContainer
4
+ *
5
+ * @description
6
+ * ToastContainer 是 toast 消息的容器组件,负责管理多个 toast 的显示、动画和生命周期。
7
+ * 提供完整的 toast 管理系统,包括自动清理、事件监听和全局 API。
8
+ *
9
+ * @design
10
+ * 设计理念:
11
+ * 1. 集中管理 - 统一管理所有 toast 的生命周期
12
+ * 2. 事件驱动 - 基于自定义事件的松耦合架构
13
+ * 3. 自动清理 - 防止内存泄漏,自动清理过期的 toast
14
+ * 4. 位置固定 - 固定在右上角,不干扰主要内容
15
+ * 5. 可访问性 - 支持屏幕阅读器和 ARIA 标准
16
+ *
17
+ * @usage
18
+ * 通常由 DashboardLayout 或其他布局组件自动包含:
19
+ * ```astro
20
+ * <ToastContainer />
21
+ * ```
22
+ *
23
+ * 提供的全局 API:
24
+ * ```javascript
25
+ * // 显示 toast
26
+ * const id = showToast('消息内容');
27
+ * const id = showToast({ message: '内容', type: 'success' });
28
+ *
29
+ * // 关闭特定 toast
30
+ * closeToast(id);
31
+ *
32
+ * // 清除所有 toast
33
+ * clearAllToasts();
34
+ * ```
35
+ */
36
+
37
+ import '../../style.ts';
38
+ ---
39
+
40
+ <!-- Toast 容器 -->
41
+ <div
42
+ id="toast-container"
43
+ class="cosy:fixed cosy:top-4 cosy:right-4 cosy:z-50 cosy:space-y-2 cosy:w-80 cosy:max-w-sm cosy:pointer-events-none"
44
+ aria-live="polite"
45
+ aria-label="通知消息区域">
46
+ <!-- Toast 项目将通过 JavaScript 动态添加 -->
47
+ </div>
48
+
49
+ <script is:inline>
50
+ // Toast 管理系统
51
+ (function () {
52
+ // 避免重复初始化
53
+ if (window.toastSystem) {
54
+ return;
55
+ }
56
+
57
+ let toastCounter = 0;
58
+ let activeToasts = new Map();
59
+
60
+ // 默认配置
61
+ const DEFAULT_CONFIG = {
62
+ type: 'info',
63
+ duration: 3000,
64
+ };
65
+
66
+ // 创建 toast 元素
67
+ function createToastElement(config) {
68
+ const id = config.id || `toast-${++toastCounter}`;
69
+ const type = config.type || DEFAULT_CONFIG.type;
70
+ const message = config.message;
71
+
72
+ // 图标路径映射
73
+ const iconMap = {
74
+ info: 'M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
75
+ success: 'M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z',
76
+ warning:
77
+ 'M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z',
78
+ error:
79
+ 'M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z',
80
+ };
81
+
82
+ // 样式映射
83
+ const styleMap = {
84
+ info: 'cosy:bg-info cosy:text-info-content cosy:border-info',
85
+ success:
86
+ 'cosy:bg-success cosy:text-success-content cosy:border-success',
87
+ warning:
88
+ 'cosy:bg-warning cosy:text-warning-content cosy:border-warning',
89
+ error: 'cosy:bg-error cosy:text-error-content cosy:border-error',
90
+ };
91
+
92
+ const toastElement = document.createElement('div');
93
+ toastElement.className = `
94
+ cosy:alert cosy:shadow-lg cosy:flex cosy:items-center cosy:gap-3 cosy:pr-2
95
+ cosy:transform cosy:transition-all cosy:duration-300 cosy:ease-in-out
96
+ cosy:translate-x-full cosy:opacity-0 cosy:pointer-events-auto
97
+ ${styleMap[type]}
98
+ `
99
+ .replace(/\s+/g, ' ')
100
+ .trim();
101
+
102
+ toastElement.setAttribute('data-toast-id', id);
103
+ toastElement.setAttribute('role', 'alert');
104
+ toastElement.setAttribute('aria-live', 'polite');
105
+
106
+ toastElement.innerHTML = `
107
+ <svg class="cosy:w-5 cosy:h-5 cosy:shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
108
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="${iconMap[type]}"></path>
109
+ </svg>
110
+ <span class="cosy:flex-1 cosy:text-sm cosy:font-medium">${message}</span>
111
+ <button
112
+ class="cosy:btn cosy:btn-ghost cosy:btn-xs cosy:btn-circle cosy:opacity-70 hover:cosy:opacity-100"
113
+ onclick="window.closeToast?.('${id}')"
114
+ aria-label="关闭通知"
115
+ type="button"
116
+ >
117
+ <svg class="cosy:w-4 cosy:h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
118
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
119
+ </svg>
120
+ </button>
121
+ `;
122
+
123
+ return { element: toastElement, id };
124
+ }
125
+
126
+ // 显示 toast
127
+ function showToast(config) {
128
+ if (typeof config === 'string') {
129
+ config = { message: config };
130
+ }
131
+
132
+ // 合并默认配置
133
+ config = { ...DEFAULT_CONFIG, ...config };
134
+
135
+ const container = document.getElementById('toast-container');
136
+ if (!container) {
137
+ console.warn('Toast container not found');
138
+ return '';
139
+ }
140
+
141
+ const { element, id } = createToastElement(config);
142
+ const duration = config.duration || DEFAULT_CONFIG.duration;
143
+
144
+ // 添加到容器
145
+ container.appendChild(element);
146
+
147
+ // 记录活跃的 toast
148
+ activeToasts.set(id, {
149
+ element,
150
+ timer: null,
151
+ config,
152
+ });
153
+
154
+ // 触发入场动画
155
+ requestAnimationFrame(() => {
156
+ element.classList.remove('cosy:translate-x-full', 'cosy:opacity-0');
157
+ element.classList.add('cosy:translate-x-0', 'cosy:opacity-100');
158
+ });
159
+
160
+ // 设置自动关闭
161
+ if (duration > 0) {
162
+ const timer = setTimeout(() => {
163
+ closeToast(id);
164
+ }, duration);
165
+
166
+ activeToasts.get(id).timer = timer;
167
+ }
168
+
169
+ return id;
170
+ }
171
+
172
+ // 关闭 toast
173
+ function closeToast(id) {
174
+ const toastData = activeToasts.get(id);
175
+ if (!toastData) return;
176
+
177
+ const { element, timer } = toastData;
178
+
179
+ // 清除定时器
180
+ if (timer) {
181
+ clearTimeout(timer);
182
+ }
183
+
184
+ // 触发退场动画
185
+ element.classList.remove('cosy:translate-x-0', 'cosy:opacity-100');
186
+ element.classList.add('cosy:translate-x-full', 'cosy:opacity-0');
187
+
188
+ // 动画结束后移除元素
189
+ setTimeout(() => {
190
+ if (element.parentNode) {
191
+ element.parentNode.removeChild(element);
192
+ }
193
+ activeToasts.delete(id);
194
+ }, 300);
195
+ }
196
+
197
+ // 关闭所有 toast
198
+ function clearAllToasts() {
199
+ activeToasts.forEach((_, id) => {
200
+ closeToast(id);
201
+ });
202
+ }
203
+
204
+ // 获取活跃的 toast 数量
205
+ function getActiveToastCount() {
206
+ return activeToasts.size;
207
+ }
208
+
209
+ // 获取所有活跃的 toast ID
210
+ function getActiveToastIds() {
211
+ return Array.from(activeToasts.keys());
212
+ }
213
+
214
+ // 创建 toast 系统对象
215
+ const toastSystem = {
216
+ show: showToast,
217
+ close: closeToast,
218
+ clearAll: clearAllToasts,
219
+ getActiveCount: getActiveToastCount,
220
+ getActiveIds: getActiveToastIds,
221
+ };
222
+
223
+ // 暴露到全局
224
+ window.showToast = showToast;
225
+ window.closeToast = closeToast;
226
+ window.clearAllToasts = clearAllToasts;
227
+ window.toastSystem = toastSystem;
228
+
229
+ // 监听自定义事件
230
+ document.addEventListener('show-toast', (event) => {
231
+ showToast(event.detail);
232
+ });
233
+
234
+ document.addEventListener('close-toast', (event) => {
235
+ closeToast(event.detail.id);
236
+ });
237
+
238
+ document.addEventListener('clear-all-toasts', () => {
239
+ clearAllToasts();
240
+ });
241
+
242
+ // 页面卸载时清理
243
+ window.addEventListener('beforeunload', () => {
244
+ clearAllToasts();
245
+ });
246
+
247
+ console.log('Toast system initialized');
248
+ })();
249
+ </script>
@@ -0,0 +1,4 @@
1
+ export { default as Toast } from './Toast.astro';
2
+ export { default as ToastContainer } from './ToastContainer.astro';
3
+ export type { ToastType, ToastConfig, ToastItem } from './types';
4
+ export { getToastStyle, toastStyleMap, DEFAULT_TOAST_CONFIG } from './types';
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Toast 组件的类型定义
3
+ */
4
+
5
+ /**
6
+ * Toast 类型
7
+ */
8
+ export type ToastType = 'info' | 'success' | 'warning' | 'error';
9
+
10
+ /**
11
+ * Toast 配置接口
12
+ */
13
+ export interface ToastConfig {
14
+ message: string;
15
+ type?: ToastType;
16
+ duration?: number; // 毫秒,默认 3000
17
+ id?: string; // 如果不提供会自动生成
18
+ }
19
+
20
+ /**
21
+ * Toast 项接口
22
+ */
23
+ export interface ToastItem extends Required<ToastConfig> {
24
+ id: string;
25
+ createdAt: number;
26
+ }
27
+
28
+ /**
29
+ * Toast 样式映射
30
+ */
31
+ export const toastStyleMap: Record<ToastType, { bg: string; icon: string; border: string }> = {
32
+ info: {
33
+ bg: 'cosy:bg-info cosy:text-info-content',
34
+ icon: 'info',
35
+ border: 'cosy:border-info'
36
+ },
37
+ success: {
38
+ bg: 'cosy:bg-success cosy:text-success-content',
39
+ icon: 'check',
40
+ border: 'cosy:border-success'
41
+ },
42
+ warning: {
43
+ bg: 'cosy:bg-warning cosy:text-warning-content',
44
+ icon: 'warning',
45
+ border: 'cosy:border-warning'
46
+ },
47
+ error: {
48
+ bg: 'cosy:bg-error cosy:text-error-content',
49
+ icon: 'error',
50
+ border: 'cosy:border-error'
51
+ }
52
+ };
53
+
54
+ /**
55
+ * 获取 Toast 样式
56
+ * @param type Toast 类型
57
+ * @returns 对应的样式配置
58
+ */
59
+ export function getToastStyle(type: ToastType) {
60
+ return toastStyleMap[type];
61
+ }
62
+
63
+ /**
64
+ * 默认 Toast 配置
65
+ */
66
+ export const DEFAULT_TOAST_CONFIG = {
67
+ type: 'info' as ToastType,
68
+ duration: 3000,
69
+ };
70
+
71
+ // 声明全局 Toast 函数
72
+ declare global {
73
+ interface Window {
74
+ showToast: (config: ToastConfig | string) => string;
75
+ closeToast: (id: string) => void;
76
+ clearAllToasts: () => void;
77
+ }
78
+ }
@@ -54,8 +54,8 @@
54
54
 
55
55
  // 导入样式
56
56
  import '../../style.ts';
57
- import { createTextGetter } from '../utils/i18n.ts';
58
- import { LanguageUtil } from '../utils/language.ts';
57
+ import { createTextGetter } from '../../src/utils/i18n.ts';
58
+ import { LanguageUtil } from '../../src/utils/language.ts';
59
59
 
60
60
  interface Props {
61
61
  /**
@@ -1,7 +1,7 @@
1
1
  import TableOfContents from './TableOfContents.astro';
2
2
  import TableOfContentsBasic from './TableOfContentsBasic.astro';
3
3
  import BasicSourceCode from './TableOfContentsBasic.astro?raw';
4
- import { extractSimpleExample } from '../utils/component';
4
+ import { extractSimpleExample } from '../../src/utils/component';
5
5
 
6
6
  export { TableOfContents, TableOfContentsBasic };
7
7
 
@@ -1 +1,26 @@
1
- export type INavItem = { href: string; label: string };
1
+ export interface INavItem {
2
+ /**
3
+ * 导航项的标题
4
+ */
5
+ title: string;
6
+
7
+ /**
8
+ * 导航项的链接地址
9
+ */
10
+ href: string;
11
+
12
+ /**
13
+ * 导航项的图标名称
14
+ */
15
+ icon?: string;
16
+
17
+ /**
18
+ * 点击事件处理函数
19
+ */
20
+ onClick?: string;
21
+
22
+ /**
23
+ * 子导航项
24
+ */
25
+ children?: INavItem[];
26
+ }
@@ -1,19 +1,20 @@
1
1
  <script setup lang="ts">
2
2
  import { computed } from 'vue';
3
+ import '../../style.ts';
3
4
 
4
5
  interface Props {
5
6
  variant?:
6
- | 'primary'
7
- | 'secondary'
8
- | 'accent'
9
- | 'info'
10
- | 'success'
11
- | 'warning'
12
- | 'error'
13
- | 'ghost'
14
- | 'link'
15
- | 'outline'
16
- | 'neutral';
7
+ | 'primary'
8
+ | 'secondary'
9
+ | 'accent'
10
+ | 'info'
11
+ | 'success'
12
+ | 'warning'
13
+ | 'error'
14
+ | 'ghost'
15
+ | 'link'
16
+ | 'outline'
17
+ | 'neutral';
17
18
  size?: 'lg' | 'md' | 'sm' | 'xs';
18
19
  shape?: 'circle' | 'square';
19
20
  wide?: boolean;
@@ -88,14 +89,8 @@ const buttonClasses = computed(() => {
88
89
  </script>
89
90
 
90
91
  <template>
91
- <component
92
- :is="props.href ? 'a' : 'button'"
93
- :class="buttonClasses"
94
- :type="props.href ? undefined : props.type"
95
- :disabled="props.disabled"
96
- :href="props.href"
97
- :target="props.target"
98
- >
92
+ <component :is="props.href ? 'a' : 'button'" :class="buttonClasses" :type="props.href ? undefined : props.type"
93
+ :disabled="props.disabled" :href="props.href" :target="props.target">
99
94
  <span class="cosy:flex cosy:items-center cosy:gap-2">
100
95
  <slot name="icon-left" />
101
96
  <slot />
@@ -28,7 +28,7 @@ import { Icon } from 'cosy-ui';
28
28
  -->
29
29
 
30
30
  <script setup lang="ts">
31
- import '../../style.ts';
31
+ import '../../style.js';
32
32
  import { computed } from 'vue';
33
33
  import { iconData } from '../../assets/iconData';
34
34
 
@@ -69,18 +69,8 @@ const viewBox = computed(() => {
69
69
  </script>
70
70
 
71
71
  <template>
72
- <svg
73
- xmlns="http://www.w3.org/2000/svg"
74
- :width="size"
75
- :height="size"
76
- :viewBox="viewBox"
77
- fill="none"
78
- :stroke="color"
79
- stroke-width="2"
80
- stroke-linecap="round"
81
- stroke-linejoin="round"
82
- :class="props.class"
83
- >
72
+ <svg xmlns="http://www.w3.org/2000/svg" :width="size" :height="size" :viewBox="viewBox" fill="none" :stroke="color"
73
+ stroke-width="2" stroke-linecap="round" stroke-linejoin="round" :class="props.class">
84
74
  <path v-if="icon" :d="icon.path" />
85
75
  </svg>
86
76
  </template>