officialblock 1.0.7 → 1.0.9

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 (103) 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 +13608 -10831
  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/assets/icon-email.svg +3 -0
  13. package/src/components/ArticleList/article.vue +3 -3
  14. package/src/components/ArticleList/contact.vue +9 -9
  15. package/src/components/ArticleList/index.ts +1 -1
  16. package/src/components/ArticleList/index.vue +22 -80
  17. package/src/components/ArticleList/setting.vue +339 -175
  18. package/src/components/ArticleList/type.ts +12 -18
  19. package/src/components/BannerImage/index.ts +11 -0
  20. package/src/components/BannerImage/index.vue +153 -0
  21. package/src/components/BannerImage/setting.vue +55 -0
  22. package/src/components/BannerImage/type.ts +10 -0
  23. package/src/components/BannerImageWithLink/index.ts +11 -0
  24. package/src/components/BannerImageWithLink/index.vue +323 -0
  25. package/src/components/BannerImageWithLink/setting.vue +344 -0
  26. package/src/components/BannerImageWithLink/type.ts +17 -0
  27. package/src/components/BannerPage/index.ts +11 -0
  28. package/src/components/BannerPage/index.vue +283 -0
  29. package/src/components/BannerPage/setting.vue +55 -0
  30. package/src/components/BannerPage/type.ts +10 -0
  31. package/src/components/BtnList/index.ts +11 -0
  32. package/src/components/BtnList/index.vue +588 -0
  33. package/src/components/BtnList/setting.vue +255 -0
  34. package/src/components/BtnList/type.ts +10 -0
  35. package/src/components/Button/index.vue +45 -33
  36. package/src/components/ContactUsList/index.ts +11 -0
  37. package/src/components/ContactUsList/index.vue +369 -0
  38. package/src/components/ContactUsList/setting.vue +497 -0
  39. package/src/components/ContactUsList/type.ts +17 -0
  40. package/src/components/CountDown/index.ts +11 -0
  41. package/src/components/CountDown/index.vue +315 -0
  42. package/src/components/CountDown/setting.vue +302 -0
  43. package/src/components/CountDown/type.ts +17 -0
  44. package/src/components/CustomIframe/index.ts +11 -0
  45. package/src/components/CustomIframe/index.vue +118 -0
  46. package/src/components/CustomIframe/setting.vue +323 -0
  47. package/src/components/CustomIframe/type.ts +17 -0
  48. package/src/components/CustomSpace/index.ts +11 -0
  49. package/src/components/CustomSpace/index.vue +82 -0
  50. package/src/components/CustomSpace/setting.vue +89 -0
  51. package/src/components/CustomSpace/type.ts +10 -0
  52. package/src/components/GalleryList/index.ts +12 -0
  53. package/src/components/GalleryList/index.vue +311 -0
  54. package/src/components/GalleryList/setting.vue +268 -0
  55. package/src/components/GalleryList/type.ts +10 -0
  56. package/src/components/HeroSlide/index.ts +1 -1
  57. package/src/components/HeroSlide/index.vue +85 -133
  58. package/src/components/HeroSlide/setting.vue +435 -0
  59. package/src/components/HeroSlide/type.ts +5 -14
  60. package/src/components/LinkLIst/index.ts +11 -0
  61. package/src/components/LinkLIst/index.vue +317 -0
  62. package/src/components/LinkLIst/setting.vue +264 -0
  63. package/src/components/LinkLIst/type.ts +10 -0
  64. package/src/components/Media/index.vue +18 -18
  65. package/src/components/Operate/index.vue +17 -8
  66. package/src/components/Profile/index.vue +999 -0
  67. package/src/components/Profile/modal.vue +56 -0
  68. package/src/components/Profile/setting.vue +330 -0
  69. package/src/components/QuickLinks/index.vue +166 -0
  70. package/src/components/QuoteText/index.ts +11 -0
  71. package/src/components/QuoteText/index.vue +133 -0
  72. package/src/components/QuoteText/setting.vue +81 -0
  73. package/src/components/QuoteText/type.ts +10 -0
  74. package/src/components/ScrollKeyInfo/index.ts +11 -0
  75. package/src/components/ScrollKeyInfo/index.vue +1345 -0
  76. package/src/components/ScrollKeyInfo/setting.vue +302 -0
  77. package/src/components/ScrollKeyInfo/type.ts +17 -0
  78. package/src/components/Swiper/index.vue +538 -0
  79. package/src/components/TabDefault/components/ComponentSelector/compsData.js +143 -0
  80. package/src/components/TabDefault/components/ComponentSelector/index.vue +188 -0
  81. package/src/components/TabDefault/components/PageContent.vue +207 -0
  82. package/src/components/TabDefault/index.vue +475 -0
  83. package/src/components/TabDefault/setting.vue +581 -0
  84. package/src/components/TabDefault/type.ts +17 -0
  85. package/src/components/TableTwo/index.ts +11 -0
  86. package/src/components/TableTwo/index.vue +232 -0
  87. package/src/components/TableTwo/setting.vue +558 -0
  88. package/src/components/TableTwo/type.ts +17 -0
  89. package/src/components/index.ts +40 -5
  90. package/src/index.ts +56 -12
  91. package/src/main.ts +6 -3
  92. package/src/router/index.ts +6 -0
  93. package/src/style.css +17 -0
  94. package/src/styles/component-isolation.scss +257 -0
  95. package/src/styles/editor.scss +1 -1
  96. package/src/styles/layers.scss +256 -0
  97. package/src/styles/main.scss +21687 -0
  98. package/src/styles/mixins/style-isolation.scss +262 -0
  99. package/src/styles/smart-reset.scss +287 -0
  100. package/src/styles/test.scss +1 -1
  101. package/src/types/button.ts +10 -0
  102. package/src/views/StyleIsolationTest.vue +292 -0
  103. package/src/views/components/ArticleListDemo.vue +59 -19
@@ -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>