@coffic/cosy-ui 0.8.16 → 0.8.18

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 (87) hide show
  1. package/dist/app.css +1 -1
  2. package/dist/index-vue.ts +14 -8
  3. package/dist/src-astro/header/Header.astro +1 -1
  4. package/dist/src-astro/icons/AstroIcon.astro +2 -3
  5. package/dist/src-astro/module/ModuleBasic.astro +1 -1
  6. package/dist/src-astro/module/ModuleCustom.astro +1 -1
  7. package/dist/src-astro/module/ModuleGrid.astro +3 -3
  8. package/dist/src-astro/sidebar-nav/SidebarNav.astro +3 -3
  9. package/dist/src-astro/speak/SpeakBasic.astro +1 -1
  10. package/dist/src-astro/speak/SpeakGrid.astro +3 -3
  11. package/dist/src-vue/SmartLink.vue +0 -1
  12. package/dist/src-vue/alert/Alert.vue +100 -0
  13. package/dist/src-vue/alert/index.ts +8 -0
  14. package/dist/src-vue/{alert-dialog-vue → alert-dialog}/index.ts +1 -1
  15. package/dist/src-vue/{banner-box-vue → banner-box}/index.ts +1 -1
  16. package/dist/src-vue/{blog-vue → blog}/BlogList.vue +2 -2
  17. package/dist/src-vue/{blog-vue → blog}/index.ts +1 -1
  18. package/dist/src-vue/{confirm-dialog-vue → confirm-dialog}/index.ts +1 -1
  19. package/dist/src-vue/container/Container.vue +214 -0
  20. package/dist/src-vue/container/index.ts +6 -0
  21. package/dist/src-vue/counter/index.ts +1 -0
  22. package/dist/src-vue/iPhone/StatusBarContent.vue +121 -0
  23. package/dist/src-vue/iPhone/iPhoneWindow.vue +234 -0
  24. package/dist/src-vue/{iPhone-vue → iPhone}/index.ts +10 -14
  25. package/dist/src-vue/icons/ErrorIcon.vue +30 -0
  26. package/dist/src-vue/icons/IPhoneBatteryIcon.vue +7 -0
  27. package/dist/src-vue/icons/IPhoneSignalIcon.vue +6 -0
  28. package/dist/src-vue/icons/IPhoneWifiIcon.vue +6 -0
  29. package/dist/src-vue/icons/SuccessIcon.vue +30 -0
  30. package/dist/src-vue/icons/VueIcon.vue +13 -3
  31. package/dist/src-vue/icons/WarningIcon.vue +30 -0
  32. package/dist/src-vue/icons/index.ts +22 -1
  33. package/dist/src-vue/mac-window/MacWindow.vue +262 -0
  34. package/dist/src-vue/mac-window/index.ts +2 -0
  35. package/package.json +12 -2
  36. package/dist/src-vue/counter-vue/index.ts +0 -1
  37. package/dist/src-vue/iPhone-vue/WeatherApp.vue +0 -143
  38. package/dist/src-vue/iPhone-vue/iPhoneWindow.vue +0 -247
  39. package/dist/src-vue/mac-window-vue/Basic.vue +0 -9
  40. package/dist/src-vue/mac-window-vue/CustomHeight.vue +0 -13
  41. package/dist/src-vue/mac-window-vue/MacWindow.vue +0 -283
  42. package/dist/src-vue/mac-window-vue/WithEvents.vue +0 -40
  43. package/dist/src-vue/mac-window-vue/WithSidebar.vue +0 -31
  44. package/dist/src-vue/mac-window-vue/WithTabs.vue +0 -26
  45. package/dist/src-vue/mac-window-vue/WithToolbar.vue +0 -44
  46. package/dist/src-vue/mac-window-vue/index.ts +0 -36
  47. /package/dist/{src-astro → src}/assets/book.png +0 -0
  48. /package/dist/{src-astro → src}/assets/iconData.ts +0 -0
  49. /package/dist/{src-astro → src}/assets/logo-rounded.png +0 -0
  50. /package/dist/{src-astro → src}/assets/logo.png +0 -0
  51. /package/dist/src-vue/{alert-dialog-vue → alert-dialog}/AlertDialog.vue +0 -0
  52. /package/dist/src-vue/{alert-dialog-vue → alert-dialog}/Basic.vue +0 -0
  53. /package/dist/src-vue/{alert-dialog-vue → alert-dialog}/Multilang.vue +0 -0
  54. /package/dist/src-vue/{banner-box-vue → banner-box}/BannerBox.vue +0 -0
  55. /package/dist/src-vue/{banner-box-vue → banner-box}/DownloadButton.vue +0 -0
  56. /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleBasic.vue +0 -0
  57. /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleCustomBg.vue +0 -0
  58. /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleDisplayModeAlways.vue +0 -0
  59. /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleDisplayModeHover.vue +0 -0
  60. /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleDisplayModeNever.vue +0 -0
  61. /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleImageExport.vue +0 -0
  62. /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleSizePreset.vue +0 -0
  63. /package/dist/src-vue/{banner-box-vue → banner-box}/FeatureCard.vue +0 -0
  64. /package/dist/src-vue/{banner-box-vue → banner-box}/SmartBanner.vue +0 -0
  65. /package/dist/src-vue/{banner-box-vue → banner-box}/bgStyles.ts +0 -0
  66. /package/dist/src-vue/{banner-box-vue → banner-box}/sizePresets.ts +0 -0
  67. /package/dist/src-vue/{blog-vue → blog}/Basic.vue +0 -0
  68. /package/dist/src-vue/{blog-vue → blog}/Empty.vue +0 -0
  69. /package/dist/src-vue/{blog-vue → blog}/EmptyEnglish.vue +0 -0
  70. /package/dist/src-vue/{blog-vue → blog}/English.vue +0 -0
  71. /package/dist/src-vue/{confirm-dialog-vue → confirm-dialog}/Basic.vue +0 -0
  72. /package/dist/src-vue/{confirm-dialog-vue → confirm-dialog}/ConfirmDialog.vue +0 -0
  73. /package/dist/src-vue/{confirm-dialog-vue → confirm-dialog}/CustomButtons.vue +0 -0
  74. /package/dist/src-vue/{counter-vue → counter}/VueCounter.vue +0 -0
  75. /package/dist/src-vue/{iPhone-vue → iPhone}/Basic.vue +0 -0
  76. /package/dist/src-vue/{iPhone-vue → iPhone}/CustomBackground.vue +0 -0
  77. /package/dist/src-vue/{iPhone-vue → iPhone}/NoFrame.vue +0 -0
  78. /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Deep Purple - Landscape.png +0 -0
  79. /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Deep Purple - Portrait.png +0 -0
  80. /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Gold - Landscape.png +0 -0
  81. /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Gold - Portrait.png +0 -0
  82. /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Silver - Landscape.png +0 -0
  83. /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Silver - Portrait.png +0 -0
  84. /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Space Black - Landscape.png +0 -0
  85. /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Space Black - Portrait.png +0 -0
  86. /package/dist/src-vue/{list-vue → list}/ListItem.vue +0 -0
  87. /package/dist/src-vue/{list-vue → list}/index.ts +0 -0
