@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.
@@ -0,0 +1,63 @@
1
+ <template>
2
+ <li
3
+ class="cosy:mb-2 cosy:rounded-md cosy:bg-base-300 cosy:p-2 cosy:flex cosy:items-center cosy:gap-3 cosy:hover:bg-accent/10 cosy:relative cosy:overflow-hidden"
4
+ @click="$emit('click')"
5
+ >
6
+ <div v-if="loading">
7
+ <template v-if="duration">
8
+ <div
9
+ class="cosy:absolute cosy:left-0 cosy:top-0 cosy:h-full cosy:bg-accent/40 cosy:z-0 loading-bar"
10
+ :style="{ animationDuration: duration + 'ms' }"
11
+ ></div>
12
+ </template>
13
+ </div>
14
+ <div
15
+ class="cosy:relative cosy:z-10 cosy:w-full cosy:flex cosy:items-center cosy:gap-3"
16
+ >
17
+ <slot />
18
+
19
+ <!-- 后置 loading 图标 -->
20
+ <div
21
+ v-if="loading && !duration"
22
+ class="cosy:flex-shrink-0 cosy:ml-auto cosy:transform-none"
23
+ style="transform: none !important"
24
+ >
25
+ <div
26
+ class="cosy:loading cosy:loading-dots cosy:loading-sm cosy:text-accent"
27
+ ></div>
28
+ </div>
29
+ </div>
30
+ </li>
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ withDefaults(
35
+ defineProps<{
36
+ loading?: boolean;
37
+ duration?: number;
38
+ }>(),
39
+ {
40
+ loading: false,
41
+ duration: undefined,
42
+ }
43
+ );
44
+
45
+ defineEmits(['click']);
46
+ </script>
47
+
48
+ <style scoped>
49
+ /* 进度条动画 */
50
+ .loading-bar {
51
+ width: 0%;
52
+ height: 100%;
53
+ animation: loading-bar-anim linear forwards;
54
+ }
55
+ @keyframes loading-bar-anim {
56
+ 0% {
57
+ width: 0%;
58
+ }
59
+ 100% {
60
+ width: 100%;
61
+ }
62
+ }
63
+ </style>
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <li
3
+ :class="[
4
+ 'cosy:mb-2 cosy:rounded-md cosy:bg-base-300 cosy:p-2 cosy:flex cosy:items-center cosy:gap-3 cosy:hover:bg-accent/10 cosy:relative cosy:overflow-hidden',
5
+ loading && !duration ? 'pulse-anim' : '',
6
+ ]"
7
+ @click="$emit('click')"
8
+ >
9
+ <div v-if="loading">
10
+ <template v-if="duration">
11
+ <div
12
+ class="cosy:absolute cosy:left-0 cosy:top-0 cosy:h-full cosy:bg-accent/40 cosy:z-0 loading-bar"
13
+ :style="{ animationDuration: duration + 'ms' }"
14
+ ></div>
15
+ </template>
16
+ </div>
17
+ <div
18
+ class="cosy:relative cosy:z-10 cosy:w-full cosy:flex cosy:items-center cosy:gap-3"
19
+ >
20
+ <slot />
21
+ </div>
22
+ </li>
23
+ </template>
24
+
25
+ <script setup lang="ts">
26
+ withDefaults(
27
+ defineProps<{
28
+ loading?: boolean;
29
+ duration?: number;
30
+ }>(),
31
+ {
32
+ loading: false,
33
+ duration: undefined,
34
+ }
35
+ );
36
+
37
+ defineEmits(['click']);
38
+ </script>
39
+
40
+ <style scoped>
41
+ /* 整体脉冲动画 */
42
+ @keyframes pulse-scale {
43
+ 0%,
44
+ 100% {
45
+ transform: scale(1);
46
+ opacity: 1;
47
+ }
48
+ 50% {
49
+ transform: scale(1.01);
50
+ opacity: 0.9;
51
+ }
52
+ }
53
+ .pulse-anim {
54
+ animation: pulse-scale 1.5s ease-in-out infinite;
55
+ }
56
+
57
+ /* 进度条动画 */
58
+ .loading-bar {
59
+ width: 0%;
60
+ height: 100%;
61
+ animation: loading-bar-anim linear forwards;
62
+ }
63
+ @keyframes loading-bar-anim {
64
+ 0% {
65
+ width: 0%;
66
+ }
67
+ 100% {
68
+ width: 100%;
69
+ }
70
+ }
71
+ </style>
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <li
3
+ :class="[
4
+ 'cosy:mb-2 cosy:rounded-md cosy:bg-base-300 cosy:p-2 cosy:flex cosy:items-center cosy:gap-3 cosy:hover:bg-accent/10 cosy:relative cosy:overflow-hidden',
5
+ loading && !duration
6
+ ? 'cosy:ring-2 cosy:ring-accent ring-pulse-anim'
7
+ : '',
8
+ ]"
9
+ @click="$emit('click')"
10
+ >
11
+ <div v-if="loading">
12
+ <template v-if="duration">
13
+ <div
14
+ class="cosy:absolute cosy:left-0 cosy:top-0 cosy:h-full cosy:bg-accent/40 cosy:z-0 loading-bar"
15
+ :style="{ animationDuration: duration + 'ms' }"
16
+ ></div>
17
+ </template>
18
+ </div>
19
+ <div
20
+ class="cosy:relative cosy:z-10 cosy:w-full cosy:flex cosy:items-center cosy:gap-3"
21
+ >
22
+ <slot />
23
+ </div>
24
+ </li>
25
+ </template>
26
+
27
+ <script setup lang="ts">
28
+ withDefaults(
29
+ defineProps<{
30
+ loading?: boolean;
31
+ duration?: number;
32
+ }>(),
33
+ {
34
+ loading: false,
35
+ duration: undefined,
36
+ }
37
+ );
38
+
39
+ defineEmits(['click']);
40
+ </script>
41
+
42
+ <style scoped>
43
+ /* Ring 外环脉冲动画 */
44
+ @keyframes ring-pulse {
45
+ 0%,
46
+ 100% {
47
+ transform: scale(1);
48
+ }
49
+ 50% {
50
+ transform: scale(1.02);
51
+ }
52
+ }
53
+ .ring-pulse-anim {
54
+ animation: ring-pulse 1.5s ease-in-out infinite;
55
+ }
56
+
57
+ /* 进度条动画 */
58
+ .loading-bar {
59
+ width: 0%;
60
+ height: 100%;
61
+ animation: loading-bar-anim linear forwards;
62
+ }
63
+ @keyframes loading-bar-anim {
64
+ 0% {
65
+ width: 0%;
66
+ }
67
+ 100% {
68
+ width: 100%;
69
+ }
70
+ }
71
+ </style>
@@ -95,168 +95,189 @@ const activeTab = ref('外观');
95
95
  -->
