@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.
@@ -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.ts';
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
- type?: 'info' | 'success' | 'warning' | 'error';
45
- title?: string;
46
- class?: string;
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
- type: 'info',
51
- title: '',
52
- class: '',
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
- 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];
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
- const iconComponents = {
69
- info: InfoIcon,
70
- success: SuccessIcon,
71
- warning: WarningIcon,
72
- error: ErrorIcon,
73
- };
74
- return iconComponents[props.type];
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
- <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 />
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>
@@ -11,7 +11,7 @@ AlertDialog 组件的多语言示例,展示如何使用不同语言的对话
11
11
  -->
12
12
 
13
13
  <script lang="ts">
14
- import '../../app.css';
14
+ import '../../style';
15
15
  import { ref, defineComponent } from 'vue';
16
16
  import AlertDialog from './AlertDialog.vue';
17
17
 
@@ -1,20 +1,20 @@
1
1
  <script setup lang="ts">
2
2
  import { computed } from 'vue';
3
- import '../../style.ts';
3
+ import '../../style';
4
4
 
5
5
  interface Props {
6
6
  variant?:
7
- | 'primary'
8
- | 'secondary'
9
- | 'accent'
10
- | 'info'
11
- | 'success'
12
- | 'warning'
13
- | 'error'
14
- | 'ghost'
15
- | 'link'
16
- | 'outline'
17
- | 'neutral';
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 :is="props.href ? 'a' : 'button'" :class="buttonClasses" :type="props.href ? undefined : props.type"
93
- :disabled="props.disabled" :href="props.href" :target="props.target">
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 />
@@ -77,7 +77,7 @@ Flex布局容器(按列排列):
77
77
  -->
78
78
 
79
79
  <script setup lang="ts">
80
- import '../../style.ts';
80
+ import '../../style';
81
81
  import { computed } from 'vue';
82
82
 
83
83
  interface Props {
@@ -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.ts';
27
+ import '../../style';
28
28
 
29
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
- };
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
- <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>
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
- shape-rendering: geometricPrecision;
125
+ shape-rendering: geometricPrecision;
114
126
  }
115
127
 
116
128
  /* 时间文字基础样式 */
117
129
  .time-text {
118
- line-height: 1;
119
- transition: font-size 0.2s ease;
130
+ line-height: 1;
131
+ transition: font-size 0.2s ease;
120
132
  }
121
133
  </style>