@opendesign-plus/components 0.0.1-rc.24 → 0.0.1-rc.26

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 (80) hide show
  1. package/dist/chunk-OElCookieNotice.cjs.js +1 -1
  2. package/dist/chunk-OElCookieNotice.es.js +111 -88
  3. package/dist/components/OHeaderSearch.vue.d.ts +814 -534
  4. package/dist/components/OHeaderUser.vue.d.ts +1 -1
  5. package/dist/components/OLanguageSwitcher.vue.d.ts +49 -0
  6. package/dist/components/OThemeSwitcher.vue.d.ts +2 -5
  7. package/dist/components/activity/OActivityMyCalendar.vue.d.ts +4 -4
  8. package/dist/components/activity/index.d.ts +2 -2
  9. package/dist/components/banner/OBanner.vue.d.ts +13 -0
  10. package/dist/components/banner/OBannerContent.vue.d.ts +7 -0
  11. package/dist/components/banner/index.d.ts +68 -0
  12. package/dist/components/banner/types.d.ts +31 -0
  13. package/dist/components/meeting/OMeetingCalendar.vue.d.ts +5 -3
  14. package/dist/components/meeting/OMeetingMyCalendar.vue.d.ts +4 -4
  15. package/dist/components/meeting/OMeetingPlayback.vue.d.ts +50 -1
  16. package/dist/components/meeting/components/OMeetingCalendarSelector.vue.d.ts +1 -1
  17. package/dist/components/meeting/components/OMeetingPlaybackSubtitles.vue.d.ts +16 -1
  18. package/dist/components/meeting/composables/useMeetingConfig.d.ts +1 -1
  19. package/dist/components/meeting/index.d.ts +347 -20
  20. package/dist/components/meeting/types.d.ts +1 -1
  21. package/dist/components/search/OSearchInput.vue.d.ts +1005 -0
  22. package/dist/components/search/composables/useImageSearch.d.ts +48 -0
  23. package/dist/components/search/composables/useKeywordHighlight.d.ts +2 -0
  24. package/dist/components/search/composables/useSearchHistory.d.ts +14 -0
  25. package/dist/components/search/index.d.ts +590 -0
  26. package/dist/components/search/internal/HighlightText.vue.d.ts +9 -0
  27. package/dist/components/search/internal/SearchImageInput.vue.d.ts +716 -0
  28. package/dist/components/search/internal/SearchPanel.vue.d.ts +100 -0
  29. package/dist/components/search/types.d.ts +20 -0
  30. package/dist/components.cjs.js +40 -40
  31. package/dist/components.css +1 -1
  32. package/dist/components.es.js +11352 -10056
  33. package/dist/index.d.ts +4 -2
  34. package/package.json +4 -4
  35. package/scripts/generate-components-index.js +1 -1
  36. package/src/assets/styles/element-plus.scss +16 -9
  37. package/src/assets/svg-icons/icon-delete-hover.svg +4 -0
  38. package/src/assets/svg-icons/icon-delete.svg +5 -1
  39. package/src/assets/svg-icons/icon-image-close.svg +4 -0
  40. package/src/assets/svg-icons/icon-image-upload.svg +3 -0
  41. package/src/assets/svg-icons/icon-image-zoomin.svg +3 -0
  42. package/src/assets/svg-icons/icon-refresh.svg +3 -0
  43. package/src/components/OHeaderSearch.vue +445 -418
  44. package/src/components/OLanguageSwitcher.vue +211 -0
  45. package/src/components/OPlusConfigProvider.vue +2 -2
  46. package/src/components/OThemeSwitcher.vue +51 -27
  47. package/src/components/activity/OActivityForm.vue +7 -3
  48. package/src/components/activity/OActivityMyCalendar.vue +16 -7
  49. package/src/components/banner/OBanner.vue +288 -0
  50. package/src/components/banner/OBannerContent.vue +175 -0
  51. package/src/components/banner/index.ts +18 -0
  52. package/src/components/banner/types.ts +39 -0
  53. package/src/components/header/OHeader.vue +1 -1
  54. package/src/components/meeting/OMeetingCalendar.vue +11 -6
  55. package/src/components/meeting/OMeetingForm.vue +55 -9
  56. package/src/components/meeting/OMeetingMyCalendar.vue +17 -14
  57. package/src/components/meeting/OMeetingPlayback.vue +10 -4
  58. package/src/components/meeting/OMeetingSigCalendar.vue +1 -1
  59. package/src/components/meeting/components/OMeetingCalendarList.vue +57 -21
  60. package/src/components/meeting/components/OMeetingCalendarSelector.vue +11 -8
  61. package/src/components/meeting/components/OMeetingDetail.vue +1 -1
  62. package/src/components/meeting/components/OMeetingPlaybackSubtitles.vue +7 -4
  63. package/src/components/meeting/composables/useMeetingConfig.ts +5 -5
  64. package/src/components/meeting/index.ts +2 -2
  65. package/src/components/meeting/types.ts +1 -1
  66. package/src/components/search/OSearchInput.vue +526 -0
  67. package/src/components/search/composables/useImageSearch.ts +157 -0
  68. package/src/components/search/composables/useKeywordHighlight.ts +30 -0
  69. package/src/components/search/composables/useSearchHistory.ts +75 -0
  70. package/src/components/search/index.ts +23 -0
  71. package/src/components/search/internal/HighlightText.vue +37 -0
  72. package/src/components/search/internal/SearchImageInput.vue +498 -0
  73. package/src/components/search/internal/SearchPanel.vue +431 -0
  74. package/src/components/search/types.ts +25 -0
  75. package/src/i18n/en.ts +13 -1
  76. package/src/i18n/zh.ts +14 -3
  77. package/src/index.ts +5 -3
  78. package/vite.config.ts +4 -0
  79. package/dist/components/OBanner.vue.d.ts +0 -11
  80. package/src/components/OBanner.vue +0 -398
