officialblock 1.0.6 → 1.0.8

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.
Files changed (73) hide show
  1. package/dist/index-Ch_ldWmA.js +1 -0
  2. package/dist/index-DXm2cqxo.mjs +485 -0
  3. package/dist/official-block.cjs.js +74 -74
  4. package/dist/official-block.es.js +13577 -10832
  5. package/dist/official-block.umd.js +78 -78
  6. package/dist/style.css +1 -1
  7. package/dist/swiper-JiLDDxAF.js +1 -0
  8. package/dist/swiper-acbnDJoL.mjs +2035 -0
  9. package/dist/utils-DD-vVZej.mjs +316 -0
  10. package/dist/utils-DOLLD0-F.js +1 -0
  11. package/package.json +2 -1
  12. package/src/components/ArticleList/article.vue +3 -3
  13. package/src/components/ArticleList/contact.vue +9 -9
  14. package/src/components/ArticleList/index.ts +1 -1
  15. package/src/components/ArticleList/index.vue +24 -82
  16. package/src/components/ArticleList/setting.vue +61 -71
  17. package/src/components/ArticleList/type.ts +12 -18
  18. package/src/components/BannerImage/index.ts +11 -0
  19. package/src/components/BannerImage/index.vue +153 -0
  20. package/src/components/BannerImage/setting.vue +55 -0
  21. package/src/components/BannerImage/type.ts +10 -0
  22. package/src/components/BannerPage/index.ts +11 -0
  23. package/src/components/BannerPage/index.vue +283 -0
  24. package/src/components/BannerPage/setting.vue +55 -0
  25. package/src/components/BannerPage/type.ts +10 -0
  26. package/src/components/BtnList/index.ts +11 -0
  27. package/src/components/BtnList/index.vue +588 -0
  28. package/src/components/BtnList/setting.vue +255 -0
  29. package/src/components/BtnList/type.ts +10 -0
  30. package/src/components/Button/index.vue +45 -33
  31. package/src/components/CustomSpace/index.ts +11 -0
  32. package/src/components/CustomSpace/index.vue +82 -0
  33. package/src/components/CustomSpace/setting.vue +89 -0
  34. package/src/components/CustomSpace/type.ts +10 -0
  35. package/src/components/GalleryList/index.ts +12 -0
  36. package/src/components/GalleryList/index.vue +311 -0
  37. package/src/components/GalleryList/setting.vue +268 -0
  38. package/src/components/GalleryList/type.ts +10 -0
  39. package/src/components/HeroSlide/index.ts +1 -1
  40. package/src/components/HeroSlide/index.vue +85 -133
  41. package/src/components/HeroSlide/setting.vue +435 -0
  42. package/src/components/HeroSlide/type.ts +5 -14
  43. package/src/components/LinkLIst/index.ts +11 -0
  44. package/src/components/LinkLIst/index.vue +317 -0
  45. package/src/components/LinkLIst/setting.vue +264 -0
  46. package/src/components/LinkLIst/type.ts +10 -0
  47. package/src/components/Media/index.vue +18 -18
  48. package/src/components/Operate/index.vue +17 -7
  49. package/src/components/Profile/index.vue +999 -0
  50. package/src/components/Profile/modal.vue +56 -0
  51. package/src/components/Profile/setting.vue +330 -0
  52. package/src/components/QuickLinks/index.vue +166 -0
  53. package/src/components/QuoteText/index.ts +11 -0
  54. package/src/components/QuoteText/index.vue +133 -0
  55. package/src/components/QuoteText/setting.vue +81 -0
  56. package/src/components/QuoteText/type.ts +10 -0
  57. package/src/components/ScrollKeyInfo/index.vue +0 -0
  58. package/src/components/Swiper/index.vue +538 -0
  59. package/src/components/index.ts +23 -5
  60. package/src/index.ts +56 -12
  61. package/src/main.ts +6 -3
  62. package/src/router/index.ts +6 -0
  63. package/src/style.css +17 -0
  64. package/src/styles/component-isolation.scss +256 -0
  65. package/src/styles/editor.scss +1 -1
  66. package/src/styles/layers.scss +256 -0
  67. package/src/styles/main.scss +21687 -0
  68. package/src/styles/mixins/style-isolation.scss +262 -0
  69. package/src/styles/smart-reset.scss +287 -0
  70. package/src/styles/test.scss +1 -1
  71. package/src/types/button.ts +10 -0
  72. package/src/views/StyleIsolationTest.vue +292 -0
  73. package/src/views/components/ArticleListDemo.vue +49 -10
