@opendesign-plus-test/components 0.0.1-rc.2

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 (52) hide show
  1. package/dist/components.cjs.js +1 -0
  2. package/dist/components.css +1 -0
  3. package/dist/components.es.js +1193 -0
  4. package/dist/components.umd.js +1 -0
  5. package/docs/design.md +27 -0
  6. package/docs/design_banner.md +41 -0
  7. package/docs/design_section.md +27 -0
  8. package/package.json +47 -0
  9. package/scripts/generate-components-index.js +81 -0
  10. package/src/assets/svg-icons/icon-chevron-right.svg +3 -0
  11. package/src/assets/svg-icons/icon-close.svg +3 -0
  12. package/src/assets/svg-icons/icon-delete.svg +3 -0
  13. package/src/assets/svg-icons/icon-header-back.svg +3 -0
  14. package/src/assets/svg-icons/icon-header-delete.svg +3 -0
  15. package/src/assets/svg-icons/icon-header-search.svg +4 -0
  16. package/src/assets/svg-icons/icon-moon.svg +3 -0
  17. package/src/assets/svg-icons/icon-sun.svg +3 -0
  18. package/src/components/OBanner.vue +390 -0
  19. package/src/components/OCookieNotice.vue +417 -0
  20. package/src/components/OCookieNoticeEl.vue +403 -0
  21. package/src/components/OHeaderSearch.vue +601 -0
  22. package/src/components/OPlusConfigProvider.vue +32 -0
  23. package/src/components/OSection.vue +178 -0
  24. package/src/components/OThemeSwitcher.vue +108 -0
  25. package/src/components/common/ClientOnlyWrapper.ts +21 -0
  26. package/src/components/common/ContentWrapper.vue +85 -0
  27. package/src/draft/Banner.vue +265 -0
  28. package/src/draft/ButtonCards.vue +106 -0
  29. package/src/draft/Feature.vue +134 -0
  30. package/src/draft/Footer.vue +512 -0
  31. package/src/draft/HorizontalAnchor.vue +165 -0
  32. package/src/draft/ItemSwiper.vue +133 -0
  33. package/src/draft/Logo.vue +141 -0
  34. package/src/draft/LogoCard.vue +75 -0
  35. package/src/draft/LogoV2.vue +19 -0
  36. package/src/draft/MainCard.vue +38 -0
  37. package/src/draft/MultiCard.vue +95 -0
  38. package/src/draft/MultiIconCard.vue +74 -0
  39. package/src/draft/OInfoCard.vue +176 -0
  40. package/src/draft/Process.vue +81 -0
  41. package/src/draft/Section.vue +167 -0
  42. package/src/draft/SingleTabCard.vue +85 -0
  43. package/src/draft/SliderCard.vue +110 -0
  44. package/src/env.d.ts +1 -0
  45. package/src/i18n/en.ts +20 -0
  46. package/src/i18n/index.ts +42 -0
  47. package/src/i18n/zh.ts +9 -0
  48. package/src/index.ts +34 -0
  49. package/src/shared/provide.ts +6 -0
  50. package/src/vue.d.ts +10 -0
  51. package/tsconfig.json +33 -0
  52. package/vite.config.ts +90 -0