@@ -0,0 +1,288 @@
1
+ <script setup lang="ts">
2
+ import { OCarousel, OCarouselItem, OFigure } from '@opensig/opendesign';
3
+ import { computed } from 'vue';
4
+
5
+ import { useScreen, useTheme } from '@opendesign-plus/composables';
6
+ import ContentWrapper from '../common/ContentWrapper.vue';
7
+ import BannerContent from './OBannerContent.vue';
8
+ import type { BannerItem } from './types';
9
+
10
+ const props = defineProps<{
11
+ options?: BannerItem | BannerItem[];
12
+ size?: 'large' | 'medium' | 'small' | 'tiny';
13
+ contentJustifyCenter?: boolean;
14
+ autoPlay?: boolean;
15
+ }>();
16
+
17
+ const emit = defineEmits<{
18
+ (e: 'click', href: string | undefined): void;
19
+ }>();
20
+
21
+ const { isLight } = useTheme();
22
+ const { isPhone } = useScreen();
23
+
24
+ // 单个 Banner(非数组,或仅含一项的数组)
25
+ const singleBanner = computed((): BannerItem | undefined => {
26
+ if (!props.options) return undefined;
27
+ if (Array.isArray(props.options)) {
28
+ return props.options.length === 1 ? props.options[0] : undefined;
29
+ }
30
+ return props.options;
31
+ });
32
+
33
+ // 多个 Banner(数组且超过一项)
34
+ const multiBanner = computed((): BannerItem[] | undefined => {
35
+ if (!Array.isArray(props.options) || props.options.length <= 1) return undefined;
36
+ return props.options;
37
+ });
38
+ </script>
39
+
40
+ <template>
41
+ <div :class="['home-banner', size]">
42
+ <!-- 单个 Banner 的情况 -->
43
+ <div v-if="singleBanner" class="content-height">
44
+ <div v-if="size === 'tiny'">
45
+ {{ singleBanner.title }}
46
+ </div>
47
+
48
+ <BannerContent
49
+ v-else-if="!isPhone"
50
+ :info="singleBanner"
51
+ :size="size"
52
+ :content-justify-center="contentJustifyCenter"
53
+ :is-phone="isPhone"
54
+ :is-light="isLight"
55
+ @click="emit('click', $event)"
56
+ />
57
+
58
+ <ContentWrapper v-else class="banner-wrapper">
59
+ <OFigure
60
+ class="banner-bg"
61
+ :src="singleBanner.bg"
62
+ fit="cover"
63
+ />
64
+ </ContentWrapper>
65
+ </div>
66
+
67
+ <!-- 多个 Banner 轮播的情况 -->
68
+ <div v-else-if="multiBanner" class="content-height">
69
+ <OCarousel
70
+ v-if="!isPhone"
71
+ class="banner-carousel"
72
+ effect="toggle"
73
+ active-class="current-slide"
74
+ indicator-click
75
+ :auto-play="autoPlay"
76
+ >
77
+ <OCarouselItem
78
+ v-for="(info, index) in multiBanner"
79
+ :key="index"
80
+ class="banner-item"
81
+ :class="`banner-item${index}`"
82
+ >
83
+ <BannerContent
84
+ :info="info"
85
+ :size="size"
86
+ :content-justify-center="contentJustifyCenter"
87
+ :is-phone="isPhone"
88
+ :is-light="isLight"
89
+ @click="emit('click', $event)"
90
+ />
91
+ </OCarouselItem>
92
+ </OCarousel>
93
+
94
+ <OCarousel
95
+ v-else
96
+ class="banner-carousel"
97
+ effect="gallery"
98
+ indicator-click
99
+ arrow="never"
100
+ :auto-play="autoPlay"
101
+ >
102
+ <OCarouselItem
103
+ v-for="(info, index) in multiBanner"
104
+ :key="index"
105
+ class="banner-item"
106
+ :class="`banner-item${index}`"
107
+ >
108
+ <ContentWrapper class="banner-wrapper">
109
+ <OFigure
110
+ class="banner-bg"
111
+ :src="info.bg"
112
+ @click="emit('click', info.href)"
113
+ />
114
+ </ContentWrapper>
115
+ </OCarouselItem>
116
+ </OCarousel>
117
+ </div>
118
+
119
+ <!-- 没有 Banner 数据的情况 -->
120
+ <div v-else class="content-height">
121
+ <p>No data.</p>
122
+ </div>
123
+ </div>
124
+ </template>
125
+
126
+ <style lang="scss" scoped>
127
+ .home-banner {
128
+ overflow: hidden;
129
+ position: relative;
130
+
131
+ &.tiny {
132
+ @include display2;
133
+ font-weight: 500;
134
+ margin: var(--o-gap-8) 0;
135
+ color: var(--o-color-info1);
136
+ }
137
+
138
+ .content-height {
139
+ height: 100%;
140
+ }
141
+
142
+ &.large {
143
+ --banner-height: 460px;
144
+ height: var(--banner-height);
145
+
146
+ @include respond-to('laptop-pc_s') {
147
+ --banner-height: 400px;
148
+ }
149
+
150
+ @include respond-to('pad_h') {
151
+ --banner-height: 360px;
152
+ }
153
+
154
+ @include respond-to('<=pad_v') {
155
+ --banner-height: 184px;
156
+ }
157
+ }
158
+
159
+ &.medium {
160
+ --banner-height: 360px;
161
+ height: var(--banner-height);
162
+
163
+ @include respond-to('laptop-pc_s') {
164
+ --banner-height: 280px;
165
+ }
166
+
167
+ @include respond-to('pad_h') {
168
+ --banner-height: 220px;
169
+ }
170
+
171
+ @include respond-to('<=pad_v') {
172
+ --banner-height: 120px;
173
+ }
174
+ }
175
+
176
+ &.small {
177
+ --banner-height: 280px;
178
+ height: var(--banner-height);
179
+
180
+ @include respond-to('laptop-pc_s') {
181
+ --banner-height: 220px;
182
+ }
183
+
184
+ @include respond-to('pad_h') {
185
+ --banner-height: 180px;
186
+ }
187
+
188
+ @include respond-to('<=pad_v') {
189
+ display: none;
190
+ }
191
+ }
192
+
193
+ :deep(.o-btn) {
194
+ border-radius: var(--btn-height);
195
+ }
196
+ }
197
+
198
+ .banner-carousel {
199
+ width: 100%;
200
+ height: 100%;
201
+ @include respond-to('>pad_v') {
202
+ --carousel-indicator-offset: 53px;
203
+ }
204
+
205
+ @include respond-to('<=pad_v') {
206
+ --carousel-indicator-offset: 1px;
207
+ }
208
+
209
+ :deep(.o-carousel-indicator-bar) {
210
+ height: 24px;
211
+ }
212
+ }
213
+
214
+ .banner-item {
215
+ width: 100%;
216
+ height: 100%;
217
+ }
218
+
219
+ @keyframes fade-up {
220
+ from {
221
+ transform: translateY(var(--d));
222
+ opacity: 0;
223
+ }
224
+ to {
225
+ transform: translateY(0);
226
+ opacity: 1;
227
+ }
228
+ }
229
+
230
+ .current-slide {
231
+ .banner-title {
232
+ animation: fade-up 400ms ease-in;
233
+ }
234
+ .banner-subtitle {
235
+ animation: fade-up 400ms ease-in;
236
+ }
237
+ .banner-text {
238
+ animation: fade-up 400ms ease-in;
239
+ }
240
+ .banner-opts {
241
+ animation: fade-up 400ms ease-in;
242
+ }
243
+ }
244
+ </style>
245
+
246
+ <style lang="scss" scoped>
247
+ // 定制修改item1
248
+ .banner-item0 {
249
+ .banner-attach {
250
+ height: 120px;
251
+
252
+ @include respond-to('pad') {
253
+ height: 80px;
254
+ }
255
+ }
256
+ }
257
+
258
+ .banner-item1 {
259
+ .banner-attach {
260
+ height: 156px;
261
+
262
+ @include respond-to('pad') {
263
+ height: 120px;
264
+ }
265
+ }
266
+ }
267
+
268
+ // 定制修改item2
269
+ .banner-item2 {
270
+ .banner-content {
271
+ width: 100%;
272
+ justify-content: center;
273
+ }
274
+ .banner-attach {
275
+ height: 38%;
276
+ margin-top: -60px;
277
+ object-fit: contain;
278
+ }
279
+ }
280
+
281
+ .banner-wrapper {
282
+ height: 100%;
283
+
284
+ .banner-bg {
285
+ height: 100%;
286
+ }
287
+ }
288
+ </style>
@@ -0,0 +1,175 @@
1
+ <script setup lang="ts">
2
+ import { OButton, OFigure } from '@opensig/opendesign';
3
+ import ContentWrapper from '../common/ContentWrapper.vue';
4
+ import type { BannerContentProps } from './types';
5
+
6
+ defineProps<BannerContentProps>();
7
+
8
+ // 内联定义 emits 类型
9
+ const emit = defineEmits<{
10
+ (e: 'click', href: string | undefined): void;
11
+ }>();
12
+
13
+ const onClick = (href: string | undefined, hasBtn: string | undefined) => {
14
+ if (href && !hasBtn) {
15
+ window.open(href);
16
+ emit('click', href);
17
+ }
18
+ };
19
+ </script>
20
+
21
+ <template>
22
+ <OFigure
23
+ class="banner-bg"
24
+ :src="info.bg"
25
+ :class="{
26
+ 'with-sticky-bg': info.withStickyBg,
27
+ 'cursor-pointer': info.href && !info.btn,
28
+ }"
29
+ :style="{
30
+ '--pad-offset': info.pad_offset,
31
+ }"
32
+ @click="onClick(info.href, info.btn)"
33
+ >
34
+ <ContentWrapper class="banner-wrapper" :class="['banner-wrapper', contentJustifyCenter ? 'content-center' : '']">
35
+ <div class="banner-content">
36
+ <img v-if="!isPhone && info.attach" :src="info.attach" class="banner-attach" />
37
+
38
+ <!-- 标题 -->
39
+ <div
40
+ :class="{
41
+ 'banner-title': true,
42
+ 'text-dark': info.text_theme === 'dark'
43
+ }"
44
+ v-if="info.title"
45
+ >
46
+ {{ info.title }}
47
+ </div>
48
+ <!-- 副标题 -->
49
+ <div
50
+ :class="{
51
+ 'banner-subtitle': true,
52
+ 'text-dark': info.text_theme === 'dark'
53
+ }"
54
+ v-if="info.subtitle"
55
+ >
56
+ {{ info.subtitle }}
57
+ </div>
58
+ <div
59
+ class="banner-text"
60
+ v-if="info.bg_text"
61
+ :style="{
62
+ backgroundImage: `url(${info.bg_text})`,
63
+ '--pc-width': info.pc_text_width,
64
+ '--pc-height': info.pc_text_height,
65
+ '--pad-width': info.pad_text_width,
66
+ '--pad-height': info.pad_text_height,
67
+ }"
68
+ ></div>
69
+ <!-- 操作按钮 -->
70
+ <div v-if="info.btn" class="banner-opts">
71
+ <OButton
72
+ :href="info.href"
73
+ target="_blank"
74
+ variant="solid"
75
+ color="primary"
76
+ :size="size === 'tiny' ? undefined : size"
77
+ >
78
+ {{ info.btn }}
79
+ </OButton>
80
+ </div>
81
+ </div>
82
+ </ContentWrapper>
83
+ </OFigure>
84
+ </template>
85
+
86
+ <style lang="scss" scoped>
87
+ .banner-bg {
88
+ width: 100%;
89
+ height: 100%;
90
+
91
+ :deep(.o-figure-img) {
92
+ width: 100%;
93
+ height: 100%;
94
+ }
95
+
96
+ @include respond-to('pad') {
97
+ :deep(.o-figure-img) {
98
+ transition: object-position 0.3s ease;
99
+ object-position: var(--pad-offset);
100
+ }
101
+ }
102
+
103
+ @include respond-to('phone') {
104
+ --figure-radius: 4px;
105
+ }
106
+ }
107
+
108
+ .banner-wrapper {
109
+ height: 100%;
110
+
111
+ &.content-center {
112
+ display: flex;
113
+ justify-content: center;
114
+
115
+ & .banner-content {
116
+ align-items: center;
117
+ }
118
+ }
119
+ }
120
+
121
+ .banner-content {
122
+ height: 100%;
123
+ display: inline-flex;
124
+ flex-direction: column;
125
+ justify-content: center;
126
+ position: relative;
127
+ }
128
+
129
+ .banner-title {
130
+ @include display1;
131
+ color: var(--o-color-info1);
132
+ font-weight: 500;
133
+ margin-bottom: 8px;
134
+
135
+ &.text-dark {
136
+ color: var(--o-color-info1-inverse);
137
+ }
138
+
139
+ @include respond-to('<=pad_v') {
140
+ font-size: 22px;
141
+ line-height: 30px;
142
+ }
143
+ }
144
+
145
+ .banner-subtitle {
146
+ color: var(--o-color-info1);
147
+ margin-top: 8px;
148
+ font-size: 16px;
149
+
150
+ &.text-dark {
151
+ color: var(--o-color-info1-inverse);
152
+ }
153
+ }
154
+
155
+ .banner-text {
156
+ height: var(--pc-height);
157
+ width: var(--pc-width);
158
+ background-size: contain;
159
+ background-repeat: no-repeat;
160
+
161
+ @include respond-to('pad') {
162
+ height: var(--pad-height);
163
+ width: var(--pad-width);
164
+ }
165
+ }
166
+
167
+ .banner-opts {
168
+ margin-top: 24px;
169
+ --d: 20px;
170
+ }
171
+
172
+ .cursor-pointer {
173
+ cursor: pointer;
174
+ }
175
+ </style>
@@ -0,0 +1,18 @@
1
+ import _OBanner from './OBanner.vue';
2
+ import _OBannerContent from './OBannerContent.vue';
3
+ import type { App } from 'vue';
4
+
5
+
6
+ const OBanner = Object.assign(_OBanner, {
7
+ install(app: App) {
8
+ app.component('OBanner', _OBanner);
9
+ },
10
+ });
11
+ const OBannerContent = Object.assign(_OBannerContent, {
12
+ install(app: App) {
13
+ app.component('OBannerContent', _OBannerContent);
14
+ },
15
+ });
16
+
17
+ export { OBanner, OBannerContent };
18
+ export * from './types';
@@ -0,0 +1,39 @@
1
+ // Banner 项的类型定义
2
+ export interface BannerItem {
3
+ title?: string;
4
+ subtitle?: string;
5
+ bg: string;
6
+ text_theme?: 'light' | 'dark';
7
+ bg_text?: string;
8
+ pc_text_width?: string;
9
+ pc_text_height?: string;
10
+ pad_text_width?: string;
11
+ pad_text_height?: string;
12
+ attach?: string;
13
+ href?: string;
14
+ btn?: string;
15
+ withStickyBg?: boolean;
16
+ pad_offset?: string;
17
+ }
18
+
19
+ // BannerContent 组件的 Props 类型
20
+ export interface BannerContentProps {
21
+ info: BannerItem;
22
+ size?: 'large' | 'medium' | 'small' | 'tiny';
23
+ contentJustifyCenter?: boolean;
24
+ isPhone?: boolean;
25
+ isLight?: boolean;
26
+ }
27
+
28
+ // Emits 事件类型
29
+ export interface HomeBannerEmits {
30
+ (e: 'before-change', index: number): void;
31
+ (e: 'click', href: string | undefined): void;
32
+ }
33
+
34
+ export interface BannerContentEmits {
35
+ (e: 'click', href: string | undefined): void;
36
+ }
37
+
38
+ // 组件尺寸类型
39
+ export type ComponentSize = 'large' | 'medium' | 'small' | 'tiny';
@@ -35,7 +35,7 @@ const handleMouseenter = (val: any) => {
35
35
  itemVisible.value = true;
36
36
  }
