officialblock 1.0.1 → 1.0.3

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 (40) hide show
  1. package/README.md +25 -1
  2. package/dist/official-block.cjs.js +195 -1
  3. package/dist/official-block.es.js +27230 -72
  4. package/dist/official-block.umd.js +195 -1
  5. package/dist/style.css +1 -1
  6. package/package.json +13 -2
  7. package/src/App.vue +32 -82
  8. package/src/components/ArticleList/article.vue +73 -0
  9. package/src/components/ArticleList/contact.vue +95 -0
  10. package/src/components/ArticleList/index.vue +220 -46
  11. package/src/components/ArticleList/setting.vue +709 -0
  12. package/src/components/Button/index.vue +183 -0
  13. package/src/components/Media/index.vue +327 -0
  14. package/src/components/Operate/index.vue +74 -0
  15. package/src/components/RichTextEditor/RichTextEditor.vue +277 -0
  16. package/src/components/RichTextEditor/index.ts +7 -0
  17. package/src/components/ThemePreview/ThemePreview.vue +462 -0
  18. package/src/components/ThemePreview/index.ts +4 -0
  19. package/src/components/index.ts +3 -0
  20. package/src/composables/useTheme.ts +205 -0
  21. package/src/index.ts +15 -4
  22. package/src/main.ts +16 -1
  23. package/src/router/index.ts +96 -0
  24. package/src/style.css +2 -4
  25. package/src/styles/editor.scss +649 -0
  26. package/src/styles/test.scss +20 -0
  27. package/src/styles/variables.scss +669 -0
  28. package/src/utils/common.ts +13 -0
  29. package/src/utils/theme.ts +335 -0
  30. package/src/views/Layout.vue +250 -0
  31. package/src/views/NotFound.vue +114 -0
  32. package/src/views/components/ArticleListDemo.vue +166 -0
  33. package/src/views/components/DragLimitDemo.vue +573 -0
  34. package/src/views/components/DragSortDemo.vue +610 -0
  35. package/src/views/components/HeroSlideDemo.vue +353 -0
  36. package/src/views/components/RichTextEditorDemo.vue +53 -0
  37. package/src/views/components/ThemeDemo.vue +477 -0
  38. package/src/views/guide/Installation.vue +234 -0
  39. package/src/views/guide/Introduction.vue +174 -0
  40. package/src/views/guide/QuickStart.vue +265 -0
@@ -1,78 +1,252 @@
1
1
  <template>
2
- <div
3
- class="your-component"
4
- :class="[`size-${size}`, { 'is-disabled': disabled }]"
5
- @click="handleClick"
6
- >
7
- <slot name="header" :title="title"></slot>
8
- <div class="content">
9
- <slot :value="modelValue">{{ modelValue }}</slot>
10
- </div>
2
+ <div class="article-list-container" :style="{ background: modelValue?.background ? modelValue?.background === 'white' ? '#fff' : '#F7F7FA' : 'transparent' }">
3
+ <a-row class="article-list" @mouseenter="isHover = true" @mouseleave="isHover = false">
4
+ <!-- 左侧文本 后侧媒体 -->
5
+ <!-- 左侧一直是一半,但只有左侧时是100% -->
6
+ <a-col :sm="{span: 24}" :md="{span: hasMedia ? 12 : 24}">
7
+ <div class="article-list-left">
8
+ <template v-for="item in modelValue?.data" :key="item.id">
9
+ <Article v-if="item.type === 'Article'" :article="item.data"></Article>
10
+ <Contact v-if="item.type === 'Contact'" :contact="item.data"></Contact>
11
+ </template>
12
+ </div>
13
+ </a-col>
14
+ <a-col v-if="hasMedia" :sm="{span: 24}" :md="{span: 12}">
15
+ <div class="article-list-right">
16
+ <template v-for="item in modelValue?.data" :key="item.id">
17
+ <Media :type="item.type" :data="item.data" :preview="modelValue.isPreview"></Media>
18
+ </template>
19
+ </div>
20
+ </a-col>
21
+
22
+ <!-- <div v-if="isHover" class="add-btn">
23
+ <icon-plus />
24
+ <span class="btn-text">添加组件</span>
25
+ </div> -->
26
+ <Operate v-model:show="isHover" @handle-edit="showSetting = true" @handle-delete="handleDelete" @handle-copy="handleCopy"></Operate>
27
+ </a-row>
11
28
  </div>