@@ -0,0 +1,403 @@
1
+ <script lang="ts" setup>
2
+ import { ref, onMounted, computed, nextTick } from 'vue';
3
+ import ClientOnly from './common/ClientOnlyWrapper';
4
+ import { useScreen } from '@opendesign-plus/composables';
5
+ import { useI18n } from '@/i18n';
6
+ import { ElButton, ElDialog, ElSwitch, ElIcon } from 'element-plus';
7
+ import { useVModel } from '@vueuse/core';
8
+
9
+ const NOT_SIGNED = '0';
10
+ const ALL_AGREED = '1';
11
+ const NECCESSARY_AGREED = '2';
12
+ const NOT_SHOW_BUT_AGREED = '3';
13
+ const COOKIE_DOMAIN = import.meta.env.VITE_COOKIE_DOMAIN as string;
14
+ const COOKIE_KEY_ZH = 'agreed-cookiepolicy-zh';
15
+ const COOKIE_KEY_EN = 'agreed-cookiepolicy-en';
16
+
17
+ const props = defineProps<{
18
+ visible?: boolean;
19
+ enableGrid?: boolean;
20
+ community: string;
21
+ aboutPathZh: string;
22
+ aboutPathEn: string;
23
+ }>();
24
+
25
+ const emits = defineEmits<{
26
+ (e: 'update:visible', value: boolean): void;
27
+ }>();
28
+
29
+ const { lePadV } = useScreen();
30
+ const { locale, t } = useI18n();
31
+ const isZh = computed(() => locale.value === 'zh');
32
+
33
+ const cookieKey = computed(() => (isZh.value ? COOKIE_KEY_ZH : COOKIE_KEY_EN));
34
+
35
+ // 是否允许分析cookie
36
+ const analysisAllowed = ref(false);
37
+ const visibleVmodel = useVModel(props, 'visible', emits, { defaultValue: false });
38
+
39
+ const getCookie = (key: string) => {
40
+ const cookie = document.cookie.split(';').find((row) => row.split('=')[0].trim() === encodeURIComponent(key));
41
+ if (!cookie) {
42
+ return null;
43
+ }
44
+ return decodeURIComponent(cookie.split('=')[1]);
45
+ };
46
+
47
+ const setCookie = (key: string, value: string, days: number, domain: string) => {
48
+ const maxAge = days ? `; max-age=${days * 24 * 60 * 60}` : '';
49
+ document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(value)}${maxAge}; path=/; domain=${domain}`;
50
+ };
51
+
52
+ // 显示/隐藏cookie提示
53
+ const toggleNoticeVisible = (val?: boolean) => {
54
+ if (typeof val === 'boolean') {
55
+ visibleVmodel.value = val;
56
+ } else {
57
+ visibleVmodel.value = !visibleVmodel.value;
58
+ }
59
+ nextTick(() => {
60
+ if (!visibleVmodel.value && isZh.value && getCookie(cookieKey.value) !== NOT_SHOW_BUT_AGREED) {
61
+ setCookie(cookieKey.value, NOT_SHOW_BUT_AGREED, 180, COOKIE_DOMAIN ?? location.hostname);
62
+ }
63
+ });
64
+ };
65
+
66
+ // 弹出框是否显示
67
+ const isDlgVisible = ref(false);
68
+
69
+ // 显示/隐藏弹出框
70
+ const toggleDlgVisible = (val?: boolean) => {
71
+ if (typeof val === 'boolean') {
72
+ isDlgVisible.value = val;
73
+ } else {
74
+ isDlgVisible.value = !isDlgVisible.value;
75
+ }
76
+ };
77
+
78
+ // 是否未签署
79
+ const isNotSigned = () => {
80
+ if (isZh.value) {
81
+ return getCookie(cookieKey.value) !== NOT_SHOW_BUT_AGREED;
82
+ }
83
+ return (getCookie(cookieKey.value) ?? '0') === NOT_SIGNED;
84
+ };
85
+
86
+ // 是否全部同意
87
+ const isAllAgreed = () => {
88
+ if (isZh.value) {
89
+ return getCookie(cookieKey.value) === NOT_SHOW_BUT_AGREED;
90
+ }
91
+ return getCookie(cookieKey.value) === ALL_AGREED;
92
+ };
93
+
94
+ onMounted(() => {
95
+ // 未签署,展示cookie notice
96
+ if (isNotSigned()) {
97
+ toggleNoticeVisible(true);
98
+ if (isZh.value && getCookie(cookieKey.value) !== NOT_SHOW_BUT_AGREED) {
99
+ setCookie(cookieKey.value, NOT_SHOW_BUT_AGREED, 180, COOKIE_DOMAIN);
100
+ }
101
+ }
102
+ });
103
+
104
+ // 用户同意所有cookie
105
+ const acceptAll = () => {
106
+ analysisAllowed.value = true;
107
+ setCookie(cookieKey.value, ALL_AGREED, 180, COOKIE_DOMAIN ?? location.hostname);
108
+ toggleNoticeVisible(false);
109
+ };
110
+
111
+ // 用户拒绝所有cookie,即仅同意必要cookie
112
+ const rejectAll = () => {
113
+ analysisAllowed.value = false;
114
+ setCookie(cookieKey.value, NECCESSARY_AGREED, 180, COOKIE_DOMAIN ?? location.hostname);
115
+ toggleNoticeVisible(false);
116
+ };
117
+
118
+ const handleSave = () => {
119
+ if (analysisAllowed.value) {
120
+ acceptAll();
121
+ } else {
122
+ rejectAll();
123
+ }
124
+ toggleDlgVisible(false);
125
+ };
126
+
127
+ const handleAllowAll = () => {
128
+ analysisAllowed.value = true;
129
+ acceptAll();
130
+ toggleDlgVisible(false);
131
+ };
132
+
133
+ const onDlgOpening = () => {
134
+ analysisAllowed.value = isAllAgreed();
135
+ };
136
+ </script>
137
+
138
+ <template>
139
+ <ClientOnly>
140
+ <Teleport to="#app">
141
+ <div v-if="visibleVmodel" class="cookie-notice">
142
+ <div class="cookie-notice-content">
143
+ <div :type="locale" :class="{ 'cookie-notice-wrap-grid': enableGrid, 'cookie-notice-wrap': !enableGrid }">
144
+ <div class="cookie-notice-left">
145
+ <p v-if="isZh" class="cookie-desc" style="margin-top: 0">
146
+ {{ t('cookie.desc') }}
147
+ <a :href="aboutPathZh" target="_blank" rel="noopener noreferrer">
148
+ {{ t('cookie.about') }}
149
+ </a>
150
+ </p>
151
+ <template v-else>
152
+ <p class="cookie-title">{{ t('cookie.title', [community]) }}</p>
153
+ <p class="cookie-desc">
154
+ {{ t('cookie.desc') }}
155
+ <a :href="aboutPathEn" target="_blank" rel="noopener noreferrer">{{ t('cookie.about') }} </a>.
156
+ </p>
157
+ </template>
158
+ </div>
159
+ <div v-if="!isZh" class="cookie-notice-right">
160
+ <el-button round type="primary" @click="acceptAll">{{ t('cookie.acceptAll') }}</el-button>
161
+ <el-button round type="primary" @click="rejectAll">{{ t('cookie.rejectAll') }}</el-button>
162
+ <el-button round type="primary" @click="toggleDlgVisible(true)">{{ t('cookie.manage') }}</el-button>
163
+ </div>
164
+ <el-icon class="cookie-notice-close" :type="locale" @click="toggleNoticeVisible(false)">
165
+ <slot name="close-icon">
166
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="currentColor" d="M764.288 214.592 512 466.88 259.712 214.592a31.936 31.936 0 0 0-45.12 45.12L466.752 512 214.528 764.224a31.936 31.936 0 1 0 45.12 45.184L512 557.184l252.288 252.288a31.936 31.936 0 0 0 45.12-45.12L557.12 512.064l252.288-252.352a31.936 31.936 0 1 0-45.12-45.184z" /></svg>
167
+ </slot>
168
+ </el-icon>
169
+ </div>
170
+ </div>
171
+ <el-dialog v-model="isDlgVisible" :width="lePadV ? '90%' : '50%'" class="cookie-dlg" :title="t('cookie.manage')" destroy-on-close @open="onDlgOpening">
172
+ <div class="cookie-dlg-content">
173
+ <div class="content-item">
174
+ <div class="item-header">
175
+ <span class="item-title">{{ t('cookie.necessaryCookie') }}</span>
176
+ <span class="item-extra">{{ t('cookie.alwaysOn') }}</span>
177
+ </div>
178
+ <div class="item-detail">
179
+ {{ t('cookie.necessaryCookieDetail') }}
180
+ </div>
181
+ </div>
182
+ <div class="content-item">
183
+ <div class="item-header">
184
+ <span class="item-title">{{ t('cookie.analyticalCookie') }}</span>
185
+ <span class="item-extra">
186
+ <el-switch v-model="analysisAllowed" />
187
+ </span>
188
+ </div>
189
+ <div class="item-detail">
190
+ {{ t('cookie.analyticalCookieDetail') }}
191
+ </div>
192
+ </div>
193
+ </div>
194
+ <template #footer>
195
+ <el-button round type="primary" @click="handleSave" style="margin-right: 16px">{{ t('cookie.saveSetting') }}</el-button>
196
+ <el-button round type="primary" @click="handleAllowAll">{{ t('cookie.acceptAll') }}</el-button>
197
+ </template>
198
+ </el-dialog>
199
+ </div>
200
+ </Teleport>
201
+ </ClientOnly>
202
+ </template>
203
+
204
+ <style lang="scss" scoped>
205
+ .el-button {
206
+ --el-button-bg-color: transparent;
207
+ --el-button-text-color: var(--o-color-primary1);
208
+ --el-button-border-color: var(--o-color-primary1);
209
+ --el-button-hover-bg-color: var(--o-color-primary1);
210
+ }
211
+
212
+ .cookie-notice {
213
+ position: fixed;
214
+ bottom: 0;
215
+ z-index: 999;
216
+ width: 100%;
217
+ --el-color-primary: var(--o-color-primary1);
218
+ .o-button {
219
+ --o-button-font-size-mini: 14px;
220
+ }
221
+ .o-button + .o-button {
222
+ margin-left: 16px;
223
+
224
+ @media (max-width: 840px) {
225
+ margin-left: 0;
226
+ margin-top: 12px;
227
+ }
228
+ }
229
+ }
230
+
231
+ .cookie-notice-content {
232
+ background-color: rgba(var(--o-mixedgray-1), 0.9);
233
+ backdrop-filter: blur(5px);
234
+ box-shadow: var(--o-shadow-1);
235
+ }
236
+
237
+ .cookie-notice-wrap {
238
+ position: relative;
239
+ display: flex;
240
+ justify-content: space-between;
241
+ margin: 0 auto;
242
+ padding: 24px var(--layout-content-padding);
243
+ max-width: var(--layout-content-max-width);
244
+ &:not([type='zh']) {
245
+ @media (max-width: 840px) {
246
+ flex-direction: column;
247
+ align-items: center;
248
+ }
249
+ }
250
+ }
251
+
252
+ .cookie-notice-wrap-grid {
253
+ position: relative;
254
+ display: flex;
255
+ justify-content: space-between;
256
+ width: var(--grid-content-width);
257
+ padding: 24px 0;
258
+ margin: 0 auto;
259
+ @media (max-width: 840px) {
260
+ padding: 16px 0;
261
+ flex-direction: column;
262
+ align-items: center;
263
+ }
264
+ }
265
+
266
+ .cookie-notice-left {
267
+ width: 60%;
268
+
269
+ @media (max-width: 1100px) {
270
+ width: 58%;
271
+ }
272
+
273
+ @media (max-width: 840px) {
274
+ width: 100%;
275
+ }
276
+
277
+ .cookie-title {
278
+ font-size: 16px;
279
+ line-height: 28px;
280
+ color: var(--o-color-info1);
281
+ font-weight: 500;
282
+ @media (max-width: 840px) {
283
+ font-size: 16px;
284
+ line-height: 24px;
285
+ text-align: center;
286
+ }
287
+ }
288
+
289
+ .cookie-desc {
290
+ font-size: 12px;
291
+ line-height: 18px;
292
+ color: var(--o-color-info2);
293
+ margin-top: 8px;
294
+ }
295
+ }
296
+
297
+ .cookie-notice-right {
298
+ display: flex;
299
+ align-items: center;
300
+ margin-top: 12px;
301
+
302
+ @media (max-width: 840px) {
303
+ width: 100%;
304
+ }
305
+
306
+ @media (max-width: 840px) {
307
+ flex-direction: column;
308
+ align-items: center;
309
+ }
310
+
311
+ .el-button:not(:first-child) {
312
+ margin-left: 16px;
313
+ }
314
+
315
+ @media (max-width: 840px) {
316
+ .el-button {
317
+ align-self: stretch;
318
+ &:not(:first-child) {
319
+ margin-top: 12px;
320
+ margin-left: 0;
321
+ }
322
+ }
323
+ }
324
+ }
325
+
326
+ .cookie-notice-close {
327
+ &[type='en'] {
328
+ position: absolute;
329
+ top: 16px;
330
+ right: var(--layout-content-padding);
331
+ transform-origin: center;
332
+ }
333
+ cursor: pointer;
334
+ color: var(--o-color-info1);
335
+ font-size: 20px;
336
+ &:hover {
337
+ color: var(--o-color-primary2);
338
+ }
339
+ @media (max-width: 840px) {
340
+ font-size: 14px;
341
+ }
342
+ @include x-svg-hover;
343
+ }
344
+
345
+ .cookie-dlg {
346
+ .cookie-dlg-content {
347
+ .content-item + .content-item {
348
+ margin-top: 24px;
349
+ }
350
+
351
+ .content-item {
352
+ .item-header {
353
+ display: flex;
354
+ align-items: center;
355
+ .item-title {
356
+ font-size: 18px;
357
+ line-height: 32px;
358
+ color: var(--o-color-info1);
359
+ font-weight: 500;
360
+ }
361
+
362
+ .item-extra {
363
+ font-size: 14px;
364
+ line-height: 22px;
365
+ color: var(--o-color-info3);
366
+ margin-left: 24px;
367
+ }
368
+ }
369
+
370
+ .item-detail {
371
+ font-size: 16px;
372
+ line-height: 28px;
373
+ color: var(--o-color-info2);
374
+ margin-top: 12px;
375
+ @media (max-width: 840px) {
376
+ font-size: 14px;
377
+ line-height: 21px;
378
+ margin-top: 8px;
379
+ }
380
+ }
381
+ }
382
+ }
383
+ }
384
+ :deep(.el-dialog) {
385
+ .el-dialog__header {
386
+ text-align: center;
387
+ }
388
+ .el-dialog__title {
389
+ font-size: 32px;
390
+ @media (max-width: 840px) {
391
+ font-size: 22px;
392
+ }
393
+ }
394
+ .el-dialog__footer {
395
+ text-align: center;
396
+ @media (max-width: 840px) {
397
+ .o-button {
398
+ margin: 0 8px;
399
+ }
400
+ }
401
+ }
402
+ }
403
+ </style>