@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.
- package/README.md +31 -0
- package/dist/app.css +1 -1
- package/dist/index-astro.ts +18 -10
- package/dist/index-vue.ts +2 -2
- package/dist/{vue → src}/utils/language.ts +1 -1
- package/dist/src/utils/link.ts +250 -0
- package/dist/{vue → src}/utils/path.ts +1 -1
- package/dist/src-astro/article/index.ts +1 -1
- package/dist/src-astro/assets/iconData.ts +5 -0
- package/dist/src-astro/banner/index.ts +1 -1
- package/dist/src-astro/code-container/CodeContainer.astro +6 -91
- package/dist/src-astro/confirm-dialog/ConfirmDialog.astro +119 -0
- package/dist/src-astro/confirm-dialog/index.ts +2 -0
- package/dist/src-astro/confirm-dialog/types.ts +47 -0
- package/dist/src-astro/cosy.ts +1 -1
- package/dist/src-astro/database/index.ts +3 -0
- package/dist/src-astro/entities/BlogDoc.ts +1 -1
- package/dist/src-astro/entities/CourseDoc.ts +1 -1
- package/dist/src-astro/entities/ExperimentDoc.ts +1 -1
- package/dist/src-astro/entities/LessonDoc.ts +1 -1
- package/dist/src-astro/entities/MetaDoc.ts +1 -1
- package/dist/src-astro/entities/Tag.ts +1 -1
- package/dist/src-astro/errors/403.astro +1 -1
- package/dist/src-astro/errors/404.astro +1 -1
- package/dist/src-astro/errors/500.astro +1 -1
- package/dist/src-astro/errors/503.astro +1 -1
- package/dist/src-astro/flex/index.ts +1 -1
- package/dist/src-astro/footer/Footer.astro +1 -1
- package/dist/src-astro/grid/index.ts +1 -1
- package/dist/src-astro/heading/index.ts +1 -1
- package/dist/src-astro/icons/LogOut.astro +28 -0
- package/dist/src-astro/icons/index.ts +1 -0
- package/dist/src-astro/image/index.ts +1 -1
- package/dist/src-astro/language-switcher/index.ts +1 -1
- package/dist/src-astro/layout-basic/index.ts +1 -1
- package/dist/src-astro/layout-dashboard/DashboardLayout.astro +76 -1
- package/dist/src-astro/layout-dashboard/tools.ts +158 -0
- package/dist/src-astro/layout-dashboard/types.ts +1 -154
- package/dist/src-astro/link/index.ts +1 -1
- package/dist/src-astro/login/Login.astro +251 -0
- package/dist/src-astro/login/index.ts +2 -0
- package/dist/src-astro/logout/Logout.astro +117 -0
- package/dist/src-astro/logout/index.ts +2 -0
- package/dist/src-astro/module/index.ts +1 -1
- package/dist/src-astro/nav-item/NavItems.astro +1 -1
- package/dist/src-astro/nav-item/index.ts +1 -1
- package/dist/src-astro/nav-section/index.ts +1 -1
- package/dist/src-astro/register/Register.astro +289 -0
- package/dist/src-astro/register/index.ts +2 -0
- package/dist/src-astro/sidebar/Sidebar.astro +1 -1
- package/dist/src-astro/sidebar/index.ts +1 -1
- package/dist/src-astro/sidebar-nav/SidebarNav.astro +1 -1
- package/dist/src-astro/sidebar-nav/index.ts +1 -1
- package/dist/src-astro/speak/index.ts +1 -1
- package/dist/src-astro/stack/index.ts +1 -1
- package/dist/src-astro/team-member/TeamMemberBasic.astro +1 -1
- package/dist/src-astro/team-member/TeamMemberCustomStyle.astro +1 -1
- package/dist/src-astro/team-member/TeamMemberGroup.astro +1 -1
- package/dist/src-astro/team-member/TeamMemberWithSocial.astro +1 -1
- package/dist/src-astro/team-member/index.ts +1 -1
- package/dist/src-astro/text/index.ts +1 -1
- package/dist/src-astro/theme-switcher/ThemeSwitcher.astro +1 -1
- package/dist/src-astro/theme-switcher/index.ts +1 -1
- package/dist/src-astro/toast/Toast.astro +114 -0
- package/dist/src-astro/toast/ToastContainer.astro +249 -0
- package/dist/src-astro/toast/index.ts +4 -0
- package/dist/src-astro/toast/types.ts +78 -0
- package/dist/src-astro/toc/TableOfContents.astro +2 -2
- package/dist/src-astro/toc/index.ts +1 -1
- package/dist/src-astro/types/nav.ts +26 -1
- package/dist/{vue/buttons-vue → src-vue/buttons}/Button.vue +14 -19
- package/dist/{vue/icons-vue → src-vue/icons}/VueIcon.vue +3 -13
- package/dist/src-vue/utils/link.ts +250 -0
- package/package.json +1 -1
- package/dist/src-astro/utils/link.ts +0 -250
- package/dist/vue/utils/link.ts +0 -250
- /package/dist/{vue → src}/utils/component.ts +0 -0
- /package/dist/{vue → src}/utils/i18n.ts +0 -0
- /package/dist/{vue → src}/utils/image.ts +0 -0
- /package/dist/{vue → src}/utils/lang_entry.ts +0 -0
- /package/dist/{vue → src}/utils/lang_package.ts +0 -0
- /package/dist/{vue → src}/utils/logger.ts +0 -0
- /package/dist/{vue → src}/utils/social.ts +0 -0
- /package/dist/{vue → src}/utils/theme.ts +0 -0
- /package/dist/{vue → src}/utils/url.ts +0 -0
- /package/dist/{vue → src-vue}/SmartLink.vue +0 -0
- /package/dist/{vue → src-vue}/TagList.vue +0 -0
- /package/dist/{vue → src-vue}/alert-dialog-vue/AlertDialog.vue +0 -0
- /package/dist/{vue → src-vue}/alert-dialog-vue/Basic.vue +0 -0
- /package/dist/{vue → src-vue}/alert-dialog-vue/Multilang.vue +0 -0
- /package/dist/{vue → src-vue}/alert-dialog-vue/index.ts +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/BannerBox.vue +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/DownloadButton.vue +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/ExampleBasic.vue +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/ExampleCustomBg.vue +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/ExampleDisplayModeAlways.vue +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/ExampleDisplayModeHover.vue +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/ExampleDisplayModeNever.vue +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/ExampleImageExport.vue +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/ExampleSizePreset.vue +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/FeatureCard.vue +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/SmartBanner.vue +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/bgStyles.ts +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/index.ts +0 -0
- /package/dist/{vue → src-vue}/banner-box-vue/sizePresets.ts +0 -0
- /package/dist/{vue → src-vue}/blog-vue/Basic.vue +0 -0
- /package/dist/{vue → src-vue}/blog-vue/BlogList.vue +0 -0
- /package/dist/{vue → src-vue}/blog-vue/Empty.vue +0 -0
- /package/dist/{vue → src-vue}/blog-vue/EmptyEnglish.vue +0 -0
- /package/dist/{vue → src-vue}/blog-vue/English.vue +0 -0
- /package/dist/{vue → src-vue}/blog-vue/index.ts +0 -0
- /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonBasic.vue +0 -0
- /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonFeature.vue +0 -0
- /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonFeatureBasic.vue +0 -0
- /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonFeatureWithTips.vue +0 -0
- /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonLink.vue +0 -0
- /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonSizes.vue +0 -0
- /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonVariants.vue +0 -0
- /package/dist/{vue/buttons-vue → src-vue/buttons}/ButtonWithIcons.vue +0 -0
- /package/dist/{vue/buttons-vue → src-vue/buttons}/index.ts +0 -0
- /package/dist/{vue → src-vue}/confirm-dialog-vue/Basic.vue +0 -0
- /package/dist/{vue → src-vue}/confirm-dialog-vue/ConfirmDialog.vue +0 -0
- /package/dist/{vue → src-vue}/confirm-dialog-vue/CustomButtons.vue +0 -0
- /package/dist/{vue → src-vue}/confirm-dialog-vue/index.ts +0 -0
- /package/dist/{vue → src-vue}/cosy.ts +0 -0
- /package/dist/{vue → src-vue}/counter-vue/VueCounter.vue +0 -0
- /package/dist/{vue → src-vue}/counter-vue/index.ts +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/Basic.vue +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/CustomBackground.vue +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/NoFrame.vue +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/WeatherApp.vue +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Deep Purple - Landscape.png +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Deep Purple - Portrait.png +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Gold - Landscape.png +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Gold - Portrait.png +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Silver - Landscape.png +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Silver - Portrait.png +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Space Black - Landscape.png +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/assets/iPhone 14 Pro - Space Black - Portrait.png +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/iPhoneWindow.vue +0 -0
- /package/dist/{vue → src-vue}/iPhone-vue/index.ts +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/AlertTriangleIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/CalendarIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/CheckCircleIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/CheckIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/ChevronDownIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/ClipboardIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/CloseIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/InboxArchiveIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/InfoCircleIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/InfoIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/LinkIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/MenuIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/SearchIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/SettingsIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/UserIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/XCircleIcon.vue +0 -0
- /package/dist/{vue/icons-vue → src-vue/icons}/index.ts +0 -0
- /package/dist/{vue → src-vue}/list-vue/ListItem.vue +0 -0
- /package/dist/{vue → src-vue}/list-vue/index.ts +0 -0
- /package/dist/{vue → src-vue}/mac-window-vue/Basic.vue +0 -0
- /package/dist/{vue → src-vue}/mac-window-vue/CustomHeight.vue +0 -0
- /package/dist/{vue → src-vue}/mac-window-vue/MacWindow.vue +0 -0
- /package/dist/{vue → src-vue}/mac-window-vue/WithEvents.vue +0 -0
- /package/dist/{vue → src-vue}/mac-window-vue/WithSidebar.vue +0 -0
- /package/dist/{vue → src-vue}/mac-window-vue/WithTabs.vue +0 -0
- /package/dist/{vue → src-vue}/mac-window-vue/WithToolbar.vue +0 -0
- /package/dist/{vue → src-vue}/mac-window-vue/index.ts +0 -0
- /package/dist/{src-astro → src-vue}/utils/component.ts +0 -0
- /package/dist/{src-astro → src-vue}/utils/i18n.ts +0 -0
- /package/dist/{src-astro → src-vue}/utils/image.ts +0 -0
- /package/dist/{src-astro → src-vue}/utils/lang_entry.ts +0 -0
- /package/dist/{src-astro → src-vue}/utils/lang_package.ts +0 -0
- /package/dist/{src-astro → src-vue}/utils/language.ts +0 -0
- /package/dist/{src-astro → src-vue}/utils/logger.ts +0 -0
- /package/dist/{src-astro → src-vue}/utils/path.ts +0 -0
- /package/dist/{src-astro → src-vue}/utils/social.ts +0 -0
- /package/dist/{src-astro → src-vue}/utils/theme.ts +0 -0
- /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,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 '
|
58
|
-
import { LanguageUtil } from '
|
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 '
|
4
|
+
import { extractSimpleExample } from '../../src/utils/component';
|
5
5
|
|
6
6
|
export { TableOfContents, TableOfContentsBasic };
|
7
7
|
|
@@ -1 +1,26 @@
|
|
1
|
-
export
|
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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
:
|
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.
|
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
|
-
|
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>
|