29
+
30
+
31
+ <Setting v-model:show="showSetting" :data="modelValue"></Setting>
12
32
  </template>
13
33
 
14
34
  <script lang="ts" setup>
15
- import { computed } from 'vue'
16
- import type { ComponentProps, ComponentEmits, ComponentSlots } from './type'
35
+ import { computed, ref } from 'vue'
36
+ import { randomString } from '@/utils/common'
37
+ import Article from './article.vue'
38
+ import Contact from './contact.vue'
39
+ import Media from '@/components/Media/index.vue'
40
+ import Setting from './setting.vue'
41
+ import Operate from '@/components/Operate/index.vue'
17
42
 
18
43
  // 定义组件名称
19
44
  defineOptions({
20
45
  name: 'ArticleList'
21
46
  })
22
47
 
23
- const props = withDefaults(defineProps<ComponentProps>(), {
24
- size: 'medium',
25
- disabled: false
48
+ const props = defineProps({
49
+ modelValue: {
50
+ type: Object,
51
+ default: () => {}
52
+ },
53
+
54
+ // 是否预览
55
+ isPreview: {
56
+ type: Boolean,
57
+ default: false
58
+ }
26
59
  })
27
60
 
28
- const emit = defineEmits<ComponentEmits>()
29
- defineSlots<ComponentSlots>()
61
+ const emit = defineEmits(['update:modelValue', 'handleDelete', 'handleCopy'])
30
62
 
31
- const title = computed(() => `Current value: ${props.modelValue}`)
63
+ const hasMedia = computed(() => {
64
+ if (!(props.modelValue && props.modelValue.data && props.modelValue.data.length)) return false
65
+ return props.modelValue.data.some((item: any) => item.type === 'Image' || item.type === 'Video' || item.type === 'ImageList')
66
+ })
32
67
 
33
- function handleClick() {
34
- if (!props.disabled) {
35
- emit('change', props.modelValue)
68
+ const handleInit = () => {
69
+ if (props.modelValue && props.modelValue.id) return // 有数据不用初始化
70
+ const data = {
71
+ id: randomString(),
72
+ type: 'ArticleList',
73
+ isPreview: false,
74
+ width: '',
75
+ background: '',
76
+ data: [
77
+ {
78
+ id: randomString(),
79
+ type: 'Article',
80
+ data: {
81
+ title: '这里是标题',
82
+ content: '耀华国际教育学校浙江桐乡校区成立于 2017 年,先进的校园设施确保学 生在安全友好的环境中学习。学校坐落于高桥镇,提供从幼儿阶段至高中 阶段 (K2 至13 年级) 的教育服务,招收2 岁至18 岁本地和外籍学生。',
83
+ buttonList: [
84
+ {
85
+ id: randomString(),
86
+ text: '查看更多',
87
+ url: 'https://www.baidu.com',
88
+ isExternal: false
89
+ }
90
+ ],
91
+ linkList: [
92
+ {
93
+ id: randomString(),
94
+ text: '查看更多',
95
+ url: 'https://www.baidu.com',
96
+ isExternal: false
97
+ }
98
+ ]
99
+ }
100
+ },
101
+ {
102
+ id: randomString(),
103
+ type: 'Image',
104
+ data: {
105
+ imgSrc: 'https://osswebsite.ycyw.com/media-library/ywies-bj/images/home/ywies-tx.jpg',
106
+ caption: '',
107
+ alt: '',
108
+ isRound: false
109
+ }
110
+ },
111
+ {
112
+ id: randomString(),
113
+ type: 'Contact',
114
+ data: {
115
+ title: '这里是标题',
116
+ content: '耀华国际教育学校浙江桐乡校区成立于 2017 年,先进的校园设施确保学 生在安全友好的环境中学习。学校坐落于高桥镇,提供从幼儿阶段至高中 阶段 (K2 至13 年级) 的教育服务,招收2 岁至18 岁本地和外籍学生。',
117
+ categories: [
118
+ {
119
+ id: randomString(),
120
+ text: '分类1'
121
+ }
122
+ ],
123
+ linkList: [
124
+ {
125
+ id: randomString(),
126
+ text: '查看更多',
127
+ url: 'https://www.baidu.com',
128
+ isExternal: false
129
+ }
130
+ ]
131
+ }
132
+ },
133
+ {
134
+ id: randomString(),
135
+ type: 'ImageList',
136
+ data: {
137
+ imageList: [
138
+ {
139
+ id: randomString(),
140
+ src: 'https://osswebsite.ycyw.com/media-library/ywies-bj/images/home/ywies-tx.jpg'
141
+ }
142
+ ],
143
+ }
144
+ },
145
+ {
146
+ id: randomString(),
147
+ type: 'Video',
148
+ data: {
149
+ videoSrc: 'http://mpv.videocc.net/4b964bbdf4/3/4b964bbdf481505df84cfd703c4b3043_2.mp4',
150
+ imgSrc: 'https://object.ycyw.com/media-library/ycyw-edu/news/20250628%20HKDSE%20Forum/Cover.jpg',
151
+ }
152
+ },
153
+ ]
36
154
  }
155
+ emit('update:modelValue', data)
156
+ }
157
+
158
+ const isHover = ref<boolean>(false);
159
+ const showSetting = ref<boolean>(false);
160
+
161
+ const handleDelete = () => {
162
+ emit('handleDelete', props.modelValue.id)
37
163
  }
38
- </script>
39
164
 
40
- <style scoped>
41
- .your-component {
42
- padding: 16px;
43
- border: 1px solid #ddd;
44
- border-radius: 8px;
45
- background: #fff;
46
- transition: all 0.3s ease;
165
+ const handleCopy = () => {
166
+ emit('handleCopy', props.modelValue)
47
167
  }
48
168
 
49
- .your-component:hover {
50
- border-color: #409eff;
51
- box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
169
+ handleInit()
170
+ </script>
171
+
172
+ <style lang="scss" scoped>
173
+ /* ===== 响应式设计 - 桌面优先,确保正确的层叠顺序 ===== */
174
+
175
+ /* 基础样式 - 桌面端 (1024px 及以上) */
176
+
177
+ .article-list-container {
178
+ width: 100%;
52
179
  }
180
+ .article-list {
181
+ position: relative;
182
+ max-width: 952px;
183
+ padding: 16px 36px;
184
+ margin: 0 auto;
53
185
 
54
- .your-component.is-disabled {
55
- opacity: 0.6;
56
- cursor: not-allowed;
57
- background: #f5f5f5;
186
+ // &:hover {
187
+ // border: 2px solid $primary-color;
188
+ // }
189
+
190
+ .add-btn {
191
+ position: absolute;
192
+ left: 50%;
193
+ bottom: 0;
194
+ transform: translate(-50%, 50%);
195
+
196
+ padding: 4px 8px;
197
+ font-size: 10px;
198
+ background: $primary-color;
199
+ color: #fff;
200
+ border-radius: 4px;
201
+ font-weight: 600;
202
+ cursor: pointer;
203
+ }
58
204
  }
59
205
 
60
- .your-component.size-small {
61
- padding: 8px;
62
- font-size: 12px;
206
+ .article-list-right {
207
+ margin-left: 60px;
208
+ max-width: 409px;
63
209
  }
64
210
 
65
- .your-component.size-medium {
66
- padding: 16px;
67
- font-size: 14px;
211
+ /* 平板设备 (768px - 1023px) */
212
+ @media (max-width: 1023.98px) {
213
+ .article-list {
214
+ padding: 12px 24px;
215
+ max-width: 1000px;
216
+ }
217
+
218
+ .article-list-right {
219
+ justify-content: flex-end;
220
+ margin-left: 20px;
221
+ max-width: 320px;
222
+ }
68
223
  }
69
224
 
70
- .your-component.size-large {
71
- padding: 24px;
72
- font-size: 16px;
225
+ /* 小平板和大手机 (576px - 767px) */
226
+ @media (max-width: 767.98px) {
227
+ .article-list {
228
+ padding: 8px 12px;
229
+ max-width: 976px;
230
+ }
231
+
232
+ .article-list-right {
233
+ justify-content: flex-start;
234
+ margin-left: 0;
235
+ max-width: 100vw;
236
+ }
73
237
  }
74
238
 
75
- .content {
76
- margin-top: 8px;
239
+ /* 小手机 (575px 及以下) */
240
+ @media (max-width: 575.98px) {
241
+ .article-list {
242
+ padding: 8px 12px;
243
+ max-width: 100%;
244
+ }
245
+
246
+ .article-list-right {
247
+ justify-content: flex-start;
248
+ margin-left: 0;
249
+ max-width: 100%;
250
+ }
77
251
  }
78
252
  </style>