@opendesign-plus/components 0.0.1-rc.2 → 0.0.1-rc.20

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 (203) hide show
  1. package/dist/chunk-OElCookieNotice.cjs.js +1 -0
  2. package/dist/chunk-OElCookieNotice.es.js +839 -0
  3. package/dist/components/OBanner.vue.d.ts +10 -1
  4. package/dist/components/OCookieNotice.vue.d.ts +6 -5
  5. package/dist/components/OFooter.vue.d.ts +46 -0
  6. package/dist/components/OHeaderSearch.vue.d.ts +4 -4
  7. package/dist/components/OHeaderUser.vue.d.ts +40 -0
  8. package/dist/components/OSourceCode.vue.d.ts +20 -0
  9. package/dist/components/activity/OActivityApproval.vue.d.ts +277 -0
  10. package/dist/components/activity/OActivityForm.vue.d.ts +140 -0
  11. package/dist/components/activity/OMyActivityCalendar.vue.d.ts +578 -0
  12. package/dist/components/activity/composables/useActivityConfig.d.ts +17 -0
  13. package/dist/components/activity/config.d.ts +1 -0
  14. package/dist/components/activity/index.d.ts +623 -0
  15. package/dist/components/activity/types.d.ts +81 -0
  16. package/dist/components/element-plus/OElCookieNotice.vue.d.ts +34 -0
  17. package/dist/components/element-plus/index.d.ts +2 -0
  18. package/dist/components/events/OEventsApply.vue.d.ts +16 -0
  19. package/dist/components/events/OEventsCalendar.vue.d.ts +5 -0
  20. package/dist/components/events/OEventsList.vue.d.ts +26 -0
  21. package/dist/components/events/config.d.ts +27 -0
  22. package/dist/components/events/index.d.ts +78 -0
  23. package/dist/components/events/types.d.ts +66 -0
  24. package/dist/components/events/utils.d.ts +7 -0
  25. package/dist/components/header/OHeader.vue.d.ts +30 -0
  26. package/dist/components/header/OHeaderMobile.vue.d.ts +171 -0
  27. package/dist/components/header/components/HeaderContent.vue.d.ts +13 -0
  28. package/dist/components/header/components/HeaderNav.vue.d.ts +19 -0
  29. package/dist/components/header/components/HeaderNavMobile.vue.d.ts +33 -0
  30. package/dist/components/header/index.d.ts +145 -0
  31. package/dist/components/header/types.d.ts +80 -0
  32. package/dist/components/meeting/OMeetingCalendar.vue.d.ts +299 -0
  33. package/dist/components/meeting/OMeetingForm.vue.d.ts +145 -0
  34. package/dist/components/meeting/OMyMeetingCalendar.vue.d.ts +586 -0
  35. package/dist/components/meeting/OSigMeetingCalendar.vue.d.ts +24 -0
  36. package/dist/components/meeting/components/OMeetingCalendarList.vue.d.ts +28 -0
  37. package/dist/components/meeting/components/OMeetingCalendarSelector.vue.d.ts +664 -0
  38. package/dist/components/meeting/components/OMeetingDetail.vue.d.ts +13 -0
  39. package/dist/components/meeting/components/OMeetingPlaybackSubtitles.vue.d.ts +5 -0
  40. package/dist/components/meeting/components/OMeetingPlaybackVideo.vue.d.ts +17 -0
  41. package/dist/components/meeting/components/OSigMeetingAside.vue.d.ts +16 -0
  42. package/dist/components/meeting/composables/useMeetingConfig.d.ts +14 -0
  43. package/dist/components/meeting/config.d.ts +12 -0
  44. package/dist/components/meeting/types.d.ts +168 -0
  45. package/dist/components/meeting/utils.d.ts +8 -0
  46. package/dist/components.cjs.js +224 -1
  47. package/dist/components.css +1 -1
  48. package/dist/components.element.cjs.js +1 -0
  49. package/dist/components.element.es.js +4 -0
  50. package/dist/components.es.js +44348 -785
  51. package/dist/index.d.ts +9 -2
  52. package/docs/design.md +27 -27
  53. package/docs/design_banner.md +41 -41
  54. package/docs/design_section.md +27 -27
  55. package/package.json +12 -3
  56. package/scripts/generate-components-index.js +103 -80
  57. package/src/assets/events/svg-icons/icon-checked.svg +3 -0
  58. package/src/assets/events/svg-icons/icon-competition.svg +7 -0
  59. package/src/assets/events/svg-icons/icon-events.svg +4 -0
  60. package/src/assets/events/svg-icons/icon-release.svg +4 -0
  61. package/src/assets/events/svg-icons/icon-summit.svg +4 -0
  62. package/src/assets/meeting/svg-icons/icon-all.svg +3 -0
  63. package/src/assets/meeting/svg-icons/icon-backward.svg +4 -0
  64. package/src/assets/meeting/svg-icons/icon-calendar.svg +3 -0
  65. package/src/assets/meeting/svg-icons/icon-cancel.svg +4 -0
  66. package/src/assets/meeting/svg-icons/icon-captions.svg +4 -0
  67. package/src/assets/meeting/svg-icons/icon-close-captions.svg +6 -0
  68. package/src/assets/meeting/svg-icons/icon-close-fullscreen.svg +6 -0
  69. package/src/assets/meeting/svg-icons/icon-copy.svg +3 -0
  70. package/src/assets/meeting/svg-icons/icon-create.svg +5 -0
  71. package/src/assets/meeting/svg-icons/icon-delete.svg +7 -0
  72. package/src/assets/meeting/svg-icons/icon-empty.svg +31 -0
  73. package/src/assets/meeting/svg-icons/icon-empty_dark.svg +49 -0
  74. package/src/assets/meeting/svg-icons/icon-event.svg +3 -0
  75. package/src/assets/meeting/svg-icons/icon-export.svg +3 -0
  76. package/src/assets/meeting/svg-icons/icon-forward.svg +4 -0
  77. package/src/assets/meeting/svg-icons/icon-fullscreen.svg +6 -0
  78. package/src/assets/meeting/svg-icons/icon-help.svg +3 -0
  79. package/src/assets/meeting/svg-icons/icon-important.svg +4 -0
  80. package/src/assets/meeting/svg-icons/icon-info.svg +3 -0
  81. package/src/assets/meeting/svg-icons/icon-meet.svg +3 -0
  82. package/src/assets/meeting/svg-icons/icon-meeting-message.svg +5 -0
  83. package/src/assets/meeting/svg-icons/icon-meeting.svg +4 -0
  84. package/src/assets/meeting/svg-icons/icon-play.svg +5 -0
  85. package/src/assets/meeting/svg-icons/icon-playing-tip.svg +7 -0
  86. package/src/assets/meeting/svg-icons/icon-playing.svg +5 -0
  87. package/src/assets/meeting/svg-icons/icon-question.svg +4 -0
  88. package/src/assets/meeting/svg-icons/icon-sound.svg +5 -0
  89. package/src/assets/meeting/svg-icons/icon-speaker.svg +3 -0
  90. package/src/assets/meeting/svg-icons/icon-summit.svg +3 -0
  91. package/src/assets/meeting/svg-icons/icon-telligent.svg +3 -0
  92. package/src/assets/meeting/svg-icons/icon-tip.svg +3 -0
  93. package/src/assets/meeting/svg-icons/icon-todo.svg +4 -0
  94. package/src/assets/meeting/transparent.png +0 -0
  95. package/src/assets/svg-icons/icon-arrow-left.svg +3 -0
  96. package/src/assets/svg-icons/icon-avatar-line.svg +3 -0
  97. package/src/assets/svg-icons/icon-caret-left.svg +3 -0
  98. package/src/assets/svg-icons/icon-caret-right.svg +3 -0
  99. package/src/assets/svg-icons/icon-chevron-down.svg +3 -0
  100. package/src/assets/svg-icons/icon-chevron-right.svg +3 -3
  101. package/src/assets/svg-icons/icon-chevron-up.svg +3 -0
  102. package/src/assets/svg-icons/icon-close.svg +3 -3
  103. package/src/assets/svg-icons/icon-delete.svg +3 -3
  104. package/src/assets/svg-icons/icon-filter.svg +3 -0
  105. package/src/assets/svg-icons/icon-header-back.svg +3 -3
  106. package/src/assets/svg-icons/icon-header-delete.svg +3 -3
  107. package/src/assets/svg-icons/icon-header-menu.svg +3 -0
  108. package/src/assets/svg-icons/icon-header-person.svg +3 -0
  109. package/src/assets/svg-icons/icon-header-search.svg +4 -4
  110. package/src/assets/svg-icons/icon-loading.svg +4 -0
  111. package/src/assets/svg-icons/icon-locale.svg +3 -0
  112. package/src/assets/svg-icons/icon-log-off.svg +3 -0
  113. package/src/assets/svg-icons/icon-message.svg +3 -0
  114. package/src/assets/svg-icons/icon-moon.svg +3 -3
  115. package/src/assets/svg-icons/icon-outlink.svg +3 -0
  116. package/src/assets/svg-icons/icon-overview.svg +3 -0
  117. package/src/assets/svg-icons/icon-search.svg +3 -0
  118. package/src/assets/svg-icons/icon-setting.svg +3 -0
  119. package/src/assets/svg-icons/icon-sun.svg +3 -3
  120. package/src/assets/svg-icons/icon-tips.svg +3 -0
  121. package/src/components/OBanner.vue +398 -390
  122. package/src/components/OCookieNotice.vue +575 -424
  123. package/src/components/OFooter.vue +576 -0
  124. package/src/components/OHeaderSearch.vue +601 -601
  125. package/src/components/OHeaderUser.vue +237 -0
  126. package/src/components/OPlusConfigProvider.vue +32 -32
  127. package/src/components/OSection.vue +178 -178
  128. package/src/components/OSourceCode.vue +153 -0
  129. package/src/components/OThemeSwitcher.vue +108 -108
  130. package/src/components/activity/OActivityApproval.vue +864 -0
  131. package/src/components/activity/OActivityForm.vue +542 -0
  132. package/src/components/activity/OMyActivityCalendar.vue +1486 -0
  133. package/src/components/activity/composables/useActivityConfig.ts +141 -0
  134. package/src/components/activity/config.ts +1 -0
  135. package/src/components/activity/index.ts +24 -0
  136. package/src/components/activity/types.ts +88 -0
  137. package/src/components/common/AppAvatar.vue +83 -0
  138. package/src/components/common/ClientOnlyWrapper.ts +21 -21
  139. package/src/components/common/ContentWrapper.vue +85 -85
  140. package/src/components/common/MoreText.vue +124 -0
  141. package/src/components/common/ThFilter.vue +330 -0
  142. package/src/components/element-plus/OElCookieNotice.vue +603 -0
  143. package/src/components/element-plus/index.ts +3 -0
  144. package/src/components/events/OEventsApply.vue +418 -0
  145. package/src/components/events/OEventsCalendar.vue +598 -0
  146. package/src/components/events/OEventsList.vue +362 -0
  147. package/src/components/events/config.ts +35 -0
  148. package/src/components/events/index.ts +24 -0
  149. package/src/components/events/types.ts +80 -0
  150. package/src/components/events/utils.ts +9 -0
  151. package/src/components/header/OHeader.vue +157 -0
  152. package/src/components/header/OHeaderMobile.vue +177 -0
  153. package/src/components/header/components/HeaderContent.vue +1121 -0
  154. package/src/components/header/components/HeaderNav.vue +278 -0
  155. package/src/components/header/components/HeaderNavMobile.vue +377 -0
  156. package/src/components/header/index.ts +16 -0
  157. package/src/components/header/types.ts +91 -0
  158. package/src/components/meeting/OMeetingCalendar.vue +878 -0
  159. package/src/components/meeting/OMeetingForm.vue +1053 -0
  160. package/src/components/meeting/OMeetingPlayback.vue +439 -0
  161. package/src/components/meeting/OMyMeetingCalendar.vue +1497 -0
  162. package/src/components/meeting/OSigMeetingCalendar.vue +410 -0
  163. package/src/components/meeting/components/OMeetingCalendarList.vue +510 -0
  164. package/src/components/meeting/components/OMeetingCalendarSelector.vue +206 -0
  165. package/src/components/meeting/components/OMeetingDetail.vue +229 -0
  166. package/src/components/meeting/components/OMeetingPlaybackSubtitles.vue +611 -0
  167. package/src/components/meeting/components/OMeetingPlaybackVideo.vue +741 -0
  168. package/src/components/meeting/components/OSigMeetingAside.vue +200 -0
  169. package/src/components/meeting/composables/useMeetingConfig.ts +108 -0
  170. package/src/components/meeting/config.ts +48 -0
  171. package/src/components/meeting/index.ts +45 -0
  172. package/src/components/meeting/types.ts +195 -0
  173. package/src/components/meeting/utils.ts +70 -0
  174. package/src/draft/Banner.vue +265 -265
  175. package/src/draft/ButtonCards.vue +105 -105
  176. package/src/draft/Feature.vue +133 -133
  177. package/src/draft/Footer.vue +512 -512
  178. package/src/draft/HorizontalAnchor.vue +165 -165
  179. package/src/draft/ItemSwiper.vue +133 -133
  180. package/src/draft/Logo.vue +141 -141
  181. package/src/draft/LogoCard.vue +74 -74
  182. package/src/draft/LogoV2.vue +19 -19
  183. package/src/draft/MainCard.vue +38 -38
  184. package/src/draft/MultiCard.vue +94 -94
  185. package/src/draft/MultiIconCard.vue +73 -73
  186. package/src/draft/OInfoCard.vue +176 -176
  187. package/src/draft/Process.vue +81 -81
  188. package/src/draft/Section.vue +167 -167
  189. package/src/draft/SingleTabCard.vue +84 -84
  190. package/src/draft/SliderCard.vue +110 -110
  191. package/src/env.d.ts +16 -1
  192. package/src/i18n/en.ts +264 -20
  193. package/src/i18n/index.ts +56 -42
  194. package/src/i18n/zh.ts +253 -9
  195. package/src/index.ts +14 -3
  196. package/src/shared/provide.ts +6 -6
  197. package/src/shims-vue-dompurify-html.d.ts +17 -0
  198. package/src/vue.d.ts +9 -9
  199. package/tsconfig.json +37 -33
  200. package/vite.config.ts +118 -94
  201. package/dist/components/OCookieNoticeEl.vue.d.ts +0 -29
  202. package/dist/components.umd.js +0 -1
  203. package/src/components/OCookieNoticeEl.vue +0 -404