96
96
 
97
97
  <script lang="ts">
98
- import '../../style.ts';
98
+ import '../../style';
99
99
  import AlertDialog from '../alert-dialog/AlertDialog.vue';
100
100
  import { ref, defineComponent, type PropType } from 'vue';
101
101
 
102
102
  export default defineComponent({
103
- name: 'MacWindow',
104
- components: {
105
- AlertDialog,
103
+ name: 'MacWindow',
104
+ components: {
105
+ AlertDialog,
106
+ },
107
+ props: {
108
+ height: {
109
+ type: String,
110
+ default: 'h-96',
106
111
  },
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
- },
112
+ title: {
113
+ type: String,
114
+ default: '',
144
115
  },
145
- setup(props) {
146
- const showAlertDialog = ref(false);
147
- const alertMessage = ref('');
148
- const activeTab = ref(props.defaultTab);
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
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
- }
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
157
 
158
- const handleCloseWindow = () => {
159
- alertMessage.value = '关闭APP窗口(这是演示,不会真实操作)';
160
- showAlertDialog.value = true;
161
- if (props.onCloseWindow) {
162
- props.onCloseWindow();
163
- }
164
- };
158
+ const handleCloseWindow = () => {
159
+ alertMessage.value = '关闭APP窗口(这是演示,不会真实操作)';
160
+ showAlertDialog.value = true;
161
+ if (props.onCloseWindow) {
162
+ props.onCloseWindow();
163
+ }
164
+ };
165
165
 
166
- const handleMinimizeWindow = () => {
167
- alertMessage.value = '最小化窗口(这是演示,不会真实操作)';
168
- showAlertDialog.value = true;
169
- if (props.onMinimizeWindow) {
170
- props.onMinimizeWindow();
171
- }
172
- };
166
+ const handleMinimizeWindow = () => {
167
+ alertMessage.value = '最小化窗口(这是演示,不会真实操作)';
168
+ showAlertDialog.value = true;
169
+ if (props.onMinimizeWindow) {
170
+ props.onMinimizeWindow();
171
+ }
172
+ };
173
173
 
174
- const handleMaximizeWindow = () => {
175
- alertMessage.value = '最大化窗口(这是演示,不会真实操作)';
176
- showAlertDialog.value = true;
177
- if (props.onMaximizeWindow) {
178
- props.onMaximizeWindow();
179
- }
180
- };
174
+ const handleMaximizeWindow = () => {
175
+ alertMessage.value = '最大化窗口(这是演示,不会真实操作)';
176
+ showAlertDialog.value = true;
177
+ if (props.onMaximizeWindow) {
178
+ props.onMaximizeWindow();
179
+ }
180
+ };
181
181
 
182
- const handleTabClick = (tab: string) => {
183
- activeTab.value = tab;
184
- if (props.onTabClick) {
185
- props.onTabClick(tab);
186
- }
187
- };
182
+ const handleTabClick = (tab: string) => {
183
+ activeTab.value = tab;
184
+ if (props.onTabClick) {
185
+ props.onTabClick(tab);
186
+ }
187
+ };
188
188
 
189
- return {
190
- showAlertDialog,
191
- alertMessage,
192
- activeTab,
193
- handleCloseWindow,
194
- handleMinimizeWindow,
195
- handleMaximizeWindow,
196
- handleTabClick,
197
- };
198
- },
189
+ return {
190
+ showAlertDialog,
191
+ alertMessage,
192
+ activeTab,
193
+ handleCloseWindow,
194
+ handleMinimizeWindow,
195
+ handleMaximizeWindow,
196
+ handleTabClick,
197
+ };
198
+ },
199
199
  });