@@ -0,0 +1,262 @@
1
+ <!--
2
+ @component MacWindow
3
+
4
+ @description
5
+ MacWindow 组件模拟 macOS 风格的应用窗口,包含标题栏、工具栏按钮、标签页和状态栏。
6
+ 适用于创建模拟桌面应用界面或代码编辑器等场景。
7
+
8
+ @usage
9
+ 基本用法:
10
+ ```vue
11
+ <MacWindow title="代码编辑器">
12
+ <div>窗口内容</div>
13
+ </MacWindow>
14
+ ```
15
+
16
+ 带标签页:
17
+ ```vue
18
+ <template>
19
+ <MacWindow
20
+ title="设置"
21
+ :tabs="['通用', '外观', '高级']"
22
+ defaultTab="外观"
23
+ :onTabClick="(tab) => {
24
+ activeTab = tab;
25
+ console.log('切换到标签:', tab);
26
+ }"
27
+ >
28
+ <div v-if="activeTab === '通用'">通用设置内容</div>
29
+ <div v-if="activeTab === '外观'">外观设置内容</div>
30
+ <div v-if="activeTab === '高级'">高级设置内容</div>
31
+ </MacWindow>
32
+ </template>
33
+
34
+ <script setup>
35
+ import { ref } from 'vue';
36
+ import { MacWindow } from 'cosy-ui';
37
+
38
+ const activeTab = ref('外观');
39
+ </script>
40
+ ```
41
+
42
+ 带自定义事件处理:
43
+ ```vue
44
+ <MacWindow
45
+ title="文件浏览器"
46
+ :onCloseWindow="() => handleClose()"
47
+ :onTabClick="(tab) => handleTabChange(tab)"
48
+ >
49
+ <div>窗口内容</div>
50
+ </MacWindow>
51
+ ```
52
+
53
+ 带工具栏和状态栏:
54
+ ```vue
55
+ <MacWindow title="文件浏览器">
56
+ <template #toolbar>
57
+ <button class="cosy:btn cosy:btn-ghost cosy:btn-sm">
58
+ <SearchIcon class="cosy:w-4 cosy:h-4" />
59
+ </button>
60
+ <button class="cosy:btn cosy:btn-ghost cosy:btn-sm">
61
+ <SettingsIcon class="cosy:w-4 cosy:h-4" />
62
+ </button>
63
+ </template>
64
+
65
+ <div>窗口内容</div>
66
+
67
+ <template #status>
68
+ <div class="cosy:text-xs">就绪</div>
69
+ <button class="cosy:btn cosy:btn-ghost cosy:btn-xs">
70
+ <InfoIcon class="cosy:w-4 cosy:h-4" />
71
+ </button>
72
+ </template>
73
+ </MacWindow>
74
+ ```
75
+
76
+ @props
77
+ @prop {String} [height='h-96'] - 窗口高度
78
+ @prop {String} [title=''] - 窗口标题
79
+ @prop {Boolean} [withShadow=true] - 是否显示阴影效果
80
+ @prop {Array} [tabs=[]] - 标签页字符串数组,如 ['标签1', '标签2', '标签3']
81
+ @prop {String} [defaultTab=''] - 默认选中的标签页
82
+ @prop {Function} [onCloseWindow=null] - 关闭窗口时调用的函数
83
+ @prop {Function} [onMinimizeWindow=null] - 最小化窗口时调用的函数
84
+ @prop {Function} [onMaximizeWindow=null] - 最大化窗口时调用的函数
85
+ @prop {Function} [onTabClick=null] - 点击标签页时调用的函数,接收标签页值作为参数
86
+
87
+ @slots
88
+ @slot default - 窗口主要内容
89
+ @slot sidebar - 侧边栏内容
90
+ @slot toolbar - 工具栏内容,位于标题栏右侧
91
+ @slot status - 状态栏内容,位于窗口底部
92
+
93
+ @emits
94
+ @emit {update:modelValue} - 切换标签页时触发,用于v-model
95
+ -->
96
+
97
+ <script lang="ts">
98
+ import '../../style.ts';
99
+ import AlertDialog from '../alert-dialog/AlertDialog.vue';
100
+ import { ref, defineComponent, type PropType } from 'vue';
101
+
102
+ export default defineComponent({
103
+ name: 'MacWindow',
104
+ components: {
105
+ AlertDialog,
106
+ },
107
+ props: {
108
+ height: {
109
+ type: String,
110
+ default: 'h-96',
111
+ },
112
+ title: {
113
+ type: String,
114
+ default: '',
115
+ },
116
+ withShadow: {
117
+ type: Boolean,
118
+ default: true,
119
+ },
120
+ tabs: {
121
+ type: Array as PropType<string[]>,
122
+ default: () => [],
123
+ },
124
+ defaultTab: {
125
+ type: String,
126
+ default: '',
127
+ },
128
+ onCloseWindow: {
129
+ type: Function,
130
+ default: null,
131
+ },
132
+ onMinimizeWindow: {
133
+ type: Function,
134
+ default: null,
135
+ },
136
+ onMaximizeWindow: {
137
+ type: Function,
138
+ default: null,
139
+ },
140
+ onTabClick: {
141
+ type: Function,
142
+ default: null,
143
+ },
144
+ },
145
+ setup(props) {
146
+ const showAlertDialog = ref(false);
147
+ const alertMessage = ref('');
148
+ const activeTab = ref(props.defaultTab);
149
+
150
+ // 如果没有设置默认标签或默认标签不在tabs中,则选择第一个标签
151
+ if (
152
+ (!activeTab.value || !props.tabs.includes(activeTab.value)) &&
153
+ props.tabs.length > 0
154
+ ) {
155
+ activeTab.value = props.tabs[0] as string;
156
+ }
157
+
158
+ const handleCloseWindow = () => {
159
+ alertMessage.value = '关闭APP窗口(这是演示,不会真实操作)';
160
+ showAlertDialog.value = true;
161
+ if (props.onCloseWindow) {
162
+ props.onCloseWindow();
163
+ }
164
+ };
165
+
166
+ const handleMinimizeWindow = () => {
167
+ alertMessage.value = '最小化窗口(这是演示,不会真实操作)';
168
+ showAlertDialog.value = true;
169
+ if (props.onMinimizeWindow) {
170
+ props.onMinimizeWindow();
171
+ }
172
+ };
173
+
174
+ const handleMaximizeWindow = () => {
175
+ alertMessage.value = '最大化窗口(这是演示,不会真实操作)';
176
+ showAlertDialog.value = true;
177
+ if (props.onMaximizeWindow) {
178
+ props.onMaximizeWindow();
179
+ }
180
+ };
181
+
182
+ const handleTabClick = (tab: string) => {
183
+ activeTab.value = tab;
184
+ if (props.onTabClick) {
185
+ props.onTabClick(tab);
186
+ }
187
+ };
188
+
189
+ return {
190
+ showAlertDialog,
191
+ alertMessage,
192
+ activeTab,
193
+ handleCloseWindow,
194
+ handleMinimizeWindow,
195
+ handleMaximizeWindow,
196
+ handleTabClick,
197
+ };
198
+ },
199
+ });
200
+ </script>
201
+
202
+ <template>
203
+ <div class="cosy:flex cosy:max-w-5xl cosy:mx-auto cosy:bg-base-100 cosy:relative cosy:rounded-2xl cosy:overflow-hidden"
204
+ :class="[height, withShadow ? 'cosy:shadow-lg' : '']">
205
+ <!-- 窗口控制按钮 -->
206
+ <div
207
+ class="cosy:absolute cosy:top-0 cosy:left-0 cosy:right-0 cosy:flex cosy:items-center cosy:h-12 cosy:px-4 cosy:bg-base-200 cosy:border-b cosy:border-base-300">
208
+ <div class="cosy:flex cosy:items-center cosy:space-x-2">
209
+ <div class="cosy:w-3 cosy:h-3 cosy:rounded-full cosy:bg-error cosy:cursor-pointer hover:cosy:opacity-80 cosy:transition-opacity"
210
+ @click="handleCloseWindow" />
211
+ <div class="cosy:w-3 cosy:h-3 cosy:rounded-full cosy:bg-warning cosy:cursor-pointer hover:cosy:opacity-80 cosy:transition-opacity"
212
+ @click="handleMinimizeWindow" />
213
+ <div class="cosy:w-3 cosy:h-3 cosy:rounded-full cosy:bg-success cosy:cursor-pointer hover:cosy:opacity-80 cosy:transition-opacity"
214
+ @click="handleMaximizeWindow" />
215
+ </div>
216
+ <div class="cosy:ml-6 cosy:text-sm cosy:font-medium cosy:text-base-content">
217
+ {{ title }}
218
+ </div>
219
+
220
+ <!-- 标签选择器 -->
221
+ <div v-if="tabs?.length" class="cosy:flex-1 cosy:flex cosy:justify-center">
222
+ <div class="cosy:inline-flex cosy:rounded-lg cosy:bg-base-300 cosy:p-1">
223
+ <button v-for="(tab, index) in tabs" :key="index" :class="[
224
+ 'cosy:px-3 cosy:py-1 cosy:text-sm cosy:rounded-md cosy:transition-colors',
225
+ activeTab === tab
226
+ ? 'cosy:bg-base-100 cosy:text-base-content cosy:shadow'
227
+ : 'cosy:text-base-content/70 hover:cosy:text-base-content',
228
+ ]" @click="handleTabClick(tab)">
229
+ {{ tab }}
230
+ </button>
231
+ </div>
232
+ </div>
233
+
234
+ <!-- 工具栏插槽 -->
235
+ <div class="cosy:ml-auto cosy:flex cosy:items-center cosy:space-x-2">
236
+ <slot name="toolbar"></slot>
237
+ </div>
238
+ </div>
239
+
240
+ <!-- 主要内容区域 -->
241
+ <div class="cosy:flex-1 cosy:flex cosy:flex-col cosy:pt-12 cosy:h-full">
242
+ <div class="cosy:flex cosy:flex-1 cosy:h-full cosy:overflow-hidden">
243
+ <!-- 左侧栏插槽 -->
244
+ <slot name="sidebar" />
245
+
246
+ <!-- 主内容插槽 -->
247
+ <slot />
248
+ </div>
249
+
250
+ <!-- 底部状态栏 -->
251
+ <div v-if="$slots.status"
252
+ class="cosy:h-6 cosy:bg-base-200/95 cosy:border-t cosy:border-base-300 cosy:flex cosy:items-center cosy:justify-end cosy:px-4 cosy:text-sm">
253
+ <div class="cosy:flex cosy:items-center cosy:space-x-2">
254
+ <slot name="status"></slot>
255
+ </div>
256
+ </div>
257
+ </div>
258
+ </div>
259
+
260
+ <!-- AlertDialog 组件 -->
261
+ <AlertDialog v-model="showAlertDialog" :message="alertMessage" />
262
+ </template>
@@ -0,0 +1,2 @@
1
+ // 导出主组件
2
+ export { default as MacWindow } from './MacWindow.vue';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffic/cosy-ui",
3
- "version": "0.8.16",
3
+ "version": "0.8.18",
4
4
  "description": "An astro component library",
