@opendesign-plus-test/components 0.0.1-rc.49 → 0.0.1-rc.50

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 (65) hide show
  1. package/dist/chunk-OElCookieNotice.cjs.js +1 -1
  2. package/dist/chunk-OElCookieNotice.es.js +48 -68
  3. package/dist/components/OHeaderSearch.vue.d.ts +534 -814
  4. package/dist/components/OThemeSwitcher.vue.d.ts +2 -5
  5. package/dist/components/activity/index.d.ts +2 -2
  6. package/dist/components/meeting/index.d.ts +3 -3
  7. package/dist/components.cjs.js +42 -42
  8. package/dist/components.css +1 -1
  9. package/dist/components.es.js +10448 -11464
  10. package/dist/index.d.ts +0 -1
  11. package/package.json +4 -6
  12. package/src/assets/styles/element-plus.scss +204 -0
  13. package/src/assets/svg-icons/icon-delete.svg +1 -5
  14. package/src/components/OHeaderSearch.vue +415 -436
  15. package/src/components/OThemeSwitcher.vue +51 -27
  16. package/src/components/activity/OActivityApproval.vue +10 -6
  17. package/src/components/activity/OActivityForm.vue +5 -3
  18. package/src/components/activity/{OMyActivityCalendar.vue → OActivityMyCalendar.vue} +43 -21
  19. package/src/components/activity/index.ts +4 -4
  20. package/src/components/events/OEventsApply.vue +2 -1
  21. package/src/components/events/OEventsCalendar.vue +7 -5
  22. package/src/components/events/OEventsList.vue +6 -4
  23. package/src/components/meeting/OMeetingCalendar.vue +15 -12
  24. package/src/components/meeting/OMeetingForm.vue +16 -10
  25. package/src/components/meeting/{OMyMeetingCalendar.vue → OMeetingMyCalendar.vue} +73 -38
  26. package/src/components/meeting/OMeetingPlayback.vue +32 -8
  27. package/src/components/meeting/{OSigMeetingCalendar.vue → OMeetingSigCalendar.vue} +6 -3
  28. package/src/components/meeting/components/OMeetingCalendarList.vue +3 -3
  29. package/src/components/meeting/components/OMeetingCalendarSelector.vue +1 -1
  30. package/src/components/meeting/components/OMeetingPlaybackSubtitles.vue +10 -9
  31. package/src/components/meeting/components/OMeetingPlaybackVideo.vue +6 -6
  32. package/src/components/meeting/components/{OSigMeetingAside.vue → OMeetingSigAside.vue} +1 -1
  33. package/src/components/meeting/config.ts +1 -1
  34. package/src/components/meeting/index.ts +8 -8
  35. package/src/i18n/en.ts +2 -12
  36. package/src/i18n/zh.ts +0 -10
  37. package/src/index.ts +0 -1
  38. package/vite.config.ts +1 -5
  39. package/dist/components/search/OSearchInput.vue.d.ts +0 -1003
  40. package/dist/components/search/composables/useImageSearch.d.ts +0 -48
  41. package/dist/components/search/composables/useKeywordHighlight.d.ts +0 -2
  42. package/dist/components/search/composables/useSearchHistory.d.ts +0 -14
  43. package/dist/components/search/index.d.ts +0 -590
  44. package/dist/components/search/internal/HighlightText.vue.d.ts +0 -9
  45. package/dist/components/search/internal/SearchImageInput.vue.d.ts +0 -716
  46. package/dist/components/search/internal/SearchPanel.vue.d.ts +0 -100
  47. package/dist/components/search/types.d.ts +0 -20
  48. package/src/assets/svg-icons/icon-delete-hover.svg +0 -4
  49. package/src/assets/svg-icons/icon-image-close.svg +0 -4
  50. package/src/assets/svg-icons/icon-image-upload.svg +0 -3
  51. package/src/assets/svg-icons/icon-image-zoomin.svg +0 -3
  52. package/src/assets/svg-icons/icon-refresh.svg +0 -3
  53. package/src/components/search/OSearchInput.vue +0 -463
  54. package/src/components/search/composables/useImageSearch.ts +0 -157
  55. package/src/components/search/composables/useKeywordHighlight.ts +0 -30
  56. package/src/components/search/composables/useSearchHistory.ts +0 -75
  57. package/src/components/search/index.ts +0 -23
  58. package/src/components/search/internal/HighlightText.vue +0 -37
  59. package/src/components/search/internal/SearchImageInput.vue +0 -488
  60. package/src/components/search/internal/SearchPanel.vue +0 -430
  61. package/src/components/search/types.ts +0 -25
  62. /package/dist/components/activity/{OMyActivityCalendar.vue.d.ts → OActivityMyCalendar.vue.d.ts} +0 -0
  63. /package/dist/components/meeting/{OMyMeetingCalendar.vue.d.ts → OMeetingMyCalendar.vue.d.ts} +0 -0
  64. /package/dist/components/meeting/{OSigMeetingCalendar.vue.d.ts → OMeetingSigCalendar.vue.d.ts} +0 -0
  65. /package/dist/components/meeting/components/{OSigMeetingAside.vue.d.ts → OMeetingSigAside.vue.d.ts} +0 -0
