@coffic/cosy-ui 0.8.24 → 0.8.26
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/src-astro/alert/Alert.astro +45 -5
- package/dist/src-astro/list/ListItem.astro +64 -38
- package/dist/src-astro/list/ListItemBreath.astro +60 -0
- package/dist/src-astro/list/ListItemGlow.astro +65 -0
- package/dist/src-astro/list/ListItemIconLeft.astro +53 -0
- package/dist/src-astro/list/ListItemIconRight.astro +53 -0
- package/dist/src-astro/list/ListItemPulse.astro +61 -0
- package/dist/src-astro/list/ListItemRing.astro +59 -0
- package/dist/src-astro/list/index.ts +7 -1
- package/dist/src-vue/alert/Alert.vue +66 -40
- package/dist/src-vue/alert-dialog/Multilang.vue +1 -1
- package/dist/src-vue/buttons/Button.vue +20 -14
- package/dist/src-vue/container/Container.vue +1 -1
- package/dist/src-vue/iPhone/StatusBarContent.vue +88 -76
- package/dist/src-vue/iPhone/iPhoneWindow.vue +149 -129
- package/dist/src-vue/list/ListItem.vue +77 -32
- package/dist/src-vue/list/ListItemBreath.vue +70 -0
- package/dist/src-vue/list/ListItemGlow.vue +75 -0
- package/dist/src-vue/list/ListItemIconLeft.vue +63 -0
- package/dist/src-vue/list/ListItemIconRight.vue +63 -0
- package/dist/src-vue/list/ListItemPulse.vue +71 -0
- package/dist/src-vue/list/ListItemRing.vue +71 -0
- package/dist/src-vue/mac-window/MacWindow.vue +160 -139
- package/package.json +1 -1
@@ -26,75 +26,101 @@ Alert 组件用于向用户显示重要的提示信息,支持多种类型的
|
|
26
26
|
</Alert>
|
27
27
|
```
|
28
28
|
|
29
|
+
自定义操作按钮:
|
30
|
+
```vue
|
31
|
+
<Alert type="info">
|
32
|
+
这是带自定义操作的提示
|
33
|
+
<template #action>
|
34
|
+
<button @click="doSomething">操作</button>
|
35
|
+
</template>
|
36
|
+
</Alert>
|
37
|
+
```
|
38
|
+
|
29
39
|
@props
|
30
40
|
@prop {('info'|'success'|'warning'|'error')} [type='info'] - 提示类型,影响颜色和图标
|
31
41
|
@prop {string} [title] - 提示标题,可选
|
32
42
|
@prop {string} [class] - 自定义 CSS 类名
|
43
|
+
@prop {boolean} [closable] - 是否可关闭,默认可关闭
|
33
44
|
|
34
45
|
@slots
|
35
46
|
@slot default - 提示内容
|
47
|
+
@slot action - 自定义操作按钮,显示在 alert 右侧
|
36
48
|
-->
|
37
49
|
|
38
50
|
<script setup lang="ts">
|
39
|
-
import '../../style
|
51
|
+
import '../../style';
|
40
52
|
import { computed } from 'vue';
|
41
53
|
import { InfoIcon, SuccessIcon, WarningIcon, ErrorIcon } from '../icons/index';
|
54
|
+
import { RiCloseLine } from '@remixicon/vue';
|
42
55
|
|
43
56
|
interface Props {
|
44
|
-
|
45
|
-
|
46
|
-
|
57
|
+
type?: 'info' | 'success' | 'warning' | 'error';
|
58
|
+
title?: string;
|
59
|
+
class?: string;
|
60
|
+
closable?: boolean;
|
47
61
|
}
|
48
62
|
|
49
63
|
const props = withDefaults(defineProps<Props>(), {
|
50
|
-
|
51
|
-
|
52
|
-
|
64
|
+
type: 'info',
|
65
|
+
title: '',
|
66
|
+
class: '',
|
67
|
+
closable: true,
|
53
68
|
});
|
54
69
|
|
70
|
+
const emit = defineEmits(['close']);
|
71
|
+
|
72
|
+
const handleClose = () => {
|
73
|
+
emit('close');
|
74
|
+
};
|
75
|
+
|
55
76
|
// 根据类型设置样式
|
56
77
|
const alertClass = computed(() => {
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
78
|
+
const alertClasses = {
|
79
|
+
info: 'cosy:alert-info',
|
80
|
+
success: 'cosy:alert-success',
|
81
|
+
warning: 'cosy:alert-warning',
|
82
|
+
error: 'cosy:alert-error',
|
83
|
+
};
|
84
|
+
return alertClasses[props.type];
|
64
85
|
});
|
65
86
|
|
66
87
|
// 根据类型设置图标组件
|
67
88
|
const IconComponent = computed(() => {
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
89
|
+
const iconComponents = {
|
90
|
+
info: InfoIcon,
|
91
|
+
success: SuccessIcon,
|
92
|
+
warning: WarningIcon,
|
93
|
+
error: ErrorIcon,
|
94
|
+
};
|
95
|
+
return iconComponents[props.type];
|
75
96
|
});
|
76
97
|
</script>
|
77
98
|
|
78
99
|
<template>
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
100
|
+
<div :class="['cosy:alert cosy:w-full cosy:flex', alertClass, props.class]" role="alert">
|
101
|
+
<div class="cosy:flex cosy:flex-row cosy:items-center cosy:gap-4 cosy:justify-between cosy:w-full">
|
102
|
+
<div class="cosy:flex cosy:items-center cosy:gap-4">
|
103
|
+
<component :is="IconComponent" class="cosy:btn cosy:btn-sm cosy:btn-ghost cosy:btn-circle" />
|
104
|
+
|
105
|
+
<div class="cosy:flex cosy:flex-col cosy:items-start cosy:h-full cosy:flex-1">
|
106
|
+
<h3 v-if="props.title" class="cosy:font-bold" style="margin-top: 0 !important">
|
107
|
+
{{ props.title }}
|
108
|
+
</h3>
|
109
|
+
<div v-if="props.title" class="cosy:text-xs">
|
110
|
+
<slot />
|
111
|
+
</div>
|
112
|
+
<slot v-else />
|
113
|
+
</div>
|
114
|
+
</div>
|
115
|
+
|
116
|
+
<div class="cosy:flex cosy:flex-row cosy:items-center cosy:gap-2" data-role="actions">
|
117
|
+
<slot name="action" />
|
118
|
+
|
119
|
+
<button v-if="props.closable" @click="handleClose"
|
120
|
+
class="cosy:btn cosy:btn-ghost cosy:btn-sm cosy:btn-circle">
|
121
|
+
<RiCloseLine class="cosy:h-5 cosy:w-5" />
|
122
|
+
</button>
|
123
|
+
</div>
|
95
124
|
</div>
|
96
|
-
<slot v-else />
|
97
|
-
</div>
|
98
125
|
</div>
|
99
|
-
</div>
|
100
126
|
</template>
|
@@ -1,20 +1,20 @@
|
|
1
1
|
<script setup lang="ts">
|
2
2
|
import { computed } from 'vue';
|
3
|
-
import '../../style
|
3
|
+
import '../../style';
|
4
4
|
|
5
5
|
interface Props {
|
6
6
|
variant?:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
| 'primary'
|
8
|
+
| 'secondary'
|
9
|
+
| 'accent'
|
10
|
+
| 'info'
|
11
|
+
| 'success'
|
12
|
+
| 'warning'
|
13
|
+
| 'error'
|
14
|
+
| 'ghost'
|
15
|
+
| 'link'
|
16
|
+
| 'outline'
|
17
|
+
| 'neutral';
|
18
18
|
size?: 'lg' | 'md' | 'sm' | 'xs';
|
19
19
|
shape?: 'circle' | 'square';
|
20
20
|
wide?: boolean;
|
@@ -89,8 +89,14 @@ const buttonClasses = computed(() => {
|
|
89
89
|
</script>
|
90
90
|
|
91
91
|
<template>
|
92
|
-
<component
|
93
|
-
:
|
92
|
+
<component
|
93
|
+
:is="props.href ? 'a' : 'button'"
|
94
|
+
:class="buttonClasses"
|
95
|
+
:type="props.href ? undefined : props.type"
|
96
|
+
:disabled="props.disabled"
|
97
|
+
:href="props.href"
|
98
|
+
:target="props.target"
|
99
|
+
>
|
94
100
|
<span class="cosy:flex cosy:items-center cosy:gap-2">
|
95
101
|
<slot name="icon-left" />
|
96
102
|
<slot />
|
@@ -24,98 +24,110 @@ StatusBarContent 组件显示 iPhone 状态栏的内容,包括时间、信号
|
|
24
24
|
<script lang="ts">
|
25
25
|
import { defineComponent, ref, onMounted, onUnmounted, computed } from 'vue';
|
26
26
|
import { IPhoneSignalIcon, IPhoneWifiIcon, IPhoneBatteryIcon } from '../icons';
|
27
|
-
import '../../style
|
27
|
+
import '../../style';
|
28
28
|
|
29
29
|
export default defineComponent({
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
};
|
30
|
+
name: 'StatusBarContent',
|
31
|
+
components: {
|
32
|
+
IPhoneSignalIcon,
|
33
|
+
IPhoneWifiIcon,
|
34
|
+
IPhoneBatteryIcon,
|
35
|
+
},
|
36
|
+
props: {
|
37
|
+
scaleRatio: {
|
38
|
+
type: Number,
|
39
|
+
default: 1,
|
90
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
91
|
});
|
92
92
|
</script>
|
93
93
|
|
94
94
|
<template>
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
95
|
+
<div class="cosy:flex cosy:items-center cosy:h-full cosy:justify-between">
|
96
|
+
<!-- 左侧时间 -->
|
97
|
+
<span
|
98
|
+
class="cosy:font-medium time-text"
|
99
|
+
:style="{ fontSize: scaledFontSize }"
|
100
|
+
>
|
101
|
+
{{ currentTime }}
|
102
|
+
</span>
|
103
|
+
|
104
|
+
<!-- 右侧状态图标 -->
|
105
|
+
<div
|
106
|
+
class="cosy:flex cosy:flex-row cosy:items-center cosy:space-x-1 cosy:h-full"
|
107
|
+
>
|
108
|
+
<div
|
109
|
+
:style="{
|
110
|
+
width: scaledIconSize,
|
111
|
+
height: scaledIconHeight,
|
112
|
+
minWidth: 0,
|
113
|
+
minHeight: 0,
|
114
|
+
}"
|
115
|
+
>
|
116
|
+
<IPhoneBatteryIcon />
|
117
|
+
</div>
|
107
118
|
</div>
|
119
|
+
</div>
|
108
120
|
</template>
|
109
121
|
|
110
122
|
<style scoped>
|
111
123
|
/* 确保图标渲染更平滑 */
|
112
124
|
svg {
|
113
|
-
|
125
|
+
shape-rendering: geometricPrecision;
|
114
126
|
}
|
115
127
|
|
116
128
|
/* 时间文字基础样式 */
|
117
129
|
.time-text {
|
118
|
-
|
119
|
-
|
130
|
+
line-height: 1;
|
131
|
+
transition: font-size 0.2s ease;
|
120
132
|
}
|
121
133
|
</style>
|