@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.
- package/dist/app.css +1 -1
- package/dist/index-vue.ts +14 -8
- package/dist/src-astro/header/Header.astro +1 -1
- package/dist/src-astro/icons/AstroIcon.astro +2 -3
- package/dist/src-astro/module/ModuleBasic.astro +1 -1
- package/dist/src-astro/module/ModuleCustom.astro +1 -1
- package/dist/src-astro/module/ModuleGrid.astro +3 -3
- package/dist/src-astro/sidebar-nav/SidebarNav.astro +3 -3
- package/dist/src-astro/speak/SpeakBasic.astro +1 -1
- package/dist/src-astro/speak/SpeakGrid.astro +3 -3
- package/dist/src-vue/SmartLink.vue +0 -1
- package/dist/src-vue/alert/Alert.vue +100 -0
- package/dist/src-vue/alert/index.ts +8 -0
- package/dist/src-vue/{alert-dialog-vue → alert-dialog}/index.ts +1 -1
- package/dist/src-vue/{banner-box-vue → banner-box}/index.ts +1 -1
- package/dist/src-vue/{blog-vue → blog}/BlogList.vue +2 -2
- package/dist/src-vue/{blog-vue → blog}/index.ts +1 -1
- package/dist/src-vue/{confirm-dialog-vue → confirm-dialog}/index.ts +1 -1
- package/dist/src-vue/container/Container.vue +214 -0
- package/dist/src-vue/container/index.ts +6 -0
- package/dist/src-vue/counter/index.ts +1 -0
- package/dist/src-vue/iPhone/StatusBarContent.vue +121 -0
- package/dist/src-vue/iPhone/iPhoneWindow.vue +234 -0
- package/dist/src-vue/{iPhone-vue → iPhone}/index.ts +10 -14
- package/dist/src-vue/icons/ErrorIcon.vue +30 -0
- package/dist/src-vue/icons/IPhoneBatteryIcon.vue +7 -0
- package/dist/src-vue/icons/IPhoneSignalIcon.vue +6 -0
- package/dist/src-vue/icons/IPhoneWifiIcon.vue +6 -0
- package/dist/src-vue/icons/SuccessIcon.vue +30 -0
- package/dist/src-vue/icons/VueIcon.vue +13 -3
- package/dist/src-vue/icons/WarningIcon.vue +30 -0
- package/dist/src-vue/icons/index.ts +22 -1
- package/dist/src-vue/mac-window/MacWindow.vue +262 -0
- package/dist/src-vue/mac-window/index.ts +2 -0
- package/package.json +12 -2
- package/dist/src-vue/counter-vue/index.ts +0 -1
- package/dist/src-vue/iPhone-vue/WeatherApp.vue +0 -143
- package/dist/src-vue/iPhone-vue/iPhoneWindow.vue +0 -247
- package/dist/src-vue/mac-window-vue/Basic.vue +0 -9
- package/dist/src-vue/mac-window-vue/CustomHeight.vue +0 -13
- package/dist/src-vue/mac-window-vue/MacWindow.vue +0 -283
- package/dist/src-vue/mac-window-vue/WithEvents.vue +0 -40
- package/dist/src-vue/mac-window-vue/WithSidebar.vue +0 -31
- package/dist/src-vue/mac-window-vue/WithTabs.vue +0 -26
- package/dist/src-vue/mac-window-vue/WithToolbar.vue +0 -44
- package/dist/src-vue/mac-window-vue/index.ts +0 -36
- /package/dist/{src-astro → src}/assets/book.png +0 -0
- /package/dist/{src-astro → src}/assets/iconData.ts +0 -0
- /package/dist/{src-astro → src}/assets/logo-rounded.png +0 -0
- /package/dist/{src-astro → src}/assets/logo.png +0 -0
- /package/dist/src-vue/{alert-dialog-vue → alert-dialog}/AlertDialog.vue +0 -0
- /package/dist/src-vue/{alert-dialog-vue → alert-dialog}/Basic.vue +0 -0
- /package/dist/src-vue/{alert-dialog-vue → alert-dialog}/Multilang.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/BannerBox.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/DownloadButton.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleBasic.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleCustomBg.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleDisplayModeAlways.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleDisplayModeHover.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleDisplayModeNever.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleImageExport.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/ExampleSizePreset.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/FeatureCard.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/SmartBanner.vue +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/bgStyles.ts +0 -0
- /package/dist/src-vue/{banner-box-vue → banner-box}/sizePresets.ts +0 -0
- /package/dist/src-vue/{blog-vue → blog}/Basic.vue +0 -0
- /package/dist/src-vue/{blog-vue → blog}/Empty.vue +0 -0
- /package/dist/src-vue/{blog-vue → blog}/EmptyEnglish.vue +0 -0
- /package/dist/src-vue/{blog-vue → blog}/English.vue +0 -0
- /package/dist/src-vue/{confirm-dialog-vue → confirm-dialog}/Basic.vue +0 -0
- /package/dist/src-vue/{confirm-dialog-vue → confirm-dialog}/ConfirmDialog.vue +0 -0
- /package/dist/src-vue/{confirm-dialog-vue → confirm-dialog}/CustomButtons.vue +0 -0
- /package/dist/src-vue/{counter-vue → counter}/VueCounter.vue +0 -0
- /package/dist/src-vue/{iPhone-vue → iPhone}/Basic.vue +0 -0
- /package/dist/src-vue/{iPhone-vue → iPhone}/CustomBackground.vue +0 -0
- /package/dist/src-vue/{iPhone-vue → iPhone}/NoFrame.vue +0 -0
- /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Deep Purple - Landscape.png +0 -0
- /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Deep Purple - Portrait.png +0 -0
- /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Gold - Landscape.png +0 -0
- /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Gold - Portrait.png +0 -0
- /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Silver - Landscape.png +0 -0
- /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Silver - Portrait.png +0 -0
- /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Space Black - Landscape.png +0 -0
- /package/dist/src-vue/{iPhone-vue → iPhone}/assets/iPhone 14 Pro - Space Black - Portrait.png +0 -0
- /package/dist/src-vue/{list-vue → list}/ListItem.vue +0 -0
- /package/dist/src-vue/{list-vue → list}/index.ts +0 -0
package/dist/index-vue.ts
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
// AlertDialog
|
2
|
-
export * from './src-vue/alert-dialog
|
2
|
+
export * from './src-vue/alert-dialog/index';
|
3
|
+
|
4
|
+
// Alert
|
5
|
+
export * from './src-vue/alert/index';
|
3
6
|
|
4
7
|
// Banner
|
5
|
-
export * from './src-vue/banner-box
|
8
|
+
export * from './src-vue/banner-box/index';
|
6
9
|
|
7
10
|
// BlogList
|
8
|
-
export * from './src-vue/blog
|
11
|
+
export * from './src-vue/blog/index';
|
12
|
+
|
13
|
+
// Container
|
14
|
+
export * from './src-vue/container/index';
|
9
15
|
|
10
16
|
// Counter
|
11
|
-
export * from './src-vue/counter
|
17
|
+
export * from './src-vue/counter/index';
|
12
18
|
|
13
19
|
// ConfirmDialog
|
14
|
-
export * from './src-vue/confirm-dialog
|
20
|
+
export * from './src-vue/confirm-dialog/index';
|
15
21
|
|
16
22
|
// Buttons
|
17
23
|
export * from './src-vue/buttons/index';
|
@@ -20,11 +26,11 @@ export * from './src-vue/buttons/index';
|
|
20
26
|
export * from './src-vue/icons/index';
|
21
27
|
|
22
28
|
// List
|
23
|
-
export * from './src-vue/list
|
29
|
+
export * from './src-vue/list/index';
|
24
30
|
|
25
31
|
// Windows
|
26
|
-
|
27
|
-
|
32
|
+
export * from './src-vue/mac-window/index';
|
33
|
+
export * from './src-vue/iPhone/index';
|
28
34
|
|
29
35
|
// SmartLink
|
30
36
|
// export { default as SmartLink } from './vue/SmartLink.vue';
|
@@ -1,5 +1,5 @@
|
|
1
1
|
---
|
2
|
-
import { iconData } from '
|
2
|
+
import { iconData } from '../../src/assets/iconData';
|
3
3
|
|
4
4
|
interface Props {
|
5
5
|
/**
|
@@ -54,8 +54,7 @@ const viewBox = icon?.viewBox || '0 0 24 24';
|
|
54
54
|
stroke-width="2"
|
55
55
|
stroke-linecap="round"
|
56
56
|
stroke-linejoin="round"
|
57
|
-
class={className}
|
58
|
-
>
|
57
|
+
class={className}>
|
59
58
|
<path d={icon.path} />
|
60
59
|
</svg>
|
61
60
|
)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
---
|
2
2
|
import { Module } from '../../index-astro';
|
3
|
-
import featureImage1 from '
|
4
|
-
import featureImage2 from '
|
5
|
-
import featureImage3 from '
|
3
|
+
import featureImage1 from '../../src/assets/logo-rounded.png';
|
4
|
+
import featureImage2 from '../../src/assets/logo-rounded.png';
|
5
|
+
import featureImage3 from '../../src/assets/logo-rounded.png';
|
6
6
|
---
|
7
7
|
|
8
8
|
<div
|
@@ -58,19 +58,19 @@ const debugClass = debug ? 'cosy:border cosy:border-red-500' : '';
|
|
58
58
|
</h3>
|
59
59
|
<ul
|
60
60
|
class:list={[
|
61
|
-
'cosy:menu cosy:bg-base-200 cosy:rounded-box cosy:w-56',
|
61
|
+
'cosy:menu cosy:bg-base-200 cosy:rounded-box cosy:w-56 cosy:no-underline',
|
62
62
|
debugClass,
|
63
63
|
]}>
|
64
64
|
{section.items?.map((item: ISidebarItem) => {
|
65
65
|
const isActive = isPathMatch(currentPath, item.href);
|
66
66
|
return (
|
67
|
-
<li class:list={[debugClass]}>
|
67
|
+
<li class:list={[debugClass, 'cosy:no-underline']}>
|
68
68
|
<a
|
69
69
|
data-sidebar-item
|
70
70
|
data-current-path={currentPath}
|
71
71
|
href={item.href}
|
72
72
|
class:list={[
|
73
|
-
'cosy:hover:bg-base-300',
|
73
|
+
'cosy:hover:bg-base-300 cosy:no-underline',
|
74
74
|
{ 'cosy:menu-active': isActive },
|
75
75
|
debugClass,
|
76
76
|
]}>
|
@@ -1,8 +1,8 @@
|
|
1
1
|
---
|
2
2
|
import { Speak } from '../../index-astro';
|
3
|
-
import avatar1 from '
|
4
|
-
import avatar2 from '
|
5
|
-
import avatar3 from '
|
3
|
+
import avatar1 from '../../src/assets/logo-rounded.png';
|
4
|
+
import avatar2 from '../../src/assets/logo-rounded.png';
|
5
|
+
import avatar3 from '../../src/assets/logo-rounded.png';
|
6
6
|
---
|
7
7
|
|
8
8
|
<div
|
@@ -0,0 +1,100 @@
|
|
1
|
+
<!--
|
2
|
+
@component Alert
|
3
|
+
|
4
|
+
@description
|
5
|
+
Alert 组件用于向用户显示重要的提示信息,支持多种类型的提示样式和交互效果。
|
6
|
+
|
7
|
+
@usage
|
8
|
+
基本用法:
|
9
|
+
```vue
|
10
|
+
<Alert type="info">这是一条信息提示</Alert>
|
11
|
+
```
|
12
|
+
|
13
|
+
带标题:
|
14
|
+
```vue
|
15
|
+
<Alert type="success" title="操作成功">您的操作已成功完成</Alert>
|
16
|
+
```
|
17
|
+
|
18
|
+
组合使用:
|
19
|
+
```vue
|
20
|
+
<Alert
|
21
|
+
type="error"
|
22
|
+
title="提交失败"
|
23
|
+
class="my-custom-class"
|
24
|
+
>
|
25
|
+
请检查表单并重新提交
|
26
|
+
</Alert>
|
27
|
+
```
|
28
|
+
|
29
|
+
@props
|
30
|
+
@prop {('info'|'success'|'warning'|'error')} [type='info'] - 提示类型,影响颜色和图标
|
31
|
+
@prop {string} [title] - 提示标题,可选
|
32
|
+
@prop {string} [class] - 自定义 CSS 类名
|
33
|
+
|
34
|
+
@slots
|
35
|
+
@slot default - 提示内容
|
36
|
+
-->
|
37
|
+
|
38
|
+
<script setup lang="ts">
|
39
|
+
import '../../style.ts';
|
40
|
+
import { computed } from 'vue';
|
41
|
+
import { InfoIcon, SuccessIcon, WarningIcon, ErrorIcon } from '../icons/index';
|
42
|
+
|
43
|
+
interface Props {
|
44
|
+
type?: 'info' | 'success' | 'warning' | 'error';
|
45
|
+
title?: string;
|
46
|
+
class?: string;
|
47
|
+
}
|
48
|
+
|
49
|
+
const props = withDefaults(defineProps<Props>(), {
|
50
|
+
type: 'info',
|
51
|
+
title: '',
|
52
|
+
class: '',
|
53
|
+
});
|
54
|
+
|
55
|
+
// 根据类型设置样式
|
56
|
+
const alertClass = computed(() => {
|
57
|
+
const alertClasses = {
|
58
|
+
info: 'cosy:alert-info',
|
59
|
+
success: 'cosy:alert-success',
|
60
|
+
warning: 'cosy:alert-warning',
|
61
|
+
error: 'cosy:alert-error',
|
62
|
+
};
|
63
|
+
return alertClasses[props.type];
|
64
|
+
});
|
65
|
+
|
66
|
+
// 根据类型设置图标组件
|
67
|
+
const IconComponent = computed(() => {
|
68
|
+
const iconComponents = {
|
69
|
+
info: InfoIcon,
|
70
|
+
success: SuccessIcon,
|
71
|
+
warning: WarningIcon,
|
72
|
+
error: ErrorIcon,
|
73
|
+
};
|
74
|
+
return iconComponents[props.type];
|
75
|
+
});
|
76
|
+
</script>
|
77
|
+
|
78
|
+
<template>
|
79
|
+
<div :class="['cosy:alert', alertClass, props.class]" role="alert">
|
80
|
+
<div
|
81
|
+
class="cosy:flex cosy:flex-row cosy:items-center cosy:gap-4 cosy:alert-content"
|
82
|
+
>
|
83
|
+
<component :is="IconComponent" />
|
84
|
+
|
85
|
+
<div class="cosy:flex cosy:flex-col cosy:items-center cosy:h-full">
|
86
|
+
<h3
|
87
|
+
v-if="props.title"
|
88
|
+
class="cosy:font-bold"
|
89
|
+
style="margin-top: 0 !important"
|
90
|
+
>
|
91
|
+
{{ props.title }}
|
92
|
+
</h3>
|
93
|
+
<div v-if="props.title" class="cosy:text-xs">
|
94
|
+
<slot />
|
95
|
+
</div>
|
96
|
+
<slot v-else />
|
97
|
+
</div>
|
98
|
+
</div>
|
99
|
+
</div>
|
100
|
+
</template>
|
@@ -2,7 +2,7 @@ import Basic from './Basic.vue';
|
|
2
2
|
import Multilang from './Multilang.vue';
|
3
3
|
import BasicSource from './Basic.vue?raw';
|
4
4
|
import MultilangSource from './Multilang.vue?raw';
|
5
|
-
import { extractSimpleExample } from '../../utils/component';
|
5
|
+
import { extractSimpleExample } from '../../src/utils/component';
|
6
6
|
|
7
7
|
// 导出主组件
|
8
8
|
export { default as AlertDialog } from './AlertDialog.vue';
|
@@ -14,7 +14,7 @@ import DisplayModeNeverSource from './ExampleDisplayModeNever.vue?raw';
|
|
14
14
|
import SmartBannerSource from './SmartBanner.vue?raw';
|
15
15
|
import SizePresetSource from './ExampleSizePreset.vue?raw';
|
16
16
|
import ImageExportSource from './ExampleImageExport.vue?raw';
|
17
|
-
import { extractSimpleExample } from '../../utils/component';
|
17
|
+
import { extractSimpleExample } from '../../src/utils/component';
|
18
18
|
|
19
19
|
// 获取 BannerBox 和 FeatureCard 组件
|
20
20
|
export { default as BannerBox } from './BannerBox.vue';
|
@@ -39,9 +39,9 @@ const currentLang = ref('zh');
|
|
39
39
|
|
40
40
|
<script setup lang="ts">
|
41
41
|
import '../../style';
|
42
|
-
import InboxArchiveIcon from '../
|
42
|
+
import InboxArchiveIcon from '../icons/InboxArchiveIcon.vue';
|
43
43
|
import Link from '../SmartLink.vue';
|
44
|
-
import ListItem from '../ListItem.vue';
|
44
|
+
import ListItem from '../list/ListItem.vue';
|
45
45
|
|
46
46
|
export interface IBlog {
|
47
47
|
id: string;
|
@@ -6,7 +6,7 @@ import BasicSource from './Basic.vue?raw';
|
|
6
6
|
import EmptySource from './Empty.vue?raw';
|
7
7
|
import EnglishSource from './English.vue?raw';
|
8
8
|
import EmptyEnglishSource from './EmptyEnglish.vue?raw';
|
9
|
-
import { extractSimpleExample } from '../../utils/component';
|
9
|
+
import { extractSimpleExample } from '../../src/utils/component';
|
10
10
|
|
11
11
|
// 导出主组件
|
12
12
|
export { default as BlogList } from './BlogList.vue';
|
@@ -2,7 +2,7 @@ import Basic from './Basic.vue';
|
|
2
2
|
import CustomButtons from './CustomButtons.vue';
|
3
3
|
import BasicSource from './Basic.vue?raw';
|
4
4
|
import CustomButtonsSource from './CustomButtons.vue?raw';
|
5
|
-
import { extractSimpleExample } from '../../utils/component';
|
5
|
+
import { extractSimpleExample } from '../../src/utils/component';
|
6
6
|
|
7
7
|
// 导出主组件
|
8
8
|
export { default as ConfirmDialog } from './ConfirmDialog.vue';
|
@@ -0,0 +1,214 @@
|
|
1
|
+
<!--
|
2
|
+
@component Container
|
3
|
+
|
4
|
+
@description
|
5
|
+
Container 组件是一个基础的布局容器,用于限制内容宽度并居中显示。
|
6
|
+
它提供了多种尺寸和内边距选项,适用于各种布局需求。
|
7
|
+
|
8
|
+
@design
|
9
|
+
设计理念:
|
10
|
+
1. 内容约束 - 限制内容宽度,提高可读性和视觉美感
|
11
|
+
2. 响应式设计 - 在不同屏幕尺寸下自动调整内边距
|
12
|
+
3. 灵活配置 - 支持多种尺寸和内边距选项
|
13
|
+
4. 简单易用 - 提供直观的API,易于集成到各种页面布局中
|
14
|
+
|
15
|
+
@usage
|
16
|
+
基本用法:
|
17
|
+
```vue
|
18
|
+
<Container>
|
19
|
+
<p>内容将被限制在一个合理的宽度内并居中显示</p>
|
20
|
+
</Container>
|
21
|
+
```
|
22
|
+
|
23
|
+
自定义尺寸和内边距:
|
24
|
+
```vue
|
25
|
+
<Container size="sm" padding="lg">
|
26
|
+
<p>小尺寸容器,大内边距</p>
|
27
|
+
</Container>
|
28
|
+
```
|
29
|
+
|
30
|
+
全宽容器:
|
31
|
+
```vue
|
32
|
+
<Container size="full" padding="none">
|
33
|
+
<p>全宽容器,无内边距</p>
|
34
|
+
</Container>
|
35
|
+
```
|
36
|
+
|
37
|
+
不居中的容器:
|
38
|
+
```vue
|
39
|
+
<Container :centered="false">
|
40
|
+
<p>不居中的容器,靠左对齐</p>
|
41
|
+
</Container>
|
42
|
+
```
|
43
|
+
|
44
|
+
带边框的容器:
|
45
|
+
```vue
|
46
|
+
<Container border>
|
47
|
+
<p>带有边框的容器</p>
|
48
|
+
</Container>
|
49
|
+
```
|
50
|
+
|
51
|
+
Flex布局容器(按行排列):
|
52
|
+
```vue
|
53
|
+
<Container flex="row" gap="md">
|
54
|
+
<div>第一项</div>
|
55
|
+
<div>第二项</div>
|
56
|
+
</Container>
|
57
|
+
```
|
58
|
+
|
59
|
+
Flex布局容器(按列排列):
|
60
|
+
```vue
|
61
|
+
<Container flex="col" gap="md" items="center" justify="between">
|
62
|
+
<div>第一项</div>
|
63
|
+
<div>第二项</div>
|
64
|
+
</Container>
|
65
|
+
```
|
66
|
+
|
67
|
+
@props
|
68
|
+
@prop {('xs'|'sm'|'md'|'lg'|'xl'|'full')} [size='md'] - 容器尺寸
|
69
|
+
@prop {('none'|'sm'|'md'|'lg'|'xl')} [padding='md'] - 内边距大小
|
70
|
+
@prop {boolean} [centered=true] - 是否居中显示
|
71
|
+
@prop {boolean} [border=false] - 是否显示边框
|
72
|
+
@prop {('row'|'col'|'row-reverse'|'col-reverse')} [flex] - flex布局方向
|
73
|
+
@prop {('none'|'xs'|'sm'|'md'|'lg'|'xl')} [gap='none'] - flex项目间距
|
74
|
+
@prop {('start'|'end'|'center'|'baseline'|'stretch')} [items] - flex项目水平对齐方式
|
75
|
+
@prop {('start'|'end'|'center'|'between'|'around'|'evenly')} [justify] - flex项目垂直对齐方式
|
76
|
+
@prop {string} [class=''] - 自定义类名
|
77
|
+
-->
|
78
|
+
|
79
|
+
<script setup lang="ts">
|
80
|
+
import '../../style.ts';
|
81
|
+
import { computed } from 'vue';
|
82
|
+
|
83
|
+
interface Props {
|
84
|
+
/**
|
85
|
+
* 容器尺寸
|
86
|
+
* @default "md"
|
87
|
+
*/
|
88
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
89
|
+
|
90
|
+
/**
|
91
|
+
* 内边距大小
|
92
|
+
* @default "md"
|
93
|
+
*/
|
94
|
+
padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
95
|
+
|
96
|
+
/**
|
97
|
+
* 是否居中显示
|
98
|
+
* @default true
|
99
|
+
*/
|
100
|
+
centered?: boolean;
|
101
|
+
|
102
|
+
/**
|
103
|
+
* 是否显示边框
|
104
|
+
* @default false
|
105
|
+
*/
|
106
|
+
border?: boolean;
|
107
|
+
|
108
|
+
/**
|
109
|
+
* flex布局方向,不设置则不启用flex布局
|
110
|
+
*/
|
111
|
+
flex?: 'row' | 'col' | 'row-reverse' | 'col-reverse';
|
112
|
+
|
113
|
+
/**
|
114
|
+
* flex项目间距
|
115
|
+
* @default "none"
|
116
|
+
*/
|
117
|
+
gap?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
118
|
+
|
119
|
+
/**
|
120
|
+
* flex项目水平对齐方式
|
121
|
+
*/
|
122
|
+
items?: 'start' | 'end' | 'center' | 'baseline' | 'stretch';
|
123
|
+
|
124
|
+
/**
|
125
|
+
* flex项目垂直对齐方式
|
126
|
+
*/
|
127
|
+
justify?: 'start' | 'end' | 'center' | 'between' | 'around' | 'evenly';
|
128
|
+
|
129
|
+
/**
|
130
|
+
* 自定义类名
|
131
|
+
*/
|
132
|
+
class?: string;
|
133
|
+
}
|
134
|
+
|
135
|
+
const props = withDefaults(defineProps<Props>(), {
|
136
|
+
size: 'md',
|
137
|
+
padding: 'md',
|
138
|
+
centered: true,
|
139
|
+
border: false,
|
140
|
+
gap: 'none',
|
141
|
+
class: '',
|
142
|
+
});
|
143
|
+
|
144
|
+
// 静态类名映射
|
145
|
+
const sizeClasses = {
|
146
|
+
xs: 'cosy:max-w-xs',
|
147
|
+
sm: 'cosy:max-w-sm',
|
148
|
+
md: 'cosy:max-w-2xl',
|
149
|
+
lg: 'cosy:max-w-4xl',
|
150
|
+
xl: 'cosy:max-w-6xl',
|
151
|
+
full: 'cosy:w-full',
|
152
|
+
} as const;
|
153
|
+
|
154
|
+
const paddingClasses = {
|
155
|
+
none: 'cosy:p-0',
|
156
|
+
sm: 'cosy:p-2',
|
157
|
+
md: 'cosy:p-4',
|
158
|
+
lg: 'cosy:p-6',
|
159
|
+
xl: 'cosy:p-8',
|
160
|
+
} as const;
|
161
|
+
|
162
|
+
const flexClasses = {
|
163
|
+
row: 'cosy:flex cosy:flex-row',
|
164
|
+
col: 'cosy:flex cosy:flex-col',
|
165
|
+
'row-reverse': 'cosy:flex cosy:flex-row-reverse',
|
166
|
+
'col-reverse': 'cosy:flex cosy:flex-col-reverse',
|
167
|
+
} as const;
|
168
|
+
|
169
|
+
const gapClasses = {
|
170
|
+
none: 'cosy:gap-0',
|
171
|
+
xs: 'cosy:gap-1',
|
172
|
+
sm: 'cosy:gap-2',
|
173
|
+
md: 'cosy:gap-4',
|
174
|
+
lg: 'cosy:gap-6',
|
175
|
+
xl: 'cosy:gap-8',
|
176
|
+
} as const;
|
177
|
+
|
178
|
+
const itemsClasses = {
|
179
|
+
start: 'cosy:items-start',
|
180
|
+
end: 'cosy:items-end',
|
181
|
+
center: 'cosy:items-center',
|
182
|
+
baseline: 'cosy:items-baseline',
|
183
|
+
stretch: 'cosy:items-stretch',
|
184
|
+
} as const;
|
185
|
+
|
186
|
+
const justifyClasses = {
|
187
|
+
start: 'cosy:justify-start',
|
188
|
+
end: 'cosy:justify-end',
|
189
|
+
center: 'cosy:justify-center',
|
190
|
+
between: 'cosy:justify-between',
|
191
|
+
around: 'cosy:justify-around',
|
192
|
+
evenly: 'cosy:justify-evenly',
|
193
|
+
} as const;
|
194
|
+
|
195
|
+
// 构建CSS类名
|
196
|
+
const containerClasses = computed(() => [
|
197
|
+
'cosy:w-full',
|
198
|
+
props.centered ? 'cosy:mx-auto' : '',
|
199
|
+
sizeClasses[props.size],
|
200
|
+
paddingClasses[props.padding],
|
201
|
+
props.border ? 'cosy:border cosy:rounded-lg' : '',
|
202
|
+
props.flex ? flexClasses[props.flex] : '',
|
203
|
+
props.flex ? gapClasses[props.gap] : '',
|
204
|
+
props.items && props.flex ? itemsClasses[props.items] : '',
|
205
|
+
props.justify && props.flex ? justifyClasses[props.justify] : '',
|
206
|
+
props.class,
|
207
|
+
]);
|
208
|
+
</script>
|
209
|
+
|
210
|
+
<template>
|
211
|
+
<section :class="containerClasses">
|
212
|
+
<slot />
|
213
|
+
</section>
|
214
|
+
</template>
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default as Counter } from './VueCounter.vue';
|
@@ -0,0 +1,121 @@
|
|
1
|
+
<!--
|
2
|
+
@component StatusBarContent
|
3
|
+
|
4
|
+
@description
|
5
|
+
StatusBarContent 组件显示 iPhone 状态栏的内容,包括时间、信号、WiFi 和电池图标。
|
6
|
+
组件会自动更新时间显示,并支持根据设备大小进行缩放。
|
7
|
+
|
8
|
+
@usage
|
9
|
+
基本用法:
|
10
|
+
```vue
|
11
|
+
<StatusBarContent />
|
12
|
+
```
|
13
|
+
|
14
|
+
带缩放比例:
|
15
|
+
```vue
|
16
|
+
<StatusBarContent :scaleRatio="1.5" />
|
17
|
+
```
|
18
|
+
|
19
|
+
@props
|
20
|
+
@prop {Number} [scaleRatio=1] - 缩放比例,用于根据设备大小调整文字和图标大小
|
21
|
+
@slots
|
22
|
+
@emits
|
23
|
+
-->
|
24
|
+
<script lang="ts">
|
25
|
+
import { defineComponent, ref, onMounted, onUnmounted, computed } from 'vue';
|
26
|
+
import { IPhoneSignalIcon, IPhoneWifiIcon, IPhoneBatteryIcon } from '../icons';
|
27
|
+
import '../../style.ts';
|
28
|
+
|
29
|
+
export default defineComponent({
|
30
|
+
name: 'StatusBarContent',
|
31
|
+
components: {
|
32
|
+
IPhoneSignalIcon,
|
33
|
+
IPhoneWifiIcon,
|
34
|
+
IPhoneBatteryIcon,
|
35
|
+
},
|
36
|
+
props: {
|
37
|
+
scaleRatio: {
|
38
|
+
type: Number,
|
39
|
+
default: 1,
|
40
|
+
},
|
41
|
+
},
|
42
|
+
setup(props) {
|
43
|
+
const currentTime = ref('12:00');
|
44
|
+
|
45
|
+
// 更新时间的函数
|
46
|
+
const updateTime = () => {
|
47
|
+
const now = new Date();
|
48
|
+
const hours = now.getHours().toString().padStart(2, '0');
|
49
|
+
const minutes = now.getMinutes().toString().padStart(2, '0');
|
50
|
+
currentTime.value = `${hours}:${minutes}`;
|
51
|
+
};
|
52
|
+
|
53
|
+
// 计算缩放后的字体大小
|
54
|
+
const scaledFontSize = computed(() => {
|
55
|
+
const baseFontSize = 14; // 基础字体大小
|
56
|
+
return `${baseFontSize * props.scaleRatio}px`;
|
57
|
+
});
|
58
|
+
|
59
|
+
// 计算缩放后的图标尺寸
|
60
|
+
const scaledIconSize = computed(() => {
|
61
|
+
const baseIconSize = 15; // 基础图标宽度
|
62
|
+
return `${baseIconSize * props.scaleRatio}px`;
|
63
|
+
});
|
64
|
+
|
65
|
+
// 计算缩放后的图标高度百分比
|
66
|
+
const scaledIconHeight = computed(() => {
|
67
|
+
const baseHeight = 60; // 基础高度百分比
|
68
|
+
return `${baseHeight * props.scaleRatio}%`;
|
69
|
+
});
|
70
|
+
|
71
|
+
// 设置定时器更新时间
|
72
|
+
let timeInterval: number;
|
73
|
+
onMounted(() => {
|
74
|
+
updateTime();
|
75
|
+
timeInterval = window.setInterval(updateTime, 60000); // 每分钟更新一次
|
76
|
+
});
|
77
|
+
|
78
|
+
onUnmounted(() => {
|
79
|
+
if (timeInterval) {
|
80
|
+
clearInterval(timeInterval);
|
81
|
+
}
|
82
|
+
});
|
83
|
+
|
84
|
+
return {
|
85
|
+
currentTime,
|
86
|
+
scaledFontSize,
|
87
|
+
scaledIconSize,
|
88
|
+
scaledIconHeight,
|
89
|
+
};
|
90
|
+
},
|
91
|
+
});
|
92
|
+
</script>
|
93
|
+
|
94
|
+
<template>
|
95
|
+
<div class="cosy:flex cosy:items-center cosy:h-full cosy:justify-between">
|
96
|
+
<!-- 左侧时间 -->
|
97
|
+
<span class="cosy:font-medium time-text" :style="{ fontSize: scaledFontSize }">
|
98
|
+
{{ currentTime }}
|
99
|
+
</span>
|
100
|
+
|
101
|
+
<!-- 右侧状态图标 -->
|
102
|
+
<div class="cosy:flex cosy:flex-row cosy:items-center cosy:space-x-1 cosy:h-full">
|
103
|
+
<div :style="{ width: scaledIconSize, height: scaledIconHeight, minWidth: 0, minHeight: 0 }">
|
104
|
+
<IPhoneBatteryIcon />
|
105
|
+
</div>
|
106
|
+
</div>
|
107
|
+
</div>
|
108
|
+
</template>
|
109
|
+
|
110
|
+
<style scoped>
|
111
|
+
/* 确保图标渲染更平滑 */
|
112
|
+
svg {
|
113
|
+
shape-rendering: geometricPrecision;
|
114
|
+
}
|
115
|
+
|
116
|
+
/* 时间文字基础样式 */
|
117
|
+
.time-text {
|
118
|
+
line-height: 1;
|
119
|
+
transition: font-size 0.2s ease;
|
120
|
+
}
|
121
|
+
</style>
|