5
5
  "author": {
6
6
  "name": "nookery",
@@ -48,9 +48,19 @@
48
48
  },
49
49
  "type": "module",
50
50
  "peerDependencies": {
51
- "astro": "^5.1.3"
51
+ "astro": "^5.1.3",
52
+ "vue": "^3.0.0"
53
+ },
54
+ "peerDependenciesMeta": {
55
+ "astro": {
56
+ "optional": true
57
+ },
58
+ "vue": {
59
+ "optional": true
60
+ }
52
61
  },
53
62
  "dependencies": {
63
+ "@remixicon/vue": "^4.6.0",
54
64
  "astro-integration-kit": "^0.18.0",
55
65
  "fs-extra": "^11.3.0",
56
66
  "html-to-image": "^1.11.13"
@@ -1 +0,0 @@
1
- export { default as VueCounter } from './VueCounter.vue';
@@ -1,143 +0,0 @@
1
- <!--
2
- @component iPhoneWindow.WeatherApp
3
-
4
- @description
5
- 天气应用示例,展示一个更复杂的 iPhone 应用界面,包含标题栏、主内容区和底部导航。
6
-
7
- @usage
8
- ```vue
9
- <iPhoneWindowExamples.WeatherApp />
10
- ```
11
- -->
12
-
13
- <script lang="ts">
14
- import '../../app.css';
15
- import { defineComponent } from 'vue';
16
- import iPhoneWindow from './iPhoneWindow.vue';
17
-
18
- export default defineComponent({
19
- name: 'iPhoneWindowWeatherAppExample',
20
- components: {
21
- iPhoneWindow,
22
- },
23
- });
24
- </script>
25
-
26
- <template>
27
- <iPhoneWindow>
28
- <div class="cosy:flex cosy:flex-col cosy:h-full">
29
- <!-- 应用标题栏 -->
30
- <div
31
- class="cosy:bg-primary cosy:text-white cosy:px-4 cosy:py-3 cosy:flex cosy:items-center cosy:justify-between"
32
- >
33
- <h2 class="cosy:font-medium">天气预报</h2>
34
- <button class="cosy:btn cosy:btn-ghost cosy:btn-sm cosy:p-1">
35
- <svg
36
- xmlns="http://www.w3.org/2000/svg"
37
- class="cosy:h-5 cosy:w-5"
38
- viewBox="0 0 20 20"
39
- fill="currentColor"
40
- >
41
- <path
42
- fill-rule="evenodd"
43
- d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
44
- clip-rule="evenodd"
45
- />
46
- </svg>
47
- </button>
48
- </div>
49
-
50
- <!-- 主要内容 -->
51
- <div
52
- class="cosy:flex-1 cosy:p-4 cosy:bg-gradient-to-b cosy:from-blue-400 cosy:to-blue-600"
53
- >
54
- <div class="cosy:text-center cosy:text-white">
55
- <div class="cosy:text-5xl cosy:font-light cosy:mb-2">23°</div>
56
- <div class="cosy:text-xl cosy:mb-4">晴朗</div>
57
- <div class="cosy:text-sm cosy:opacity-90">上海市,今天</div>
58
- </div>
59
-
60
- <div
61
- class="cosy:mt-8 cosy:bg-white/20 cosy:backdrop-blur-sm cosy:rounded-xl cosy:p-4"
62
- >
63
- <div
64
- class="cosy:grid cosy:grid-cols-3 cosy:gap-4 cosy:text-center cosy:text-white"
65
- >
66
- <div>
67
- <div class="cosy:text-sm cosy:opacity-80">湿度</div>
68
- <div class="cosy:font-medium">68%</div>
69
- </div>
70
- <div>
71
- <div class="cosy:text-sm cosy:opacity-80">风速</div>
72
- <div class="cosy:font-medium">8 km/h</div>
73
- </div>
74
- <div>
75
- <div class="cosy:text-sm cosy:opacity-80">能见度</div>
76
- <div class="cosy:font-medium">10 km</div>
77
- </div>
78
- </div>
79
- </div>
80
- </div>
81
-
82
- <!-- 底部导航 -->
83
- <div
84
- class="cosy:bg-white cosy:border-t cosy:border-gray-200 cosy:flex cosy:justify-around cosy:py-2"
85
- >
86
- <button class="cosy:p-2 cosy:text-primary">
87
- <svg
88
- xmlns="http://www.w3.org/2000/svg"
89
- class="cosy:h-6 cosy:w-6"
90
- fill="none"
91
- viewBox="0 0 24 24"
92
- stroke="currentColor"
93
- >
94
- <path
95
- stroke-linecap="round"
96
- stroke-linejoin="round"
97
- stroke-width="2"
98
- d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
99
- />
100
- </svg>
101
- </button>
102
- <button class="cosy:p-2">
103
- <svg
104
- xmlns="http://www.w3.org/2000/svg"
105
- class="cosy:h-6 cosy:w-6"
106
- fill="none"
107
- viewBox="0 0 24 24"
108
- stroke="currentColor"
109
- >
110
- <path
111
- stroke-linecap="round"
112
- stroke-linejoin="round"
113
- stroke-width="2"
114
- d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
115
- />
116
- </svg>
117
- </button>
118
- <button class="cosy:p-2">
119
- <svg
120
- xmlns="http://www.w3.org/2000/svg"
121
- class="cosy:h-6 cosy:w-6"
122
- fill="none"
123
- viewBox="0 0 24 24"
124
- stroke="currentColor"
125
- >
126
- <path
127
- stroke-linecap="round"
128
- stroke-linejoin="round"
129
- stroke-width="2"
130
- d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
131
- />
132
- <path
133
- stroke-linecap="round"
134
- stroke-linejoin="round"
135
- stroke-width="2"
136
- d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
137
- />
138
- </svg>
139
- </button>
140
- </div>
141
- </div>
142
- </iPhoneWindow>
143
- </template>
@@ -1,247 +0,0 @@
1
- <!--
2
- @component iPhoneWindow
3
-
4
- @description
5
- iPhoneWindow 组件模拟 iPhone 设备的外观,包含状态栏、时间显示和设备边框。
6
- 适用于创建移动应用界面原型或展示移动端设计效果。
7
-
8
- @usage
9
- 基本用法:
10
- ```vue
11
- <iPhoneWindow>
12
- <div>应用内容</div>
13
- </iPhoneWindow>
14
- ```
15
-
16
- 不显示边框:
17
- ```vue
18
- <iPhoneWindow :showFrame="false">
19
- <div>应用内容</div>
20
- </iPhoneWindow>
21
- ```
22
-
23
- 自定义背景色:
24
- ```vue
25
- <iPhoneWindow backgroundColor="bg-blue-50">
26
- <div>应用内容</div>
27
- </iPhoneWindow>
28
- ```
29
-
30
- @props
31
- @prop {String} [height='h-96'] - 窗口高度
32
- @prop {String} [title=''] - 窗口标题
33
- @prop {Array} [statusBarButtons=[]] - 状态栏按钮数组
34
- @prop {Boolean} [withShadow=true] - 是否显示阴影效果
35
- @prop {Boolean} [showFrame=true] - 是否显示 iPhone 边框
36
- @prop {String} [backgroundColor=''] - 内容区域背景色
37
-
38
- @slots
39
- @slot default - 主要内容区域
40
-
41
- @emits
42
- -->
43
- <script lang="ts">
44
- import '../../style.ts';
45
- import { AlertDialog } from '../../index-vue.ts';
46
- import { ref, onMounted, onUnmounted, defineComponent } from 'vue';
47
- // 导入内部图片资源
48
- import iphoneFrame from './assets/iPhone 14 Pro - Deep Purple - Portrait.png';
49
-
50
- export default defineComponent({
51
- name: 'iPhoneWindow',
52
- components: {
53
- AlertDialog,
54
- },
55
- props: {
56
- height: {
57
- type: String,
58
- default: 'h-96',
59
- },
60
- title: {
61
- type: String,
62
- default: '',
63
- },
64
- statusBarButtons: {
65
- type: Array,
66
- default: () => [],
67
- },
68
- withShadow: {
69
- type: Boolean,
70
- default: true,
71
- },
72
- showFrame: {
73
- type: Boolean,
74
- default: true,
75
- },
76
- backgroundColor: {
77
- type: String,
78
- default: '',
79
- },
80
- },
81
- setup() {
82
- const showAlertDialog = ref(false);
83
- const alertMessage = ref('');
84
- const currentTime = ref('12:00');
85
-
86
- // 获取图片URL
87
- const frameSrc =
88
- typeof iphoneFrame === 'string' ? iphoneFrame : iphoneFrame.src;
89
-
90
- // 更新时间的函数
91
- const updateTime = () => {
92
- const now = new Date();
93
- const hours = now.getHours().toString().padStart(2, '0');
94
- const minutes = now.getMinutes().toString().padStart(2, '0');
95
- currentTime.value = `${hours}:${minutes}`;
96
- };
97
-
98
- // 设置定时器更新时间
99
- let timeInterval: number;
100
- onMounted(() => {
101
- updateTime();
102
- timeInterval = window.setInterval(updateTime, 60000); // 每分钟更新一次
103
- });
104
-
105
- onUnmounted(() => {
106
- if (timeInterval) {
107
- clearInterval(timeInterval);
108
- }
109
- });
110
-
111
- return {
112
- showAlertDialog,
113
- alertMessage,
114
- currentTime,
115
- frameSrc,
116
- };
117
- },
118
- });
119
- </script>
120
-
121
- <template>
122
- <div class="cosy:relative cosy:w-full">
123
- <div class="cosy:relative cosy:aspect-[9/19.5]">
124
- <!-- iPhone 边框 (放在最底层) -->
125
- <img
126
- v-if="showFrame"
127
- :src="frameSrc"
128
- alt="iPhone frame"
129
- class="cosy:absolute cosy:inset-0 cosy:w-full cosy:h-full cosy:object-contain"
130
- />
131
-
132
- <!-- 内容区域 -->
133
- <div
134
- :class="[
135
- 'cosy:absolute cosy:inset-0',
136
- showFrame ? 'cosy:px-[6%] cosy:pt-[13%] cosy:pb-[13%]' : '',
137
- ]"
138
- >
139
- <div
140
- :class="[
141
- 'cosy:w-full cosy:h-full cosy:flex cosy:flex-col cosy:overflow-hidden',
142
- showFrame
143
- ? 'cosy:rounded-t-[2.5em] cosy:rounded-b-[2.5rem]'
144
- : 'cosy:rounded-lg cosy:shadow',
145
- backgroundColor || 'cosy:bg-transparent',
146
- ]"
147
- >
148
- <!-- 顶部状态栏 (z-index 设为负数,确保在边框下方) -->
149
- <div
150
- class="cosy:flex-none cosy:h-12 cosy:px-4 cosy:z-0 cosy:relative"
151
- >
152
- <div
153
- class="cosy:flex cosy:items-center cosy:h-full cosy:justify-between"
154
- >
155
- <!-- 左侧时间 -->
156
- <div class="cosy:flex cosy:items-center">
157
- <span
158
- class="cosy:text-sm cosy:font-medium cosy:text-gray-700 cosy:dark:text-gray-200"
159
- >{{ currentTime }}</span
160
- >
161
- </div>
162
- <!-- 右侧状态图标 -->
163
- <div class="cosy:flex cosy:items-center cosy:space-x-1.5">
164
- <!-- 信号图标 -->
165
- <svg
166
- class="cosy:w-5 cosy:h-3.5 cosy:text-gray-700 cosy:dark:text-gray-200"
167
- viewBox="0 0 20 12"
168
- fill="none"
169
- stroke="currentColor"
170
- >
171
- <path
172
- d="M1 11h2V6H1v5zm4 0h2V4H5v7zm4 0h2V2H9v9zm4 0h2V0h-2v11z"
173
- fill="currentColor"
174
- />
175
- <path
176
- d="M17 11h2V0h-2v11z"
177
- fill="currentColor"
178
- opacity="0.4"
179
- />
180
- </svg>
181
- <!-- Wi-Fi图标 -->
182
- <svg
183
- class="cosy:w-5 cosy:h-4 cosy:text-gray-700 cosy:dark:text-gray-200"
184
- viewBox="0 0 16 12"
185
- fill="currentColor"
186
- >
187
- <path
188
- d="M8 10.5a1 1 0 100-2 1 1 0 000 2zM4.25 7.25a5 5 0 017.5 0l-1.06 1.06a3.5 3.5 0 00-5.38 0L4.25 7.25z"
189
- />
190
- <path
191
- d="M1.75 4.75a8.5 8.5 0 0112.5 0l-1.06 1.06a7 7 0 00-10.38 0L1.75 4.75z"
192
- />
193
- </svg>
194
- <!-- 电池图标 -->
195
- <div class="cosy:flex cosy:items-center cosy:space-x-0.5">
196
- <svg
197
- class="cosy:w-6 cosy:h-3.5 cosy:text-gray-700 cosy:dark:text-gray-200"
198
- viewBox="0 0 25 12"
199
- fill="none"
200
- stroke="currentColor"
201
- >
202
- <rect
203
- x="0.5"
204
- y="0.5"
205
- width="21"
206
- height="11"
207
- rx="2.5"
208
- stroke-width="1"
209
- />
210
- <rect
211
- x="2"
212
- y="2"
213
- width="18"
214
- height="8"
215
- rx="1"
216
- fill="currentColor"
217
- />
218
- <path
219
- d="M23 4h1a1 1 0 011 1v2a1 1 0 01-1 1h-1V4z"
220
- fill="currentColor"
221
- />
222
- </svg>
223
- </div>
224
- </div>
225
- </div>
226
- </div>
227
-
228
- <!-- 主要内容区域 -->
229
- <div
230
- class="cosy:flex-1 cosy:flex cosy:flex-col cosy:overflow-hidden cosy:relative"
231
- >
232
- <slot />
233
- </div>
234
- </div>
235
- </div>
236
- </div>
237
- </div>
238
- <!-- 添加 AlertDialog 组件 -->
239
- <AlertDialog v-model="showAlertDialog" :message="alertMessage" />
240
- </template>
241
-
242
- <style scoped>
243
- /* 确保图标渲染更平滑 */
244
- svg {
245
- shape-rendering: geometricPrecision;
246
- }
247
- </style>
@@ -1,9 +0,0 @@
1
- <script setup>
2
- import { MacWindow } from './index';
3
- </script>
4
-
5
- <template>
6
- <MacWindow title="代码编辑器">
7
- <div class="cosy:p-4">窗口内容区域</div>
8
- </MacWindow>
9
- </template>