@@ -0,0 +1,11 @@
1
+ import type { App, Plugin } from 'vue'
2
+ import LinkList from './index.vue'
3
+
4
+ export default {
5
+ install: (app: App) => {
6
+ app.component('LinkList', LinkList)
7
+ },
8
+ } satisfies Plugin
9
+
10
+ export { default as LinkList } from './index.vue'
11
+ export type { LinkListProps, LinkListEmits } from './type'
@@ -0,0 +1,317 @@
1
+ <template>
2
+ <div class="link-list" :style="{ backgroundColor: modelValue?.bgColor }" @mouseenter="isHover = true" @mouseleave="isHover = false">
3
+ <div class="link-list__container justify-content-center" :class="[modelValue?.width ? `container-content-${modelValue?.width}` : 'container-content']">
4
+ <div class="link-list__item" v-for="item in modelValue?.data" :key="item.id" @click="handleClick(item)">
5
+ <div class="circle-link" :class="[item.isLight ? 'circle-link--light' : '']" v-if="item.type === 'circle'">
6
+ <a :href="item.url || '#' " :class="[item.isLight ? 'nuxt-link-exact-active nuxt-link-active' : '']">
7
+ <div>{{ item.text }}</div>
8
+ <span class="circle-link__icon" :class="[item.isLight ? 'circle-link__icon--light' : '']"></span>
9
+ </a>
10
+ </div>
11
+ <div class="text-link" v-else>
12
+ <button type="button" class="text-link__wrapper link link--udrline-2">
13
+ <span class="text-link__text">{{ item.text }}</span>
14
+ </button>
15
+ </div>
16
+ </div>
17
+ </div>
18
+
19
+ <Operate v-if="!modelValue?.readOnly" v-model:show="isHover" @handle-edit="showSetting = true" @handle-delete="handleDelete" @handle-copy="handleCopy"></Operate>
20
+ </div>
21
+
22
+ <Setting v-model:show="showSetting" :data="modelValue"></Setting>
23
+ <ProfileModel v-model:show="showProfile" :data="profileData"></ProfileModel>
24
+ </template>
25
+
26
+ <script lang="ts" setup>
27
+ import { ref } from 'vue'
28
+ import { randomString } from '@/utils/common'
29
+ import Setting from './setting.vue'
30
+ import Operate from '@/components/Operate/index.vue'
31
+ import ProfileModel from '@/components/Profile/modal.vue'
32
+
33
+ // 定义组件名称
34
+ defineOptions({
35
+ name: 'LinkList'
36
+ })
37
+
38
+ const props = defineProps({
39
+ modelValue: {
40
+ type: Object,
41
+ default: () => {}
42
+ },
43
+
44
+ // 是否预览
45
+ isPreview: {
46
+ type: Boolean,
47
+ default: false
48
+ }
49
+ })
50
+
51
+ const emit = defineEmits(['update:modelValue', 'handleDelete', 'handleCopy'])
52
+
53
+ const handleInit = () => {
54
+ if (props.modelValue && props.modelValue.data) return // 有数据不用初始化
55
+ const data = {
56
+ id: props.modelValue?.id || randomString(),
57
+ type: 'LinkList',
58
+ readOnly: props.modelValue?.readOnly || false,
59
+ width: '',
60
+ bgColor: '',
61
+ data: [
62
+ {
63
+ id: randomString(),
64
+ type: 'circle',
65
+ text: '了解更多',
66
+ url: 'https://www.baidu.com',
67
+ isExternal: false,
68
+ isLight: false
69
+ },
70
+ {
71
+ id: randomString(),
72
+ type: 'circle',
73
+ text: '了解更多',
74
+ url: 'https://www.baidu.com',
75
+ isExternal: false,
76
+ isLight: true
77
+ },
78
+ {
79
+ id: randomString(),
80
+ type: 'text',
81
+ text: '了解更多',
82
+ profile: {
83
+ logo: 'https://ywies-tx.cedim.cn/images/logo/logo-ycyw.png',
84
+ title: '耀华国际教育学校浙江桐乡',
85
+ subTitle: '耀华国际教育学校浙江桐乡',
86
+ name: '耀华国际教育学校浙江桐乡',
87
+ label: '123',
88
+ imgSrc: 'https://osswebsite.ycyw.com/media-library/ywies-bj/images/home/ywies-tx.jpg',
89
+ alt: '',
90
+ buttonList: {
91
+ id: props.modelValue?.id || randomString(),
92
+ type: 'BtnList',
93
+ readOnly: true,
94
+ width: '',
95
+ bgColor: '',
96
+ data: [
97
+ {
98
+ id: randomString(),
99
+ type: 'white',
100
+ text: '了解更多',
101
+ url: 'https://www.baidu.com',
102
+ isExternal: false
103
+ },
104
+ {
105
+ id: randomString(),
106
+ type: 'light',
107
+ text: '了解更多',
108
+ url: 'https://www.baidu.com',
109
+ isExternal: false
110
+ }
111
+ ]
112
+ },
113
+ paragraphs: [{
114
+ id: randomString(),
115
+ title: '123',
116
+ content: '123'
117
+ }]
118
+ }
119
+ }
120
+ ]
121
+ }
122
+ emit('update:modelValue', data)
123
+ }
124
+
125
+ const isHover = ref<boolean>(false);
126
+ const showSetting = ref<boolean>(false);
127
+
128
+ const handleDelete = () => {
129
+ emit('handleDelete', props.modelValue.id)
130
+ }
131
+
132
+ const handleCopy = () => {
133
+ emit('handleCopy', props.modelValue)
134
+ }
135
+
136
+ const showProfile = ref<boolean>(false)
137
+ const profileData = ref<any>({})
138
+ const handleClick = (item: any) => {
139
+ if (item.type !== 'text') return
140
+ profileData.value = item.profile
141
+ showProfile.value = true
142
+ }
143
+
144
+ handleInit()
145
+ </script>
146
+
147
+ <style lang="scss" scoped>
148
+ .link-list {
149
+ position: relative;
150
+ }
151
+
152
+ .link-list__container {
153
+ display: flex;
154
+ align-items: center;
155
+ }
156
+
157
+ .link-list__item:not(:first-child) {
158
+ margin-left: 40px;
159
+ }
160
+
161
+ @media (max-width: 767.98px) {
162
+ .link-list__item:not(:first-child) {
163
+ margin-left: 24px;
164
+ }
165
+ }
166
+
167
+ .link-list.center .link-list__container {
168
+ justify-content: center;
169
+ }
170
+
171
+ .text-link {
172
+ display: flex;
173
+ }
174
+
175
+ .text-link__wrapper {
176
+ background: none;
177
+ padding: 0;
178
+ border: none;
179
+ --text-color: #0032a0;
180
+ }
181
+
182
+ .text-link--light .text-link__wrapper {
183
+ --text-color: #fff;
184
+ }
185
+
186
+ .circle-link {
187
+ display: flex;
188
+ --link-color: var(--link-blue-color);
189
+ }
190
+
191
+ .circle-link--light {
192
+ --link-color: var(--link-light-color);
193
+ }
194
+
195
+ .circle-link a,
196
+ .circle-link button {
197
+ font-size: 14px;
198
+ font-weight: 500;
199
+ line-height: 1.285;
200
+ letter-spacing: .04em;
201
+ border: none;
202
+ background: none;
203
+ color: var(--link-color);
204
+ text-decoration: none;
205
+ display: flex;
206
+ align-items: center;
207
+ padding: 0;
208
+ }
209
+
210
+ @media (max-width: 1023.98px) {
211
+ .circle-link a,
212
+ .circle-link button {
213
+ line-height: 1.428;
214
+ }
215
+ }
216
+
217
+ @media (max-width: 767.98px) {
218
+ .circle-link a,
219
+ .circle-link button {
220
+ line-height: 1.285;
221
+ }
222
+ }
223
+
224
+ .circle-link a:hover .circle-link__icon:before,
225
+ .circle-link button:hover .circle-link__icon:before {
226
+ transform: translate(-50%, -50%);
227
+ }
228
+
229
+ .circle-link a:hover .circle-link__icon:after,
230
+ .circle-link button:hover .circle-link__icon:after {
231
+ transform: translate(150%, -50%);
232
+ }
233
+
234
+ .circle-link a:active .circle-link__icon:before,
235
+ .circle-link button:active .circle-link__icon:before {
236
+ transform: translate(-260%, -50%);
237
+ }
238
+
239
+ .circle-link a:active .circle-link__icon:after,
240
+ .circle-link button:active .circle-link__icon:after {
241
+ transform: translate(-50%, -50%);
242
+ }
243
+
244
+ .circle-link__icon {
245
+ width: 18px;
246
+ height: 18px;
247
+ border-radius: 50%;
248
+ overflow: hidden;
249
+ background-color: var(--link-color);
250
+ position: relative;
251
+ margin-left: 7px;
252
+ flex-shrink: 0;
253
+ }
254
+
255
+ @media (max-width: 767.98px) {
256
+ .circle-link__icon {
257
+ width: 12px;
258
+ height: 12px;
259
+ margin-left: 4px;
260
+ }
261
+ }
262
+
263
+ .circle-link__icon:after,
264
+ .circle-link__icon:before {
265
+ content: "";
266
+ width: 6px;
267
+ height: 9px;
268
+ position: absolute;
269
+ top: 50%;
270
+ left: 55%;
271
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNiIgaGVpZ2h0PSI5IiB2aWV3Qm94PSIwIDAgNiA5IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMC4yMzUxOTYgNy42MjA3OUwzLjM2MDE4IDQuNDk1OEwwLjIzNTE5NiAxLjM3MDgyQzAuMTYwNjMgMS4yOTYyNSAwLjEwMTQ4MSAxLjIwNzczIDAuMDYxMTI1OSAxLjExMDMxQzAuMDIwNzcxIDEuMDEyODggMS41NzEzN2UtMDkgMC45MDg0NiAwIDAuODAzMDA4Qy0xLjU3MTM2ZS0wOSAwLjY5NzU1NSAwLjAyMDc3MSAwLjU5MzEzNSAwLjA2MTEyNTkgMC40OTU3MUMwLjEwMTQ4MSAwLjM5ODI4NSAwLjE2MDYzIDAuMzA5NzYyIDAuMjM1MTk2IDAuMjM1MTk1QzAuMzA5NzYyIDAuMTYwNjI5IDAuMzk4Mjg1IDAuMTAxNDggMC40OTU3MSAwLjA2MTEyNTFDMC41OTMxMzYgMC4wMjA3NzAyIDAuNjk3NTU2IC0xLjU3MTM3ZS0wOSAwLjgwMzAwOCAwQzAuOTA4NDYxIDEuNTcxMzdlLTA5IDEuMDEyODggMC4wMjA3NzAyIDEuMTEwMzEgMC4wNjExMjUxQzEuMjA3NzMgMC4xMDE0OCAxLjI5NjI1IDAuMTYwNjI5IDEuMzcwODIgMC4yMzUxOTVMNS4wNjc2NCAzLjkzMjAyQzUuMzgxNzUgNC4yNDYxMyA1LjM4MTc1IDQuNzUzNTMgNS4wNjc2NCA1LjA2NzY0TDEuMzcwODIgOC43NjQ0NkMxLjI5NjMxIDguODM5MTMgMS4yMDc4IDguODk4MzYgMS4xMTAzNyA4LjkzODc4QzEuMDEyOTQgOC45NzkyIDAuOTA4NDkxIDkgMC44MDMwMDggOUMwLjY5NzUyNSA5IDAuNTkzMDc4IDguOTc5MiAwLjQ5NTY0NSA4LjkzODc4QzAuMzk4MjEyIDguODk4MzYgMC4zMDk3MDcgOC44MzkxMyAwLjIzNTE5NiA4Ljc2NDQ2Qy0wLjA3MDg1OTEgOC40NTAzNSAtMC4wNzg5MTMyIDcuOTM0ODkgMC4yMzUxOTYgNy42MjA3OVoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=);
272
+ background-position: 50%;
273
+ background-size: cover;
274
+ background-repeat: no-repeat;
275
+ background-color: hsla(0,0%,100%,0);
276
+ transition: transform .3s ease-in-out;
277
+ }
278
+
279
+ @media (max-width: 767.98px) {
280
+ .circle-link__icon:after,
281
+ .circle-link__icon:before {
282
+ width: 4.7px;
283
+ height: 6px;
284
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNCIgaGVpZ2h0PSI2IiB2aWV3Qm94PSIwIDAgNCA2IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMSAxTDMuMDU3MTQgMy4wNTcxNEwxIDUuMTE0MjkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9zdmc+Cg==);
285
+ background-position: 50%;
286
+ background-size: cover;
287
+ background-repeat: no-repeat;
288
+ background-color: hsla(0,0%,100%,0);
289
+ }
290
+ }
291
+
292
+ .circle-link__icon:before {
293
+ transform: translate(-260%,-50%);
294
+ }
295
+
296
+ .circle-link__icon:after {
297
+ transform: translate(-50%,-50%);
298
+ }
299
+
300
+ .circle-link__icon--light:after,.circle-link__icon--light:before {
301
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNiIgaGVpZ2h0PSI5IiB2aWV3Qm94PSIwIDAgNiA5IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMC4yMzUxOTYgNy42MjA3OUwzLjM2MDE4IDQuNDk1OEwwLjIzNTE5NiAxLjM3MDgyQzAuMTYwNjMgMS4yOTYyNSAwLjEwMTQ4MSAxLjIwNzczIDAuMDYxMTI1OSAxLjExMDMxQzAuMDIwNzcxIDEuMDEyODggMS41NzEzN2UtMDkgMC45MDg0NiAwIDAuODAzMDA4Qy0xLjU3MTM2ZS0wOSAwLjY5NzU1NSAwLjAyMDc3MSAwLjU5MzEzNSAwLjA2MTEyNTkgMC40OTU3MUMwLjEwMTQ4MSAwLjM5ODI4NSAwLjE2MDYzIDAuMzA5NzYyIDAuMjM1MTk2IDAuMjM1MTk1QzAuMzA5NzYyIDAuMTYwNjI5IDAuMzk4Mjg1IDAuMTAxNDggMC40OTU3MSAwLjA2MTEyNTFDMC41OTMxMzYgMC4wMjA3NzAyIDAuNjk3NTU2IC0xLjU3MTM3ZS0wOSAwLjgwMzAwOCAwQzAuOTA4NDYxIDEuNTcxMzdlLTA5IDEuMDEyODggMC4wMjA3NzAyIDEuMTEwMzEgMC4wNjExMjUxQzEuMjA3NzMgMC4xMDE0OCAxLjI5NjI1IDAuMTYwNjI5IDEuMzcwODIgMC4yMzUxOTVMNS4wNjc2NCAzLjkzMjAyQzUuMzgxNzUgNC4yNDYxMyA1LjM4MTc1IDQuNzUzNTMgNS4wNjc2NCA1LjA2NzY0TDEuMzcwODIgOC43NjQ0NkMxLjI5NjMxIDguODM5MTMgMS4yMDc4IDguODk4MzYgMS4xMTAzNyA4LjkzODc4QzEuMDEyOTQgOC45NzkyIDAuOTA4NDkxIDkgMC44MDMwMDggOUMwLjY5NzUyNSA5IDAuNTkzMDc4IDguOTc5MiAwLjQ5NTY0NSA4LjkzODc4QzAuMzk4MjEyIDguODk4MzYgMC4zMDk3MDcgOC44MzkxMyAwLjIzNTE5NiA4Ljc2NDQ2Qy0wLjA3MDg1OTEgOC40NTAzNSAtMC4wNzg5MTMyIDcuOTM0ODkgMC4yMzUxOTYgNy42MjA3OVoiIGZpbGw9IiMwMDFFNjAiLz4KPC9zdmc+Cgo=);
302
+ background-position: 50%;
303
+ background-size: cover;
304
+ background-repeat: no-repeat;
305
+ background-color: hsla(0,0%,100%,0);
306
+ }
307
+
308
+ @media (max-width: 767.98px) {
309
+ .circle-link__icon--light:after,.circle-link__icon--light:before {
310
+ background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNCIgaGVpZ2h0PSI2IiB2aWV3Qm94PSIwIDAgNCA2IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMSAxTDMuMDU3MTQgMy4wNTcxNEwxIDUuMTE0MjkiIHN0cm9rZT0iIzAwMUU2MCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8L3N2Zz4K);
311
+ background-position: 50%;
312
+ background-size: cover;
313
+ background-repeat: no-repeat;
314
+ background-color: hsla(0,0%,100%,0);
315
+ }
316
+ }
317
+ </style>
@@ -0,0 +1,264 @@
1
+ <template>
2
+ <a-drawer :width="500" :visible="show" :footer="false" @cancel="handleCancel" unmountOnClose>
3
+ <template #title>
4
+ {{data.type}}组件编辑
5
+ </template>
6
+ <div class="setting-content">
7
+ <!-- 组件自身属性 -->
8
+ <div class="setting-header flex items-center">
9
+ <span class="header-title">组件宽度</span>
10
+ <a-select v-model="data.width" placeholder="请选择" allow-clear>
11
+ <a-option value="">默认</a-option>
12
+ <a-option value="small">小</a-option>
13
+ <a-option value="middle">中</a-option>
14
+ <a-option value="max">大</a-option>
15
+ </a-select>
16
+ </div>
17
+ <div class="setting-header flex items-center">
18
+ <span class="header-title">组件背景</span>
19
+ <a-select v-model="data.bgColor" placeholder="请选择" allow-clear>
20
+ <a-option value="#ffffff">白色</a-option>
21
+ <a-option value="#F7F7FA">灰色</a-option>
22
+ </a-select>
23
+ </div>
24
+
25
+ <a-button-group type="primary">
26
+ <a-button size="mini" @click="handleAdd('circle')"><template #icon><icon-plus /></template> 圆链接 </a-button>
27
+ <a-button size="mini" @click="handleAdd('text')"><template #icon><icon-plus /></template> 文字链接 </a-button>
28
+ </a-button-group>
29
+
30
+ <!-- 子组件属性 -->
31
+ <div class="setting-body">
32
+ <div class="setting-item">
33
+ <p class="item-name">链接</p>
34
+ <draggable
35
+ v-model="data.data"
36
+ :component-data="{
37
+ tag: 'div',
38
+ type: 'transition-group',
39
+ name: !drag ? 'flip-list' : null
40
+ }"
41
+ v-bind="linkDragOptions"
42
+ :disabled="!shouldShowDragHandle(data.data)"
43
+ @start="drag = true"
44
+ @end="drag = false"
45
+ item-key="id"
46
+ >
47
+ <template #item="{ element: link }">
48
+ <div
49
+ class="item-button draggable-item"
50
+ :class="{ 'sortable-disabled': !shouldShowDragHandle(data.data) }"
51
+ :key="link.id"
52
+ >
53
+ <div class="btn-group">
54
+ <div
55
+ v-if="shouldShowDragHandle(data.data)"
56
+ class="drag-handle"
57
+ >
58
+ <icon-drag-arrow class="drag-icon" />
59
+ </div>
60
+ <icon-delete class="btn-delete" @click="handleDelete(link.id)" />
61
+ </div>
62
+ <a-link href="link">{{ link.text }}</a-link>
63
+ <template v-if="link.type === 'circle'">
64
+ <div class="item-action flex items-center">
65
+ <a-input class="action-text" v-model="link.text" placeholder="链接文本" allow-clear />
66
+ <a-input v-model="link.url" placeholder="链接链接" allow-clear />
67
+ </div>
68
+ <a-checkbox :model-value="link.isExternal">是否外部链接</a-checkbox>
69
+ <a-checkbox style="padding-left: 10px;" :model-value="link.isLight">是否亮色</a-checkbox>
70
+ </template>
71
+ <template v-else>
72
+ <a-input class="action-text m-2" v-model="link.text" placeholder="链接文本" allow-clear />
73
+ <p class="item-name">Profile Information</p>
74
+
75
+ <ProfileSetting :data="link.profile"></ProfileSetting>
76
+ </template>
77
+ </div>
78
+ </template>
79
+ </draggable>
80
+ </div>
81
+ </div>
82
+ </div>
83
+ </a-drawer>
84
+ </template>
85
+
86
+ <script lang="ts" setup>
87
+ import { ref, computed } from 'vue'
88
+ import draggable from 'vuedraggable'
89
+ import ProfileSetting from '@/components/Profile/setting.vue'
90
+ import { randomString } from '@/utils/common'
91
+
92
+ // 拖拽相关状态
93
+ const drag = ref(false)
94
+
95
+ // 不同类型的拖拽配置选项
96
+ const linkDragOptions = computed(() => ({
97
+ animation: 200,
98
+ group: 'links', // 链接专用分组
99
+ disabled: false,
100
+ ghostClass: 'ghost'
101
+ }))
102
+
103
+ // 检查是否应该显示拖拽图标
104
+ const shouldShowDragHandle = (list: any[]) => {
105
+ return list && list.length > 1
106
+ }
107
+
108
+ const props = defineProps({
109
+ show: {
110
+ type: Boolean,
111
+ default: false
112
+ },
113
+
114
+ data: {
115
+ type: Object,
116
+ default: () => {}
117
+ }
118
+ })
119
+
120
+ const emit = defineEmits(['update:show']);
121
+
122
+ const handleCancel = () => {
123
+ emit('update:show', false);
124
+ }
125
+
126
+ const handleAdd = (type: string) => {
127
+ const detail = props.data;
128
+ detail.data.push({
129
+ id: randomString(),
130
+ type,
131
+ text: '查看更多',
132
+ url: undefined,
133
+ isExternal: false,
134
+ isLight: false
135
+ })
136
+ }
137
+
138
+ const handleDelete = (id: string) => {
139
+ props.data.data = props.data.data.filter((item: any) => item.id !== id)
140
+ }
141
+ </script>
142
+
143
+ <style lang="scss" scoped>
144
+ .setting-content {
145
+ .setting-header {
146
+ padding-bottom: 12px;
147
+
148
+ .header-title {
149
+ width: 120px;
150
+ padding-right: 12px;
151
+ text-align: right;
152
+ }
153
+ }
154
+
155
+ .setting-body {
156
+ margin-top: 12px;
157
+
158
+ .setting-item {
159
+ position: relative;
160
+ padding: 16px 12px;
161
+ background: #f0f2f5;
162
+ border-radius: 8px;
163
+ margin-bottom: 20px;
164
+
165
+ .btn-group {
166
+ position: absolute;
167
+ right: 0;
168
+ top: 0;
169
+ display: flex;
170
+ align-items: center;
171
+ padding: 4px;
172
+
173
+ .btn-delete {
174
+ padding: 4px;
175
+ font-size: 24px;
176
+ cursor: pointer;
177
+ }
178
+ }
179
+
180
+ .item-name {
181
+ font-size: 16px;
182
+ font-weight: 600;
183
+ padding-bottom: 10px;
184
+ border-bottom: 1px solid #fff;
185
+ }
186
+
187
+ .item-button {
188
+ position: relative;
189
+ padding: 12px 8px 4px;
190
+ background: #fff;
191
+ border-radius: 4px;
192
+ margin: 4px 0;
193
+ transition: all 0.3s ease;
194
+
195
+ &.draggable-item {
196
+ cursor: move;
197
+
198
+ &:hover {
199
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
200
+ transform: translateY(-1px);
201
+ }
202
+
203
+ // 当禁用拖拽时,不显示拖拽效果
204
+ &.sortable-disabled {
205
+ cursor: default;
206
+
207
+ &:hover {
208
+ box-shadow: none;
209
+ transform: none;
210
+ }
211
+ }
212
+ }
213
+
214
+ .arco-input-wrapper {
215
+ background: #f2f3f5;
216
+ }
217
+ }
218
+
219
+ // 拖拽相关样式
220
+ .flip-list-move {
221
+ transition: transform 0.5s;
222
+ }
223
+
224
+ .no-move {
225
+ transition: transform 0s;
226
+ }
227
+
228
+ .ghost {
229
+ opacity: 0.5;
230
+ background: #c8ebfb;
231
+ }
232
+
233
+ .item-action {
234
+ padding: 10px 0;
235
+
236
+ .action-text {
237
+ width: 150px;
238
+ margin-right: 8px;
239
+ }
240
+ }
241
+ }
242
+ }
243
+
244
+ .drag-handle {
245
+ padding: 4px;
246
+ cursor: grab;
247
+ padding: 4px;
248
+ border-radius: 4px;
249
+
250
+ &:hover {
251
+ background-color: #f0f2f5;
252
+ }
253
+
254
+ &:active {
255
+ cursor: grabbing;
256
+ }
257
+
258
+ .drag-icon {
259
+ font-size: 16px;
260
+ color: #86909c;
261
+ }
262
+ }
263
+ }
264
+ </style>
@@ -0,0 +1,10 @@
1
+ export interface LinkListProps {
2
+ /** 双向绑定的值 */
3
+ modelValue: any
4
+ }
5
+
6
+ export interface LinkListEmits {
7
+ (e: 'update:modelValue', value: any): void
8
+ (e: 'handleDelete', value: string | number): void
9
+ (e: 'handleCopy', value: any): void
10
+ }
@@ -241,7 +241,7 @@ onUnmounted(() => {
241
241
  }
242
242
 
243
243
  .image:not(:last-of-type) {
244
- margin-right: 10.6px
244
+ margin-right: 10.6px;
245
245
  }
246
246
  }
