hy-app 0.4.11 → 0.4.13
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/components/hy-card/hy-card.vue +55 -27
- package/components/hy-card/index.scss +14 -6
- package/components/hy-flex/hy-flex.vue +3 -6
- package/components/hy-folding-panel/hy-folding-panel.vue +345 -111
- package/components/hy-folding-panel-item/hy-folding-panel-item.vue +228 -0
- package/components/hy-watermark/hy-watermark.vue +7 -3
- package/package.json +2 -2
- package/web-types.json +1 -1
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="hy-folding-panel-item">
|
|
3
|
+
<HyCell
|
|
4
|
+
:title="title"
|
|
5
|
+
:value="value"
|
|
6
|
+
:icon="icon"
|
|
7
|
+
:border="border"
|
|
8
|
+
:size="size"
|
|
9
|
+
:disabled="disabled"
|
|
10
|
+
:clickable="!disabled"
|
|
11
|
+
@click="handleClick"
|
|
12
|
+
>
|
|
13
|
+
<template #icon="{ icon }">
|
|
14
|
+
<slot name="icon" :icon="icon"></slot>
|
|
15
|
+
</template>
|
|
16
|
+
<template #title="{ title }">
|
|
17
|
+
<slot name="title" :title="title">{{ title }}</slot>
|
|
18
|
+
</template>
|
|
19
|
+
<template #value="{ value }">
|
|
20
|
+
<slot name="value" :value="value">
|
|
21
|
+
<text v-if="value">{{ value }}</text>
|
|
22
|
+
<text v-else class="hy-folding-panel-item__arrow" :class="{ 'hy-folding-panel-item__arrow--up': spread }">
|
|
23
|
+
{{ spread ? '↑' : '↓' }}
|
|
24
|
+
</text>
|
|
25
|
+
</slot>
|
|
26
|
+
</template>
|
|
27
|
+
<template #bottom>
|
|
28
|
+
<transition name="hy-folding-panel-item__transition">
|
|
29
|
+
<view
|
|
30
|
+
v-show="spread"
|
|
31
|
+
class="hy-folding-panel-item__content"
|
|
32
|
+
:style="[
|
|
33
|
+
customStyle,
|
|
34
|
+
{ height: contentHeight }
|
|
35
|
+
]"
|
|
36
|
+
>
|
|
37
|
+
<slot />
|
|
38
|
+
</view>
|
|
39
|
+
</transition>
|
|
40
|
+
<HyLine v-if="spread && showBottomLine" />
|
|
41
|
+
</template>
|
|
42
|
+
</HyCell>
|
|
43
|
+
</view>
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<script lang="ts">
|
|
47
|
+
export default {
|
|
48
|
+
name: "hy-folding-panel-item",
|
|
49
|
+
options: {
|
|
50
|
+
addGlobalClass: true,
|
|
51
|
+
virtualHost: true,
|
|
52
|
+
styleIsolation: "shared",
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<script setup lang="ts">
|
|
58
|
+
import { ref, computed, watch, onMounted, inject } from "vue";
|
|
59
|
+
import type { CSSProperties } from "vue";
|
|
60
|
+
import { addUnit } from "../../libs";
|
|
61
|
+
import HyCell from "../hy-cell/hy-cell.vue";
|
|
62
|
+
import HyLine from "../hy-line/hy-line.vue";
|
|
63
|
+
|
|
64
|
+
interface IProps {
|
|
65
|
+
/** 标题 */
|
|
66
|
+
title?: string;
|
|
67
|
+
/** 标题左侧的图标 */
|
|
68
|
+
icon?: string;
|
|
69
|
+
/** 右侧的值 */
|
|
70
|
+
value?: string;
|
|
71
|
+
/** 是否显示下边框 */
|
|
72
|
+
border?: boolean;
|
|
73
|
+
/** 单元的大小 */
|
|
74
|
+
size?: "large" | "medium" | "small";
|
|
75
|
+
/** 是否禁用 */
|
|
76
|
+
disabled?: boolean;
|
|
77
|
+
/** 内容面板高度 */
|
|
78
|
+
contentHeight?: string | number;
|
|
79
|
+
/** 是否默认展开 */
|
|
80
|
+
defaultOpen?: boolean;
|
|
81
|
+
/** 是否显示底部线条 */
|
|
82
|
+
showBottomLine?: boolean;
|
|
83
|
+
/** 定义需要用到的外部样式 */
|
|
84
|
+
customStyle?: CSSProperties;
|
|
85
|
+
/** 面板索引(由父组件提供) */
|
|
86
|
+
index?: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const props = withDefaults(defineProps<IProps>(), {
|
|
90
|
+
title: "",
|
|
91
|
+
icon: "",
|
|
92
|
+
value: "",
|
|
93
|
+
border: true,
|
|
94
|
+
size: "medium",
|
|
95
|
+
disabled: false,
|
|
96
|
+
contentHeight: 120,
|
|
97
|
+
defaultOpen: false,
|
|
98
|
+
showBottomLine: true,
|
|
99
|
+
customStyle: () => ({}),
|
|
100
|
+
index: -1,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const emit = defineEmits<{
|
|
104
|
+
(e: "click", value: boolean): void;
|
|
105
|
+
(e: "open"): void;
|
|
106
|
+
(e: "close"): void;
|
|
107
|
+
// 用于手风琴模式的特殊事件
|
|
108
|
+
(e: "child-click", index: number, isOpen: boolean): void;
|
|
109
|
+
}>();
|
|
110
|
+
|
|
111
|
+
// 尝试从父组件注入手风琴模式配置
|
|
112
|
+
const accordion = inject<boolean>('hy-folding-panel-accordion', false);
|
|
113
|
+
|
|
114
|
+
const spread = ref(props.defaultOpen);
|
|
115
|
+
const contentHeight = computed(() => {
|
|
116
|
+
return typeof props.contentHeight === 'number'
|
|
117
|
+
? `${props.contentHeight}px`
|
|
118
|
+
: props.contentHeight;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// 监听默认展开状态
|
|
122
|
+
watch(
|
|
123
|
+
() => props.defaultOpen,
|
|
124
|
+
(newValue) => {
|
|
125
|
+
spread.value = newValue;
|
|
126
|
+
},
|
|
127
|
+
{ immediate: true }
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// 处理点击事件
|
|
131
|
+
const handleClick = () => {
|
|
132
|
+
if (props.disabled) return;
|
|
133
|
+
|
|
134
|
+
spread.value = !spread.value;
|
|
135
|
+
emit("click", spread.value);
|
|
136
|
+
|
|
137
|
+
// 向父组件通知子组件点击事件(用于手风琴模式)
|
|
138
|
+
if (props.index >= 0) {
|
|
139
|
+
emit('child-click', props.index, spread.value);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (spread.value) {
|
|
143
|
+
emit("open");
|
|
144
|
+
} else {
|
|
145
|
+
emit("close");
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// 提供给父组件控制展开/收起的方法
|
|
150
|
+
defineExpose({
|
|
151
|
+
open: () => {
|
|
152
|
+
if (!props.disabled && !spread.value) {
|
|
153
|
+
spread.value = true;
|
|
154
|
+
emit("click", true);
|
|
155
|
+
emit("open");
|
|
156
|
+
|
|
157
|
+
// 通知父组件
|
|
158
|
+
if (props.index >= 0) {
|
|
159
|
+
emit('child-click', props.index, true);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
close: () => {
|
|
164
|
+
if (!props.disabled && spread.value) {
|
|
165
|
+
spread.value = false;
|
|
166
|
+
emit("click", false);
|
|
167
|
+
emit("close");
|
|
168
|
+
|
|
169
|
+
// 通知父组件
|
|
170
|
+
if (props.index >= 0) {
|
|
171
|
+
emit('child-click', props.index, false);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
toggle: () => {
|
|
176
|
+
handleClick();
|
|
177
|
+
},
|
|
178
|
+
getSpread: () => spread.value,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// 组件挂载时,如果是手风琴模式且默认打开,通知父组件
|
|
182
|
+
onMounted(() => {
|
|
183
|
+
if (spread.value && accordion && props.index >= 0) {
|
|
184
|
+
emit('child-click', props.index, true);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
</script>
|
|
188
|
+
|
|
189
|
+
<style lang="scss" scoped>
|
|
190
|
+
@import "./index.scss";
|
|
191
|
+
|
|
192
|
+
.hy-folding-panel-item {
|
|
193
|
+
&__arrow {
|
|
194
|
+
font-size: 16px;
|
|
195
|
+
color: #999;
|
|
196
|
+
transition: transform 0.3s;
|
|
197
|
+
|
|
198
|
+
&--up {
|
|
199
|
+
transform: rotate(0deg);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
&__content {
|
|
204
|
+
padding: 12px 16px;
|
|
205
|
+
box-sizing: border-box;
|
|
206
|
+
overflow: hidden;
|
|
207
|
+
background-color: #f8f8f8;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
&__transition-enter-active,
|
|
211
|
+
&__transition-leave-active {
|
|
212
|
+
transition: all 0.3s ease;
|
|
213
|
+
overflow: hidden;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
&__transition-enter-from,
|
|
217
|
+
&__transition-leave-to {
|
|
218
|
+
opacity: 0;
|
|
219
|
+
max-height: 0;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
&__transition-enter-to,
|
|
223
|
+
&__transition-leave-from {
|
|
224
|
+
opacity: 1;
|
|
225
|
+
max-height: 1000px; /* 足够大的值,确保内容能完全展开 */
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
</style>
|
|
@@ -220,6 +220,7 @@ function doInit() {
|
|
|
220
220
|
image,
|
|
221
221
|
imageHeight,
|
|
222
222
|
imageWidth,
|
|
223
|
+
title
|
|
223
224
|
} = props;
|
|
224
225
|
|
|
225
226
|
// 创建水印
|
|
@@ -238,6 +239,7 @@ function doInit() {
|
|
|
238
239
|
image,
|
|
239
240
|
imageHeight,
|
|
240
241
|
imageWidth,
|
|
242
|
+
title
|
|
241
243
|
);
|
|
242
244
|
}
|
|
243
245
|
|
|
@@ -257,6 +259,7 @@ function doInit() {
|
|
|
257
259
|
* @param image canvas图片
|
|
258
260
|
* @param imageHeight canvas图片高度
|
|
259
261
|
* @param imageWidth canvas图片宽度
|
|
262
|
+
* @param title 标题
|
|
260
263
|
*/
|
|
261
264
|
function createWaterMark(
|
|
262
265
|
width: number,
|
|
@@ -273,6 +276,7 @@ function createWaterMark(
|
|
|
273
276
|
image: string,
|
|
274
277
|
imageHeight: number,
|
|
275
278
|
imageWidth: number,
|
|
279
|
+
title: string,
|
|
276
280
|
) {
|
|
277
281
|
const canvasHeight = (height + gutterY) * pixelRatio.value;
|
|
278
282
|
const canvasWidth = (width + gutterX) * pixelRatio.value;
|
|
@@ -299,7 +303,7 @@ function createWaterMark(
|
|
|
299
303
|
image,
|
|
300
304
|
imageHeight,
|
|
301
305
|
imageWidth,
|
|
302
|
-
|
|
306
|
+
title,
|
|
303
307
|
titleFontSize
|
|
304
308
|
);
|
|
305
309
|
} else {
|
|
@@ -313,7 +317,7 @@ function createWaterMark(
|
|
|
313
317
|
image,
|
|
314
318
|
imageHeight,
|
|
315
319
|
imageWidth,
|
|
316
|
-
|
|
320
|
+
title,
|
|
317
321
|
titleFontSize
|
|
318
322
|
);
|
|
319
323
|
}
|
|
@@ -334,7 +338,7 @@ function createWaterMark(
|
|
|
334
338
|
image,
|
|
335
339
|
imageHeight,
|
|
336
340
|
imageWidth,
|
|
337
|
-
|
|
341
|
+
title,
|
|
338
342
|
titleFontSize
|
|
339
343
|
);
|
|
340
344
|
// #endif
|