@@ -0,0 +1,278 @@
1
+ <script setup lang="ts">
2
+ import { ref, onMounted, onUnmounted, nextTick } from 'vue';
3
+ import { OIcon, OTag } from '@opensig/opendesign';
4
+
5
+ import IconCaretLeft from '~icons/components/icon-caret-left.svg';
6
+ import IconCaretRight from '~icons/components/icon-caret-right.svg';
7
+
8
+ import { type NavLiT } from '../types.ts';
9
+
10
+ import { useTheme } from '@opendesign-plus/composables';
11
+
12
+ import { useDebounceFn } from '@vueuse/core';
13
+
14
+ export interface OHeaderEmitsT {
15
+ (e: 'handle-mouseenter', val: any): void;
16
+ (e: 'handle-mouseleave', val: any): void;
17
+ (e: 'handle-click', val: any): void;
18
+ }
19
+
20
+ const emit = defineEmits<OHeaderEmitsT>();
21
+ const { isDark } = useTheme();
22
+
23
+ const props = defineProps<NavLiT>();
24
+
25
+ const navRef = ref();
26
+ const navListRef = ref();
27
+ const resizeTimer = ref(null);
28
+ const navVisibleRight = ref(false);
29
+ const navVisibleLeft = ref(false);
30
+
31
+ const hoverIndex = ref();
32
+
33
+ const toggleDebounced = useDebounceFn((item: any | null, id: string) => {
34
+ hoverIndex.value = item?.id;
35
+ if (id === 'mouseenter') {
36
+ emit('handle-mouseenter', item);
37
+ }
38
+ if (id === 'mouseleave') {
39
+ hoverIndex.value = '';
40
+ emit('handle-mouseleave', item);
41
+ }
42
+ }, 100);
43
+
44
+ const handleClick = (item: any) => {
45
+ emit('handle-click', item);
46
+ };
47
+
48
+ const scrollNavRight = () => {
49
+ navVisibleLeft.value = true;
50
+ nextTick(() => {
51
+ navRef.value.scrollTo({
52
+ left: navRef.value.clientWidth,
53
+ behavior: 'smooth',
54
+ });
55
+ });
56
+ };
57
+ const scrollNavLeft = () => {
58
+ navRef.value.scrollTo({
59
+ left: 0,
60
+ behavior: 'smooth',
61
+ });
62
+ navVisibleLeft.value = false;
63
+ };
64
+
65
+ const calculateLayout = () => {
66
+ if (navRef.value?.clientWidth < navListRef.value?.clientWidth) {
67
+ navVisibleRight.value = true;
68
+ } else {
69
+ navVisibleRight.value = false;
70
+ }
71
+ };
72
+
73
+ // ------------导航埋点------------
74
+ // 首次hover时间
75
+ let hoverTime = 0;
76
+ // 最终点击导航所用步骤
77
+ let steps = 0;
78
+
79
+ const onHoverHeader = () => (steps = 0);
80
+
81
+ const onHoverNav = (name: string) => {
82
+ if (steps > 0) return void steps++;
83
+ steps++;
84
+ hoverTime = Date.now();
85
+ return {
86
+ event: 'hover',
87
+ properties: {
88
+ module: 'navigation',
89
+ level1: name,
90
+ target: name,
91
+ },
92
+ };
93
+ };
94
+
95
+ const onClickNavItem = (item: any) => {
96
+ const res = {
97
+ properties: {
98
+ module: 'navigation',
99
+ level1: item.label,
100
+ target: item.label,
101
+ steps: steps,
102
+ url: item.href,
103
+ duration: Date.now() - hoverTime,
104
+ },
105
+ };
106
+ return res;
107
+ };
108
+
109
+ onMounted(() => {
110
+ window.addEventListener('resize', calculateLayout);
111
+ // 确保 DOM 完全渲染后再计算
112
+ nextTick(() => {
113
+ calculateLayout();
114
+ resizeTimer.value = setTimeout(() => {
115
+ calculateLayout();
116
+ }, 1000);
117
+ });
118
+ });
119
+
120
+ // 清理
121
+ onUnmounted(() => {
122
+ window.removeEventListener('resize', calculateLayout);
123
+ clearTimeout(resizeTimer.value);
124
+ });
125
+ </script>
126
+
127
+ <template>
128
+ <div class="header-nav-wrap">
129
+ <div class="header-nav" :class="{ 'header-nav-scroll': navVisibleLeft }">
130
+ <div class="right-icon" v-if="navVisibleLeft">
131
+ <OIcon @click="scrollNavLeft"><IconCaretLeft /></OIcon>
132
+ </div>
133
+ <div ref="navRef" class="o-nav" :class="{ 'o-nav-scroll': navVisibleLeft || !navVisibleRight, dark: isDark }">
134
+ <ul ref="navListRef" class="o-nav-list" @mouseenter="onHoverHeader">
135
+ <li
136
+ v-for="(item, idx) in navData"
137
+ :key="item.id"
138
+ :class="{
139
+ 'is-selected': hoverIndex === item.id || props.hoverId === item.id,
140
+ 'is-active': props.activeIndex === idx,
141
+ }"
142
+ @mouseenter="toggleDebounced(item, 'mouseenter')"
143
+ @mouseleave="toggleDebounced(item, 'mouseleave')"
144
+ v-analytics:mouseenter="onHoverNav(item.label)"
145
+ v-analytics.catchBubble="onClickNavItem(item)"
146
+ >
147
+ <div v-if="item?.children?.length" :id="'tour_headerNav_' + item.id" class="nav-item">
148
+ <span class="nav-text">{{ item.label }}</span>
149
+ </div>
150
+ <div v-else :id="'tour_headerNav_' + item.id" class="nav-item item-other" @click="handleClick(item)">
151
+ <span class="nav-text">{{ item.label }}</span>
152
+ <OTag v-if="item.tag" round="pill" color="danger" size="small" class="content-tag">{{ item.tag }}</OTag>
153
+ </div>
154
+ </li>
155
+ </ul>
156
+ </div>
157
+ <div class="right-icon" v-if="navVisibleRight && !navVisibleLeft">
158
+ <OIcon @click="scrollNavRight"><IconCaretRight /></OIcon>
159
+ </div>
160
+ </div>
161
+ </div>
162
+ </template>
163
+
164
+ <style lang="scss" scoped>
165
+ .header-nav-wrap {
166
+ height: 100%;
167
+ .header-nav {
168
+ height: 100%;
169
+ display: flex;
170
+ justify-content: space-between;
171
+ width: calc(100% - 64px);
172
+ align-items: center;
173
+ }
174
+ .header-nav-scroll {
175
+ width: calc(100% - 64px - 24px);
176
+ }
177
+ }
178
+ .o-nav {
179
+ height: 100%;
180
+ position: relative;
181
+ overflow-y: hidden;
182
+ overflow-x: auto;
183
+ &::after {
184
+ content: '';
185
+ position: absolute;
186
+ width: 50px;
187
+ height: 100%;
188
+ right: 0;
189
+ top: 0;
190
+ background-image: linear-gradient(90deg, rgba(var(--o-mixedgray-1), 0) 0%, rgba(var(--o-mixedgray-1), 1) 100%);
191
+ z-index: 0;
192
+ }
193
+ &::-webkit-scrollbar {
194
+ display: none;
195
+ }
196
+ &.dark {
197
+ &::after {
198
+ background-image: linear-gradient(90deg, rgba(var(--o-mixedgray-4), 0) 0%, rgba(var(--o-mixedgray-4), 1) 100%);
199
+ }
200
+ }
201
+ }
202
+ .o-nav-scroll {
203
+ &::after {
204
+ display: none;
205
+ }
206
+ }
207
+ .o-nav-list {
208
+ display: flex;
209
+ height: 100%;
210
+ width: fit-content;
211
+ flex-wrap: nowrap;
212
+ white-space: nowrap;
213
+ padding: 0;
214
+ margin: 0;
215
+ li {
216
+ position: relative;
217
+ display: flex;
218
+ align-items: center;
219
+ height: 100%;
220
+ color: var(--o-color-info1);
221
+ transition: all var(--o-duration-s) var(--o-easing-standard);
222
+ .nav-text {
223
+ position: relative;
224
+ &::after {
225
+ content: '';
226
+ position: absolute;
227
+ left: 0;
228
+ opacity: 0;
229
+ bottom: -24px;
230
+ width: 100%;
231
+ height: 2px;
232
+ border-radius: 1px;
233
+ background: var(--o-color-primary1);
234
+ transition: all var(--o-duration-s) var(--o-easing-standard);
235
+ }
236
+ }
237
+ &.is-selected,
238
+ &.is-active {
239
+ .nav-text {
240
+ color: var(--o-color-primary1);
241
+ z-index: 99;
242
+ font-weight: 500;
243
+ &::after {
244
+ content: '';
245
+ opacity: 1;
246
+ }
247
+ }
248
+ }
249
+ }
250
+
251
+ .nav-item {
252
+ cursor: default;
253
+ display: flex;
254
+ align-items: center;
255
+ padding: 22px var(--o-gap-4);
256
+ @include text1;
257
+
258
+ @include respond-to('laptop') {
259
+ padding: 22px 12px;
260
+ }
261
+ @include respond-to('pad_h') {
262
+ padding: 22px 8px;
263
+ }
264
+ &.en {
265
+ @media (min-width: 841px) and (max-width: 1000px) {
266
+ padding: var(--o-gap-2);
267
+ }
268
+ }
269
+ }
270
+ .item-other {
271
+ cursor: pointer;
272
+ .content-tag {
273
+ margin-left: var(--o-gap-2);
274
+ --layout-pkg-radius: var(--o-radius-xs);
275
+ }
276
+ }
277
+ }
278
+ </style>
@@ -0,0 +1,377 @@
1
+ <script lang="ts" setup>
2
+ import { ref, onMounted, watch } from 'vue';
3
+ import { OIcon, OTag } from '@opensig/opendesign';
4
+
5
+ import { type NavMobileItemT, NavType } from '../types.ts';
6
+
7
+ export interface OHeaderEmitsT {
8
+ (e: 'on-click'): void;
9
+ (e: 'handle-click', val: any): void;
10
+ }
11
+ const emit = defineEmits<OHeaderEmitsT>();
12
+
13
+ const props = withDefaults(defineProps<NavMobileItemT>(), {
14
+ menuShow: false,
15
+ navData: () => [],
16
+ codeData: () => [],
17
+ langData: () => [],
18
+ });
19
+
20
+ const navActive = ref('');
21
+ const navInfo = ref({});
22
+
23
+ const handleNavClick = (item: any, val?: string) => {
24
+ if (val === NavType.NAV) {
25
+ if (item?.children?.length) {
26
+ navActive.value = item.id;
27
+ navInfo.value = item;
28
+ } else {
29
+ emit('handle-click', item);
30
+ }
31
+ } else if (val === NavType.CODE) {
32
+ navActive.value = val;
33
+ navInfo.value = props.codeData.list;
34
+ } else if (val === NavType.LANG) {
35
+ navActive.value = val;
36
+ navInfo.value = props.langData.list;
37
+ }
38
+ };
39
+
40
+ const onClick = (url: string, target?: string) => {
41
+ window.open(url, target ? target : '_self');
42
+ emit('on-click');
43
+ };
44
+
45
+ const onClickNav = (val: any) => {
46
+ if (navActive.value === NavType.CODE) {
47
+ onClick(val.href, val?.target);
48
+ }
49
+ };
50
+
51
+ onMounted(() => {
52
+ navActive.value = props.navData[0].id;
53
+ navInfo.value = props.navData[0];
54
+ });
55
+
56
+ watch(
57
+ () => props.navData || props.codeData || props.langData,
58
+ () => {
59
+ if (navActive.value === NavType.CODE) {
60
+ navInfo.value = props.codeData.list;
61
+ } else if (navActive.value === NavType.LANG) {
62
+ navInfo.value = props.langData.list;
63
+ } else {
64
+ navInfo.value = props.navData.find((item) => item.id === navActive.value);
65
+ }
66
+ },
67
+ {
68
+ deep: true,
69
+ }
70
+ );
71
+ </script>
72
+
73
+ <template>
74
+ <div class="header-nav" :class="{ active: menuShow }">
75
+ <div class="o-nav">
76
+ <ul class="o-nav-list">
77
+ <li
78
+ v-for="item in navData"
79
+ :key="item.id"
80
+ :class="{
81
+ active: navActive === item.id,
82
+ }"
83
+ >
84
+ <span @click="handleNavClick(item, 'nav')">{{ item.label }}</span>
85
+ </li>
86
+ </ul>
87
+ <div class="nav-aside">
88
+ <ul v-if="navActive !== 'code' && navActive !== 'lang'" class="nav-aside-wrapper">
89
+ <li v-for="item in navInfo.children" :value="item.label" :key="item.label" class="nav-aside-content">
90
+ <template v-if="item?.children">
91
+ <p class="content-label">{{ item.label }}</p>
92
+ <div class="container-mobile">
93
+ <div v-for="subItem in item?.children" :key="subItem.label" class="content-container-mobile">
94
+ <a @click="onClick(subItem.href, subItem?.target)" rel="noopener noreferrer" class="content-subtitle">
95
+ <span class="item-label">{{ subItem.label }}</span>
96
+ <OIcon v-if="subItem.icon">
97
+ <component :is="subItem.icon" class="icon" />
98
+ </OIcon>
99
+ <OTag v-if="subItem.tag" round="pill" color="danger" size="small" class="content-tag">{{ subItem.tag }}</OTag>
100
+ </a>
101
+ <div class="desc-container">
102
+ <p class="item-desc">{{ subItem.description }}</p>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ </template>
107
+ <template v-else>
108
+ <a @click="onClick(item.href, item?.target)" rel="noopener noreferrer" class="content-subtitle item-not-children">
109
+ <span class="item-label">{{ item.label }}</span>
110
+ <OIcon v-if="item.icon">
111
+ <component :is="item.icon" class="icon" />
112
+ </OIcon>
113
+ <OTag v-if="item.tag" round="pill" color="danger" size="small">{{ item.tag }}</OTag>
114
+ </a>
115
+ </template>
116
+ </li>
117
+ </ul>
118
+ <div v-else class="nav-aside-wrapper">
119
+ <a v-for="item in navInfo" :key="item.label" @click="onClickNav(item)" class="source-code-item">
120
+ <span>{{ item.label }}</span>
121
+ <OIcon v-if="item.icon">
122
+ <component :is="item.icon" class="icon" />
123
+ </OIcon>
124
+ </a>
125
+ </div>
126
+ </div>
127
+ </div>
128
+ <!-- 移动端 tool -->
129
+ <div class="header-tool">
130
+ <!-- 源码 -->
131
+ <div
132
+ v-if="codeData"
133
+ class="header-tool-item"
134
+ @click="handleNavClick(null, 'code')"
135
+ :class="{
136
+ active: navActive === 'code',
137
+ }"
138
+ >
139
+ {{ codeData.label }}
140
+ </div>
141
+ <div
142
+ v-if="langData"
143
+ class="header-tool-item"
144
+ @click="handleNavClick(null, 'lang')"
145
+ :class="{
146
+ active: navActive === 'lang',
147
+ }"
148
+ >
149
+ {{ langData.label }}
150
+ </div>
151
+ <!-- 语言 -->
152
+ <div v-if="$slots.tool" class="other-tool">
153
+ <slot name="tool"></slot>
154
+ </div>
155
+ </div>
156
+ </div>
157
+ </template>
158
+
159
+ <style lang="scss" scoped>
160
+ @mixin nav-item {
161
+ display: flex;
162
+ align-items: center;
163
+ justify-content: center;
164
+ height: 48px;
165
+ color: var(--o-color-info1);
166
+
167
+ &.active {
168
+ color: var(--o-color-primary1);
169
+ background: var(--o-color-fill2);
170
+ font-weight: 500;
171
+ }
172
+ }
173
+
174
+ .header-nav {
175
+ flex: 1;
176
+ justify-content: space-between;
177
+ width: 100%;
178
+ overflow: hidden;
179
+ height: 100%;
180
+ background-color: var(--o-color-fill2);
181
+ transform: translateX(-130%);
182
+
183
+ transition-duration: 0.333s;
184
+ transition-property: all;
185
+ transition-timing-function: cubic-bezier(0.5, 0, 0.84, 0.25);
186
+ display: block;
187
+ opacity: 0;
188
+
189
+ &.active {
190
+ opacity: 1;
191
+ visibility: visible;
192
+ transform: translateX(0);
193
+ }
194
+ }
195
+
196
+ .o-nav {
197
+ height: 100%;
198
+ position: relative;
199
+ width: 99px;
200
+ background: var(--o-color-fill1);
201
+ display: flex;
202
+ flex-direction: column;
203
+ justify-content: space-between;
204
+
205
+ .o-nav-list {
206
+ padding: 0;
207
+ margin: 0;
208
+ height: auto;
209
+
210
+ > li {
211
+ position: relative;
212
+ text-align: center;
213
+ @include text2;
214
+ @include nav-item;
215
+ }
216
+ }
217
+ }
218
+
219
+ .nav-aside {
220
+ position: fixed;
221
+ background-color: var(--o-color-fill2);
222
+ top: 0;
223
+ left: 0;
224
+ width: calc(100% - 99px);
225
+ transform: translateX(99px);
226
+ height: 100%;
227
+ z-index: 190;
228
+ .nav-aside-wrapper {
229
+ overflow-y: auto;
230
+ padding: 16px 12px 32px;
231
+ height: 100%;
232
+ .nav-aside-content {
233
+ display: block;
234
+ flex: 0 1 auto;
235
+
236
+ & + .nav-aside-content {
237
+ position: relative;
238
+ padding-top: var(--o-gap-3);
239
+ &::before {
240
+ content: '';
241
+ position: absolute;
242
+ top: 0;
243
+ width: 100%;
244
+ height: 1px;
245
+ background-color: rgba(var(--o-mixedgray-14), 0.1);
246
+ }
247
+ }
248
+ .content-label {
249
+ color: var(--o-color-info3);
250
+ @include text2;
251
+ }
252
+
253
+ .item-not-children {
254
+ margin-bottom: 12px;
255
+ display: flex;
256
+ align-items: center;
257
+ .o-tag {
258
+ margin-left: var(--o-gap-2);
259
+ --layout-pkg-radius: 100vh;
260
+ }
261
+ .o-icon {
262
+ margin-left: var(--o-gap-2);
263
+ }
264
+ }
265
+ }
266
+
267
+ .source-code-item {
268
+ height: 40px;
269
+ display: flex;
270
+ align-items: center;
271
+ color: var(--o-color-info1);
272
+
273
+ &.active {
274
+ color: var(--o-color-primary1);
275
+ }
276
+
277
+ & + .source-code-item {
278
+ border-top: 1px solid var(--o-color-control4);
279
+ }
280
+
281
+ .icon {
282
+ margin-left: var(--o-gap-2);
283
+ }
284
+ }
285
+
286
+ &::-webkit-scrollbar-track {
287
+ border-radius: 3px;
288
+ }
289
+
290
+ &::-webkit-scrollbar {
291
+ width: 6px;
292
+ background-color: transparent;
293
+ }
294
+
295
+ &::-webkit-scrollbar-thumb {
296
+ border-radius: 3px;
297
+ background: var(--o-color-control1);
298
+ }
299
+ }
300
+
301
+ .container-mobile {
302
+ @include text2;
303
+
304
+ .o-icon {
305
+ --icon-size: 16px;
306
+ margin-left: var(--o-gap-2);
307
+ }
308
+ }
309
+
310
+ .content-container-mobile {
311
+ margin-top: var(--o-gap-3);
312
+
313
+ &:first-child {
314
+ margin-top: 8px;
315
+ }
316
+ &:last-child {
317
+ margin-bottom: 12px;
318
+ }
319
+
320
+ .content-subtitle {
321
+ color: var(--o-color-info1);
322
+ display: flex;
323
+ align-items: center;
324
+ @include text2;
325
+ }
326
+
327
+ .content-tag {
328
+ margin-left: var(--o-gap-2);
329
+ --layout-pkg-radius: var(--o-radius-xs);
330
+ }
331
+
332
+ .desc-container {
333
+ overflow: hidden;
334
+ position: relative;
335
+
336
+ .item-desc {
337
+ color: var(--o-color-info2);
338
+ margin-top: var(--o-gap-1);
339
+ text-align: justify;
340
+ word-break: normal;
341
+ @include tip1;
342
+ @include text-truncate(2);
343
+ @include respond-to('phone') {
344
+ @include text1;
345
+ }
346
+ }
347
+ }
348
+ }
349
+ }
350
+
351
+ .header-tool {
352
+ position: absolute;
353
+ bottom: 36px;
354
+ left: 0;
355
+ width: 99px;
356
+
357
+ display: flex;
358
+ height: auto;
359
+ justify-content: center;
360
+ align-items: center;
361
+ flex-direction: column;
362
+ }
363
+
364
+ .header-tool-item {
365
+ width: 99px;
366
+ @include nav-item;
367
+ @include tip1;
368
+ @include respond-to('phone') {
369
+ @include text1;
370
+ }
371
+ }
372
+ .other-tool {
373
+ width: 99px;
374
+ margin-top: 8px;
375
+ text-align: center;
376
+ }
377
+ </style>
@@ -0,0 +1,16 @@
1
+ import _OHeader from './OHeader.vue';
2
+ import _OHeaderMobile from './OHeaderMobile.vue';
3
+ import type { App } from 'vue';
4
+
5
+ const OHeader = Object.assign(_OHeader, {
6
+ install(app: App) {
7
+ app.component('OHeader', _OHeader);
8
+ },
9
+ });
10
+ const OHeaderMobile = Object.assign(_OHeaderMobile, {
11
+ install(app: App) {
12
+ app.component('OHeaderMobile', _OHeaderMobile);
13
+ },
14
+ });
15
+
16
+ export { OHeader, OHeaderMobile };