247
247
 
@@ -272,56 +272,56 @@ onUnmounted(() => {
272
272
  }
273
273
  }
274
274
 
275
- @media(max-width: 767.98px) {
275
+ @media (max-width: 767.98px) {
276
276
  .image-container .image {
277
277
  border-radius: 0;
278
278
  }
279
279
  }
280
280
 
281
- @media(max-width: 1023.98px) {
281
+ @media (max-width: 1023.98px) {
282
282
  .image-desc p {
283
- font-size:14px;
283
+ font-size: 14px;
284
284
  line-height: 1.714;
285
- letter-spacing: .01em
285
+ letter-spacing: .01em;
286
286
  }
287
287
  }
288
288
 
289
- @media(max-width: 767.98px) {
289
+ @media (max-width: 767.98px) {
290
290
  .video-container {
291
- width:100vw;
292
- padding: 0
291
+ width: 100vw;
292
+ padding: 0;
293
293
  }
294
294
  }
295
295
 
296
- @media(max-width: 767.98px) {
296
+ @media (max-width: 767.98px) {
297
297
  .image-list-container .image-preview {
298
- padding-bottom:68.75%
298
+ padding-bottom: 68.75%;
299
299
  }
300
300
  }
301
301
 
302
- @media(max-width: 1023.98px) {
302
+ @media (max-width: 1023.98px) {
303
303
  .thumbnail__nav__prev,
304
304
  .thumbnail__nav__next {
305
- width:28px
305
+ width: 28px;
306
306
  }
307
307
  }
308
308
 
309
- @media(max-width: 767.98px) {
309
+ @media (max-width: 767.98px) {
310
310
  .thumbnail__nav__prev,
311
311
  .thumbnail__nav__next {
312
- box-shadow:0 4px 4px hsla(0,0%,100%,.2)
312
+ box-shadow: 0 4px 4px hsla(0,0%,100%,.2);
313
313
  }
314
314
  }
315
315
 
316
- @media(max-width: 900px) {
316
+ @media (max-width: 900px) {
317
317
  .image-list-container .image-list-wrapper .image-list .image {
318
- width:80px
318
+ width: 80px;
319
319
  }
320
320
  }
321
321
 
322
- @media(max-width: 767.98px) {
322
+ @media (max-width: 767.98px) {
323
323
  .image-list-container .image-list-wrapper .image-list .image {
324
- width:75px
324
+ width: 75px;
325
325
  }
326
326
  }
327
327
  </style>