200
200
  </script>
201
201
 
202
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
- <!-- 窗口控制按钮 -->
203
+ <div
204
+ class="cosy:flex cosy:max-w-5xl cosy:mx-auto cosy:bg-base-100 cosy:relative cosy:rounded-2xl cosy:overflow-hidden"
205
+ :class="[height, withShadow ? 'cosy:shadow-lg' : '']"
206
+ >
207
+ <!-- 窗口控制按钮 -->
208
+ <div
209
+ 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"
210
+ >
211
+ <div class="cosy:flex cosy:items-center cosy:space-x-2">
206
212
  <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>
213
+ class="cosy:w-3 cosy:h-3 cosy:rounded-full cosy:bg-error cosy:cursor-pointer hover:cosy:opacity-80 cosy:transition-opacity"
214
+ @click="handleCloseWindow"
215
+ />
216
+ <div
217
+ class="cosy:w-3 cosy:h-3 cosy:rounded-full cosy:bg-warning cosy:cursor-pointer hover:cosy:opacity-80 cosy:transition-opacity"
218
+ @click="handleMinimizeWindow"
219
+ />
220
+ <div
221
+ class="cosy:w-3 cosy:h-3 cosy:rounded-full cosy:bg-success cosy:cursor-pointer hover:cosy:opacity-80 cosy:transition-opacity"
222
+ @click="handleMaximizeWindow"
223
+ />
224
+ </div>
225
+ <div
226
+ class="cosy:ml-6 cosy:text-sm cosy:font-medium cosy:text-base-content"
227
+ >
228
+ {{ title }}
229
+ </div>
233
230
 
234
- <!-- 工具栏插槽 -->
235
- <div class="cosy:ml-auto cosy:flex cosy:items-center cosy:space-x-2">
236
- <slot name="toolbar"></slot>
237
- </div>
231
+ <!-- 标签选择器 -->
232
+ <div
233
+ v-if="tabs?.length"
234
+ class="cosy:flex-1 cosy:flex cosy:justify-center"
235
+ >
236
+ <div class="cosy:inline-flex cosy:rounded-lg cosy:bg-base-300 cosy:p-1">
237
+ <button
238
+ v-for="(tab, index) in tabs"
239
+ :key="index"
240
+ :class="[
241
+ 'cosy:px-3 cosy:py-1 cosy:text-sm cosy:rounded-md cosy:transition-colors',
242
+ activeTab === tab
243
+ ? 'cosy:bg-base-100 cosy:text-base-content cosy:shadow'
244
+ : 'cosy:text-base-content/70 hover:cosy:text-base-content',
245
+ ]"
246
+ @click="handleTabClick(tab)"
247
+ >
248
+ {{ tab }}
249
+ </button>
238
250
  </div>
251
+ </div>
252
+
253
+ <!-- 工具栏插槽 -->
254
+ <div class="cosy:ml-auto cosy:flex cosy:items-center cosy:space-x-2">
255
+ <slot name="toolbar"></slot>
256
+ </div>
257
+ </div>
239
258
 
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" />
259
+ <!-- 主要内容区域 -->
260
+ <div class="cosy:flex-1 cosy:flex cosy:flex-col cosy:pt-12 cosy:h-full">
261
+ <div class="cosy:flex cosy:flex-1 cosy:h-full cosy:overflow-hidden">
262
+ <!-- 左侧栏插槽 -->
263
+ <slot name="sidebar" />
245
264
 
246
- <!-- 主内容插槽 -->
247
- <slot />
248
- </div>
265
+ <!-- 主内容插槽 -->
266
+ <slot />
267
+ </div>
249
268
 
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>
269
+ <!-- 底部状态栏 -->
270
+ <div
271
+ v-if="$slots.status"
272
+ 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"
273
+ >
274
+ <div class="cosy:flex cosy:items-center cosy:space-x-2">
275
+ <slot name="status"></slot>
257
276
  </div>
277
+ </div>
258
278
  </div>
279
+ </div>
259
280
 
260
- <!-- AlertDialog 组件 -->
261
- <AlertDialog v-model="showAlertDialog" :message="alertMessage" />
281
+ <!-- AlertDialog 组件 -->
282
+ <AlertDialog v-model="showAlertDialog" :message="alertMessage" />
262
283
  </template>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffic/cosy-ui",
3
- "version": "0.8.24",
3
+ "version": "0.8.26",
4
4
  "description": "An astro component library",
5
5
  "author": {
6
6
  "name": "nookery",