@@ -1,100 +0,0 @@
1
- import { OSearchRecommendItem } from '../types';
2
- export interface SearchPanelPropsT {
3
- keyword?: string;
4
- onestepItems?: OSearchRecommendItem[];
5
- onestepTitle?: string;
6
- suggestItems?: OSearchRecommendItem[];
7
- suggestTitle?: string;
8
- recommendItems?: string[];
9
- historyItems?: string[];
10
- historyTitle?: string;
11
- hotItems?: string[];
12
- hotTitle?: string;
13
- noDataText?: string;
14
- highlightKeyword?: boolean;
15
- /** When true, show history+hot sections only if keyword is empty */
16
- hideOnKeyword?: boolean;
17
- /** When true, show suggest empty state ("no data") even when list is empty */
18
- showSuggestEmpty?: boolean;
19
- isDark?: boolean;
20
- /** 'chips' = tag-cloud (header dropdown), 'list' = full-width rows (page search) */
21
- historyLayout?: 'chips' | 'list';
22
- }
23
- declare function __VLS_template(): {
24
- attrs: Partial<{}>;
25
- slots: {
26
- 'onestep-header'?(_: {
27
- items: OSearchRecommendItem[];
28
- }): any;
29
- 'onestep-content'?(_: {
30
- items: OSearchRecommendItem[];
31
- keyword: string;
32
- }): any;
33
- 'suggest-header'?(_: {
34
- items: OSearchRecommendItem[];
35
- }): any;
36
- 'suggest-content'?(_: {
37
- items: OSearchRecommendItem[];
38
- keyword: string;
39
- }): any;
40
- 'recommend-header'?(_: {
41
- items: string[];
42
- }): any;
43
- 'recommend-content'?(_: {
44
- items: string[];
45
- }): any;
46
- 'history-header'?(_: {
47
- items: string[];
48
- }): any;
49
- 'history-content'?(_: {
50
- items: string[];
51
- }): any;
52
- 'hot-header'?(_: {
53
- items: string[];
54
- }): any;
55
- 'hot-content'?(_: {
56
- items: string[];
57
- }): any;
58
- };
59
- refs: {};
60
- rootEl: HTMLDivElement;
61
- };
62
- type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
63
- declare const __VLS_component: import('../../../../vue/dist/vue.esm-bundler.js').DefineComponent<SearchPanelPropsT, {}, {}, {}, {}, import('../../../../vue/dist/vue.esm-bundler.js').ComponentOptionsMixin, import('../../../../vue/dist/vue.esm-bundler.js').ComponentOptionsMixin, {} & {
64
- "onestep-click": (item: OSearchRecommendItem) => any;
65
- "suggest-click": (item: OSearchRecommendItem) => any;
66
- "recommend-click": (val: string) => any;
67
- "history-click": (val: string) => any;
68
- "hot-click": (val: string) => any;
69
- "history-remove": (val: string) => any;
70
- "history-clear": () => any;
71
- "hot-refresh": () => any;
72
- }, string, import('../../../../vue/dist/vue.esm-bundler.js').PublicProps, Readonly<SearchPanelPropsT> & Readonly<{
73
- "onOnestep-click"?: ((item: OSearchRecommendItem) => any) | undefined;
74
- "onSuggest-click"?: ((item: OSearchRecommendItem) => any) | undefined;
75
- "onRecommend-click"?: ((val: string) => any) | undefined;
76
- "onHistory-click"?: ((val: string) => any) | undefined;
77
- "onHot-click"?: ((val: string) => any) | undefined;
78
- "onHistory-remove"?: ((val: string) => any) | undefined;
79
- "onHistory-clear"?: (() => any) | undefined;
80
- "onHot-refresh"?: (() => any) | undefined;
81
- }>, {
82
- keyword: string;
83
- onestepItems: OSearchRecommendItem[];
84
- suggestItems: OSearchRecommendItem[];
85
- recommendItems: string[];
86
- historyItems: string[];
87
- hotItems: string[];
88
- highlightKeyword: boolean;
89
- hideOnKeyword: boolean;
90
- showSuggestEmpty: boolean;
91
- isDark: boolean;
92
- historyLayout: "chips" | "list";
93
- }, {}, {}, {}, string, import('../../../../vue/dist/vue.esm-bundler.js').ComponentProvideOptions, false, {}, HTMLDivElement>;
94
- declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
95
- export default _default;
96
- type __VLS_WithTemplateSlots<T, S> = T & {
97
- new (): {
98
- $slots: S;
99
- };
100
- };
@@ -1,20 +0,0 @@
1
- export interface OSearchRecommendItem {
2
- key: string;
3
- path?: string;
4
- type?: string;
5
- count?: number;
6
- }
7
- export interface OSearchPayload {
8
- keyword: string;
9
- imageUrl?: string;
10
- }
11
- export interface OSearchImageUploadErrorPayload {
12
- file: File;
13
- error: unknown;
14
- }
15
- export type OSearchUploadImageFn = (file: File) => Promise<string>;
16
- export type OSearchItemClickType = 'history' | 'hot' | 'suggest' | 'onestep';
17
- export interface OSearchHighlightPart {
18
- text: string;
19
- match: boolean;
20
- }
@@ -1,4 +0,0 @@
1
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
- <path fill="#6f6f75" d="M22.5 12c0 5.799-4.701 10.5-10.5 10.5s-10.5-4.701-10.5-10.5c0-5.799 4.701-10.5 10.5-10.5s10.5 4.701 10.5 10.5z"></path>
3
- <path fill="#ffffff" d="M15.3 7.631c0.274-0.197 0.657-0.172 0.903 0.074 0.273 0.273 0.273 0.717 0 0.99l-3.259 3.259 3.259 3.259c0.273 0.273 0.273 0.717 0 0.99-0.246 0.246-0.63 0.271-0.903 0.074l-0.087-0.074-3.259-3.259-3.259 3.259-0.087 0.074c-0.274 0.197-0.657 0.172-0.903-0.074-0.273-0.273-0.273-0.717 0-0.99l3.259-3.259-3.259-3.259c-0.273-0.273-0.273-0.717 0-0.99 0.246-0.246 0.63-0.271 0.903-0.074l0.087 0.074 3.259 3.259 3.259-3.259 0.087-0.074z"></path>
4
- </svg>
@@ -1,4 +0,0 @@
1
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
- <path d="M22.5 12c0 5.799-4.701 10.5-10.5 10.5s-10.5-4.701-10.5-10.5c0-5.799 4.701-10.5 10.5-10.5s10.5 4.701 10.5 10.5z"></path>
3
- <path fill="currentColor" d="M15.3 7.631c0.274-0.197 0.657-0.172 0.903 0.074 0.273 0.273 0.273 0.717 0 0.99l-3.259 3.259 3.259 3.259c0.273 0.273 0.273 0.717 0 0.99-0.246 0.246-0.63 0.271-0.903 0.074l-0.087-0.074-3.259-3.259-3.259 3.259-0.087 0.074c-0.274 0.197-0.657 0.172-0.903-0.074-0.273-0.273-0.273-0.717 0-0.99l3.259-3.259-3.259-3.259c-0.273-0.273-0.273-0.717 0-0.99 0.246-0.246 0.63-0.271 0.903-0.074l0.087 0.074 3.259 3.259 3.259-3.259 0.087-0.074z"></path>
4
- </svg>
@@ -1,3 +0,0 @@
1
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
- <path opacity="0.8" d="M19.724 4.238c1.105 0 2 0.895 2 2v6.772c0 0.387-0.313 0.7-0.7 0.7s-0.7-0.313-0.7-0.7v-0.816l-3.544 3.84c-0.248 0.268-0.661 0.301-0.948 0.075l-4.13-3.256-3.925 3.843c-0.249 0.243-0.632 0.264-0.904 0.064l-0.086-0.075c-0.27-0.276-0.266-0.72 0.011-0.99l4.365-4.273c0.251-0.246 0.647-0.267 0.923-0.050l4.104 3.235 4.134-4.478v-3.892c0-0.331-0.269-0.6-0.6-0.6h-15.45c-0.331 0-0.6 0.269-0.6 0.6v11.501c0 0.331 0.269 0.6 0.6 0.6h9.781c0.387 0 0.7 0.313 0.7 0.7s-0.313 0.7-0.7 0.7h-9.781c-1.105 0-2-0.895-2-2v-11.501c0-1.105 0.895-2 2-2h15.45zM9.532 8.878c0-0.695-0.579-1.259-1.294-1.259s-1.294 0.564-1.294 1.259c0 0.695 0.579 1.259 1.294 1.259s1.294-0.564 1.294-1.259zM16.561 18.645c-0.195-0.195-0.195-0.512 0-0.707l2.090-2.090c0.010-0.011 0.020-0.021 0.030-0.030l0.001-0.001c0.195-0.195 0.512-0.195 0.707 0l2.121 2.121c0.195 0.195 0.195 0.512 0 0.707s-0.512 0.195-0.707 0l-1.284-1.284v3.57c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5v-3.538l-1.251 1.251c-0.174 0.174-0.443 0.193-0.638 0.058l-0.069-0.058z"></path>
3
- </svg>
@@ -1,3 +0,0 @@
1
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
- <path fill="currentColor" d="M3.398 10.877c0-4.099 3.323-7.423 7.423-7.423s7.423 3.323 7.423 7.423c0 4.099-3.323 7.423-7.423 7.423s-7.423-3.323-7.423-7.423zM16.774 10.877c0-3.326-2.657-6.023-5.935-6.023s-5.935 2.696-5.935 6.023c0 3.326 2.657 6.023 5.935 6.023s5.935-2.696 5.935-6.023zM11.499 13.369c0 0.365-0.296 0.661-0.661 0.661s-0.661-0.296-0.661-0.661v-1.821h-1.775c-0.371 0-0.671-0.3-0.671-0.671s0.3-0.671 0.671-0.671h1.775v-1.821c0-0.365 0.296-0.661 0.661-0.661s0.661 0.296 0.661 0.661v1.821h1.775c0.371 0 0.671 0.3 0.671 0.671s-0.3 0.671-0.671 0.671h-1.775v1.821zM16.579 16.598c0.242-0.246 0.62-0.271 0.89-0.075l0.086 0.074 2.72 2.754c0.27 0.273 0.27 0.716 0.001 0.99-0.242 0.246-0.62 0.271-0.89 0.075l-0.086-0.074-2.72-2.754c-0.27-0.273-0.27-0.716-0.001-0.99z"></path>
3
- </svg>
@@ -1,3 +0,0 @@
1
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
- <path opacity="0.8" fill="currentColor" d="M17.947 4.273c-1.676-1.292-3.752-2.023-5.948-2.023-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75c4.032 0 7.604-2.47 9.066-6.156 0.153-0.385-0.035-0.821-0.42-0.974s-0.821 0.036-0.974 0.42c-1.237 3.119-4.26 5.209-7.672 5.209-4.556 0-8.25-3.694-8.25-8.25s3.694-8.25 8.25-8.25c1.837 0 3.574 0.604 4.983 1.673l-1.305 1.556c-0.077 0.092-0.021 0.232 0.098 0.246l4.873 0.539c0.106 0.012 0.191-0.088 0.16-0.191l-1.377-4.706c-0.034-0.115-0.182-0.146-0.259-0.054l-1.226 1.461z"></path>
3
- </svg>
@@ -1,463 +0,0 @@
1
- <script setup lang="ts">
2
- import { computed, ref, toRef, watch } from 'vue';
3
- import { onClickOutside, useDebounceFn } from '@vueuse/core';
4
-
5
- import SearchImageInput from './internal/SearchImageInput.vue';
6
- import SearchPanel from './internal/SearchPanel.vue';
7
- import { useSearchHistory } from './composables/useSearchHistory';
8
- import { useI18n } from '@/i18n';
9
- import type {
10
- OSearchPayload,
11
- OSearchRecommendItem,
12
- OSearchUploadImageFn,
13
- } from './types';
14
-
15
- export interface OSearchInputPropsT {
16
- modelValue?: string;
17
- imageUrl?: string;
18
- size?: 'small' | 'medium' | 'large';
19
- placeholder?: string;
20
- imagePlaceholder?: string;
21
-
22
- /** ---- Image search ---- */
23
- enableImageSearch?: boolean;
24
- uploadImage?: OSearchUploadImageFn;
25
- maxImageSize?: number;
26
- imageUploadTooltip?: string;
27
-
28
- /** ---- Recommendation lists (controlled by parent) ---- */
29
- suggestItems?: OSearchRecommendItem[];
30
- onestepItems?: OSearchRecommendItem[];
31
- suggestTitle?: string;
32
- onestepTitle?: string;
33
- noDataText?: string;
34
- /** When true, show "no data" placeholder for empty suggest while typing */
35
- showSuggestEmpty?: boolean;
36
- highlightKeyword?: boolean;
37
- debounce?: number;
38
-
39
- /** ---- History ---- */
40
- enableHistory?: boolean;
41
- historyItems?: string[];
42
- maxHistoryCount?: number;
43
- storeHistory?: boolean;
44
- storageKey?: string;
45
- historyTitle?: string;
46
- /** Auto-record history on search; default true */
47
- autoSaveHistory?: boolean;
48
-
49
- /** ---- "Did you mean" list (below input) ---- */
50
- suggestList?: string[];
51
- suggestListLabel?: string;
52
- /** When true, render suggestList items as HTML (with v-html on inert string) */
53
- allowHtmlInSuggest?: boolean;
54
-
55
- /** ---- Misc ---- */
56
- clearable?: boolean;
57
- closeOnSearch?: boolean;
58
- closeOnClickOutside?: boolean;
59
- /** Show dropdown on focus even when empty (history) */
60
- openOnFocus?: boolean;
61
- /** Always show image as inline thumbnail inside the input; never expand preview below */
62
- alwaysInlineThumbnail?: boolean;
63
- }
64
-
65
- const props = withDefaults(defineProps<OSearchInputPropsT>(), {
66
- modelValue: '',
67
- imageUrl: '',
68
- size: 'large',
69
- enableImageSearch: false,
70
- maxImageSize: 10 * 1024 * 1024,
71
- suggestItems: () => [],
72
- onestepItems: () => [],
73
- showSuggestEmpty: true,
74
- highlightKeyword: true,
75
- debounce: 300,
76
- enableHistory: true,
77
- historyItems: () => [],
78
- maxHistoryCount: 6,
79
- storeHistory: false,
80
- storageKey: 'search-history',
81
- autoSaveHistory: true,
82
- suggestList: () => [],
83
- allowHtmlInSuggest: false,
84
- clearable: true,
85
- closeOnSearch: true,
86
- closeOnClickOutside: true,
87
- openOnFocus: true,
88
- });
89
-
90
- const emit = defineEmits<{
91
- (e: 'update:modelValue', val: string): void;
92
- (e: 'update:imageUrl', url: string): void;
93
- (e: 'update:historyItems', items: string[]): void;
94
- (e: 'focus'): void;
95
- (e: 'blur'): void;
96
- (e: 'input', val: string): void;
97
- (e: 'clear'): void;
98
- (e: 'search', payload: OSearchPayload): void;
99
- (e: 'recommend-click', item: OSearchRecommendItem): void;
100
- (e: 'onestep-click', item: OSearchRecommendItem): void;
101
- (e: 'history-click', val: string): void;
102
- (e: 'suggest-list-click', val: string): void;
103
- (e: 'delete-history', items: string[]): void;
104
- (e: 'delete-history-item', val: string): void;
105
- (e: 'image-upload-start', file: File): void;
106
- (e: 'image-upload-success', url: string, file: File): void;
107
- (e: 'image-upload-error', error: unknown, file: File): void;
108
- (e: 'image-validate-error', reason: 'size' | 'type', file: File): void;
109
- }>();
110
-
111
- const { t } = useI18n();
112
-
113
- const inputRef = ref<InstanceType<typeof SearchImageInput>>();
114
- const wrapperRef = ref<HTMLElement | null>(null);
115
-
116
- const innerValue = computed({
117
- get: () => props.modelValue,
118
- set: (val: string) => emit('update:modelValue', val),
119
- });
120
-
121
- const isFocus = ref(false);
122
- const isPreviewOpen = ref(false);
123
- const justClosedPreview = ref(false);
124
- const hasInternalImage = ref(false);
125
-
126
- const showDropdown = computed(() => {
127
- if (!isFocus.value) return false;
128
- if (props.imageUrl || hasInternalImage.value) return false;
129
- const hasSuggest =
130
- !!innerValue.value &&
131
- (props.suggestItems.length > 0 || props.onestepItems.length > 0 || props.showSuggestEmpty);
132
- const hasHistory = props.enableHistory && history.items.value.length > 0 && !innerValue.value;
133
- if (hasSuggest) return true;
134
- if (props.openOnFocus && hasHistory) return true;
135
- return false;
136
- });
137
-
138
- // history
139
- const historyItemsRef = toRef(props, 'historyItems');
140
- const storageKeyRef = toRef(props, 'storageKey');
141
- const storeHistoryRef = toRef(props, 'storeHistory');
142
- const maxHistoryRef = toRef(props, 'maxHistoryCount');
143
-
144
- const history = useSearchHistory({
145
- initial: historyItemsRef,
146
- storageKey: storageKeyRef,
147
- storeHistory: storeHistoryRef,
148
- maxHistoryCount: maxHistoryRef,
149
- onChange: (items) => emit('update:historyItems', items),
150
- });
151
-
152
- // debounced input event
153
- const emitInputDebounced = useDebounceFn((val: string) => {
154
- emit('input', val);
155
- }, () => props.debounce);
156
-
157
- watch(innerValue, (val) => {
158
- emitInputDebounced(val);
159
- });
160
-
161
- // click outside
162
- onClickOutside(wrapperRef, () => {
163
- if (!props.closeOnClickOutside) return;
164
- if (isPreviewOpen.value || justClosedPreview.value) return;
165
- isFocus.value = false;
166
- });
167
-
168
- const handleFocus = () => {
169
- isFocus.value = true;
170
- emit('focus');
171
- };
172
-
173
- const handleBlur = () => {
174
- emit('blur');
175
- };
176
-
177
- const runSearch = async () => {
178
- if (inputRef.value?.getIsUploading?.()) {
179
- await inputRef.value.awaitUpload?.();
180
- }
181
- const keyword = innerValue.value.trim();
182
- const imageUrl = inputRef.value?.getUploadedUrl?.() || props.imageUrl;
183
-
184
- if (!keyword && !imageUrl) return;
185
-
186
- if (props.autoSaveHistory && keyword) {
187
- history.push(keyword);
188
- }
189
-
190
- if (props.closeOnSearch) {
191
- isFocus.value = false;
192
- }
193
-
194
- emit('search', { keyword, imageUrl: imageUrl || undefined });
195
- };
196
-
197
- const handleClear = () => {
198
- innerValue.value = '';
199
- emit('clear');
200
- };
201
-
202
- const handleSuggestClick = (item: OSearchRecommendItem) => {
203
- emit('recommend-click', item);
204
- innerValue.value = item.key;
205
- runSearch();
206
- };
207
-
208
- const handleOnestepClick = (item: OSearchRecommendItem) => {
209
- emit('onestep-click', item);
210
- if (item.path) {
211
- const url = item.path;
212
- if (typeof window !== 'undefined') window.open(url, '_blank', 'noopener,noreferrer');
213
- }
214
- };
215
-
216
- const handleHistoryClick = (val: string) => {
217
- emit('history-click', val);
218
- innerValue.value = val;
219
- runSearch();
220
- };
221
-
222
- const handleHistoryRemove = (val: string) => {
223
- history.remove(val);
224
- emit('delete-history-item', val);
225
- };
226
-
227
- const handleHistoryClear = () => {
228
- const removed = [...history.items.value];
229
- history.clearAll();
230
- emit('delete-history', removed);
231
- };
232
-
233
- const handleSuggestListClick = (val: string) => {
234
- // Strip HTML tags when raw HTML is allowed for display
235
- const text = props.allowHtmlInSuggest ? val.replace(/<[^>]+>/g, '') : val;
236
- emit('suggest-list-click', text);
237
- innerValue.value = text;
238
- runSearch();
239
- };
240
-
241
- const onPreviewChange = (visible: boolean) => {
242
- isPreviewOpen.value = visible;
243
- if (!visible) {
244
- justClosedPreview.value = true;
245
- setTimeout(() => {
246
- justClosedPreview.value = false;
247
- }, 100);
248
- }
249
- };
250
-
251
- const showInlineThumbnail = computed(() =>
252
- !!props.imageUrl && (props.alwaysInlineThumbnail || !isFocus.value)
253
- );
254
-
255
- const onImageUploadStart = (file: File) => {
256
- hasInternalImage.value = true;
257
- emit('image-upload-start', file);
258
- };
259
-
260
- const onImageUploadSuccess = (url: string, file: File) => {
261
- hasInternalImage.value = false;
262
- emit('image-upload-success', url, file);
263
- };
264
-
265
- const onImageClear = () => {
266
- hasInternalImage.value = false;
267
- emit('update:imageUrl', '');
268
- };
269
-
270
- defineExpose({
271
- focus: () => inputRef.value?.focus?.(),
272
- blur: () => inputRef.value?.blur?.(),
273
- search: runSearch,
274
- saveHistory: (val?: string) => history.push(val ?? innerValue.value),
275
- });
276
- </script>
277
-
278
- <template>
279
- <div ref="wrapperRef" class="o-search-input" :class="{ 'is-focus': isFocus }">
280
- <div class="o-search-input-box">
281
- <SearchImageInput
282
- ref="inputRef"
283
- v-model="innerValue"
284
- :image-url="imageUrl"
285
- :placeholder="placeholder"
286
- :image-placeholder="imagePlaceholder"
287
- :size="size"
288
- :enable-image-search="enableImageSearch"
289
- :upload-image="uploadImage"
290
- :max-image-size="maxImageSize"
291
- :image-upload-tooltip="imageUploadTooltip"
292
- :expanded="isFocus && !props.alwaysInlineThumbnail"
293
- :inline-thumbnail="showInlineThumbnail"
294
- :clearable="clearable"
295
- class="o-search-input-field"
296
- @update:imageUrl="(url: string) => emit('update:imageUrl', url)"
297
- @focus="handleFocus"
298
- @blur="handleBlur"
299
- @enter="runSearch"
300
- @clear="handleClear"
301
- @image-clear="onImageClear"
302
- @image-upload-start="onImageUploadStart"
303
- @image-upload-success="onImageUploadSuccess"
304
- @image-upload-error="(error: unknown, file: File) => emit('image-upload-error', error, file)"
305
- @image-validate-error="(reason: 'size' | 'type', file: File) => emit('image-validate-error', reason, file)"
306
- @preview-change="onPreviewChange"
307
- >
308
- <template #prefix><slot name="input-prefix" /></template>
309
- <template #suffix="slotProps"><slot name="input-suffix" v-bind="slotProps" /></template>
310
- <template v-if="$slots['image-preview']" #preview="slotProps">
311
- <slot name="image-preview" v-bind="slotProps" />
312
- </template>
313
- </SearchImageInput>
314
-
315
- <Transition name="o-search-input-dropdown">
316
- <div v-if="showDropdown" class="o-search-input-dropdown">
317
- <slot name="dropdown" :keyword="modelValue">
318
- <SearchPanel
319
- :keyword="modelValue"
320
- :onestep-items="onestepItems"
321
- :onestep-title="onestepTitle"
322
- :suggest-items="suggestItems"
323
- :suggest-title="suggestTitle"
324
- :history-items="enableHistory ? history.items.value : []"
325
- :history-title="historyTitle"
326
- :no-data-text="noDataText"
327
- :highlight-keyword="highlightKeyword"
328
- :hide-on-keyword="true"
329
- :show-suggest-empty="showSuggestEmpty"
330
- history-layout="list"
331
- @onestep-click="handleOnestepClick"
332
- @suggest-click="handleSuggestClick"
333
- @history-click="handleHistoryClick"
334
- @history-remove="handleHistoryRemove"
335
- @history-clear="handleHistoryClear"
336
- >
337
- <template v-if="$slots['onestep-header']" #onestep-header="slotProps">
338
- <slot name="onestep-header" v-bind="slotProps" />
339
- </template>
340
- <template v-if="$slots['onestep-content']" #onestep-content="slotProps">
341
- <slot name="onestep-content" v-bind="slotProps" />
342
- </template>
343
- <template v-if="$slots['suggest-header']" #suggest-header="slotProps">
344
- <slot name="suggest-header" v-bind="slotProps" />
345
- </template>
346
- <template v-if="$slots['suggest-content']" #suggest-content="slotProps">
347
- <slot name="suggest-content" v-bind="slotProps" />
348
- </template>
349
- <template v-if="$slots['history-header']" #history-header="slotProps">
350
- <slot name="history-header" v-bind="slotProps" />
351
- </template>
352
- <template v-if="$slots['history-content']" #history-content="slotProps">
353
- <slot name="history-content" v-bind="slotProps" />
354
- </template>
355
- </SearchPanel>
356
- </slot>
357
- </div>
358
- </Transition>
359
- </div>
360
-
361
- <div v-if="suggestList?.length" class="o-search-input-suggest-list-row">
362
- <slot name="suggest-list" :items="suggestList">
363
- <span class="o-search-input-suggest-list-label">{{ suggestListLabel ?? t('search.suggestListLabel') }}</span>
364
- <ul class="o-search-input-suggest-list">
365
- <li
366
- v-for="(item, idx) in suggestList"
367
- :key="item + idx"
368
- class="o-search-input-suggest-list-item"
369
- @click="handleSuggestListClick(item)"
370
- >
371
- <span v-if="allowHtmlInSuggest" v-html="item" />
372
- <span v-else>{{ item }}</span>
373
- </li>
374
- </ul>
375
- </slot>
376
- </div>
377
- </div>
378
- </template>
379
-
380
- <style lang="scss" scoped>
381
- .o-search-input {
382
- position: relative;
383
- width: 100%;
384
- background-color: var(--o-color-fill2);
385
- border-radius: var(--o-radius-xs);
386
-
387
- // Make large size 48px tall
388
- :deep(.o-input.o_box-large) {
389
- --_box-height: 48px;
390
- }
391
- }
392
-
393
- .o-search-input-box {
394
- position: relative;
395
- width: 100%;
396
- }
397
-
398
- .o-search-input-field {
399
- width: 100%;
400
- }
401
-
402
- .o-search-input-dropdown {
403
- position: absolute;
404
- top: calc(100% + 4px);
405
- left: 0;
406
- right: 0;
407
- z-index: 10;
408
- padding: var(--o-gap-4);
409
- background-color: var(--o-color-fill2);
410
- border-radius: var(--o-radius-xs);
411
- box-shadow: var(--o-shadow-2);
412
- }
413
-
414
- .o-search-input-dropdown-enter-active,
415
- .o-search-input-dropdown-leave-active {
416
- transition: opacity var(--o-duration-m1), transform var(--o-duration-m1);
417
- }
418
-
419
- .o-search-input-dropdown-enter-from,
420
- .o-search-input-dropdown-leave-to {
421
- opacity: 0;
422
- transform: translateY(-4px);
423
- }
424
-
425
- .o-search-input-suggest-list-row {
426
- display: flex;
427
- margin-top: 8px;
428
- align-items: center;
429
- flex-wrap: wrap;
430
- @include tip1;
431
- color: var(--o-color-info1);
432
- }
433
-
434
- .o-search-input-suggest-list-label {
435
- color: var(--o-color-info3);
436
- margin-right: 4px;
437
- @include tip1;
438
- }
439
-
440
- .o-search-input-suggest-list {
441
- display: flex;
442
- flex-wrap: wrap;
443
- align-items: center;
444
- padding: 0;
445
- margin: 0;
446
- list-style: none;
447
- }
448
-
449
- .o-search-input-suggest-list-item {
450
- margin-right: 8px;
451
- cursor: pointer;
452
- color: var(--o-color-primary1);
453
-
454
- :deep(em) {
455
- color: var(--o-color-primary1);
456
- font-style: normal;
457
- }
458
-
459
- @include hover {
460
- text-decoration: underline;
461
- }
462
- }
463
- </style>