37
37
  };
38
- const handleMouseleave = (val: any) => {
38
+ const handleMouseleave = () => {
39
39
  itemVisible.value = false;
40
40
  };
41
41
  const handleClick = (val: any) => {
@@ -286,6 +286,10 @@ const checkSelectedDay = (type: CalendarDataType, date: string) => {
286
286
  }
287
287
  return false;
288
288
  };
289
+
290
+ defineExpose({
291
+ refresh: getDateData,
292
+ });
289
293
  </script>
290
294
  <template>
291
295
  <div class="o-meeting-calendar">
@@ -372,7 +376,7 @@ const checkSelectedDay = (type: CalendarDataType, date: string) => {
372
376
  >
373
377
  <OOption v-for="t in groups" :value="t" :key="t">{{ t }}</OOption>
374
378
  </OSelect>
375
- <OTab v-model="tabType" :line="false">
379
+ <OTab v-model="tabType" :line="false" :max-show="9999">
376
380
  <OTabPane v-for="item in tabs" :key="item.value" :value="item.value">
377
381
  <template #nav>
378
382
  <OIcon>
@@ -822,6 +826,7 @@ const checkSelectedDay = (type: CalendarDataType, date: string) => {
822
826
 
823
827
  .o-select {
824
828
  display: none;
829
+ margin-bottom: var(--o-gap-2);
825
830
  @include respond('<=pad_v') {
826
831
  display: inline-flex;
827
832
  }
@@ -829,6 +834,7 @@ const checkSelectedDay = (type: CalendarDataType, date: string) => {
829
834
  display: flex;
830
835
  width: 100%;
831
836
  max-width: 100%;
837
+ margin-bottom: 0;
832
838
  }
833
839
  }
834
840
 
@@ -857,17 +863,16 @@ const checkSelectedDay = (type: CalendarDataType, date: string) => {
857
863
  .o-icon {
858
864
  display: none;
859
865
  }
860
- .o-tab-navs-wrap {
861
- height: 40px;
866
+ .o-tab-navs-container {
862
867
 
863
868
  .o-tab-nav {
864
- line-height: 2;
869
+ line-height: 32px;
865
870
  }
866
871
  }
867
872
  }
868
873
  @include respond('phone') {
869
- .o-tab-navs-wrap {
870
- height: auto;
874
+ .o-tab-nav {
875
+ line-height: 2;
871
876
  }
872
877
  }
873
878