@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.
- package/dist/chunk-OElCookieNotice.cjs.js +1 -1
- package/dist/chunk-OElCookieNotice.es.js +111 -88
- package/dist/components/OHeaderSearch.vue.d.ts +814 -534
- package/dist/components/OHeaderUser.vue.d.ts +1 -1
- package/dist/components/OLanguageSwitcher.vue.d.ts +49 -0
- package/dist/components/OThemeSwitcher.vue.d.ts +2 -5
- package/dist/components/activity/OActivityMyCalendar.vue.d.ts +4 -4
- package/dist/components/activity/index.d.ts +2 -2
- package/dist/components/banner/OBanner.vue.d.ts +13 -0
- package/dist/components/banner/OBannerContent.vue.d.ts +7 -0
- package/dist/components/banner/index.d.ts +68 -0
- package/dist/components/banner/types.d.ts +31 -0
- package/dist/components/meeting/OMeetingCalendar.vue.d.ts +5 -3
- package/dist/components/meeting/OMeetingMyCalendar.vue.d.ts +4 -4
- package/dist/components/meeting/OMeetingPlayback.vue.d.ts +50 -1
- package/dist/components/meeting/components/OMeetingCalendarSelector.vue.d.ts +1 -1
- package/dist/components/meeting/components/OMeetingPlaybackSubtitles.vue.d.ts +16 -1
- package/dist/components/meeting/composables/useMeetingConfig.d.ts +1 -1
- package/dist/components/meeting/index.d.ts +347 -20
- package/dist/components/meeting/types.d.ts +1 -1
- package/dist/components/search/OSearchInput.vue.d.ts +1005 -0
- package/dist/components/search/composables/useImageSearch.d.ts +48 -0
- package/dist/components/search/composables/useKeywordHighlight.d.ts +2 -0
- package/dist/components/search/composables/useSearchHistory.d.ts +14 -0
- package/dist/components/search/index.d.ts +590 -0
- package/dist/components/search/internal/HighlightText.vue.d.ts +9 -0
- package/dist/components/search/internal/SearchImageInput.vue.d.ts +716 -0
- package/dist/components/search/internal/SearchPanel.vue.d.ts +100 -0
- package/dist/components/search/types.d.ts +20 -0
- package/dist/components.cjs.js +40 -40
- package/dist/components.css +1 -1
- package/dist/components.es.js +11352 -10056
- package/dist/index.d.ts +4 -2
- package/package.json +4 -4
- package/scripts/generate-components-index.js +1 -1
- package/src/assets/styles/element-plus.scss +16 -9
- package/src/assets/svg-icons/icon-delete-hover.svg +4 -0
- package/src/assets/svg-icons/icon-delete.svg +5 -1
- package/src/assets/svg-icons/icon-image-close.svg +4 -0
- package/src/assets/svg-icons/icon-image-upload.svg +3 -0
- package/src/assets/svg-icons/icon-image-zoomin.svg +3 -0
- package/src/assets/svg-icons/icon-refresh.svg +3 -0
- package/src/components/OHeaderSearch.vue +445 -418
- package/src/components/OLanguageSwitcher.vue +211 -0
- package/src/components/OPlusConfigProvider.vue +2 -2
- package/src/components/OThemeSwitcher.vue +51 -27
- package/src/components/activity/OActivityForm.vue +7 -3
- package/src/components/activity/OActivityMyCalendar.vue +16 -7
- package/src/components/banner/OBanner.vue +288 -0
- package/src/components/banner/OBannerContent.vue +175 -0
- package/src/components/banner/index.ts +18 -0
- package/src/components/banner/types.ts +39 -0
- package/src/components/header/OHeader.vue +1 -1
- package/src/components/meeting/OMeetingCalendar.vue +11 -6
- package/src/components/meeting/OMeetingForm.vue +55 -9
- package/src/components/meeting/OMeetingMyCalendar.vue +17 -14
- package/src/components/meeting/OMeetingPlayback.vue +10 -4
- package/src/components/meeting/OMeetingSigCalendar.vue +1 -1
- package/src/components/meeting/components/OMeetingCalendarList.vue +57 -21
- package/src/components/meeting/components/OMeetingCalendarSelector.vue +11 -8
- package/src/components/meeting/components/OMeetingDetail.vue +1 -1
- package/src/components/meeting/components/OMeetingPlaybackSubtitles.vue +7 -4
- package/src/components/meeting/composables/useMeetingConfig.ts +5 -5
- package/src/components/meeting/index.ts +2 -2
- package/src/components/meeting/types.ts +1 -1
- package/src/components/search/OSearchInput.vue +526 -0
- package/src/components/search/composables/useImageSearch.ts +157 -0
- package/src/components/search/composables/useKeywordHighlight.ts +30 -0
- package/src/components/search/composables/useSearchHistory.ts +75 -0
- package/src/components/search/index.ts +23 -0
- package/src/components/search/internal/HighlightText.vue +37 -0
- package/src/components/search/internal/SearchImageInput.vue +498 -0
- package/src/components/search/internal/SearchPanel.vue +431 -0
- package/src/components/search/types.ts +25 -0
- package/src/i18n/en.ts +13 -1
- package/src/i18n/zh.ts +14 -3
- package/src/index.ts +5 -3
- package/vite.config.ts +4 -0
- package/dist/components/OBanner.vue.d.ts +0 -11
- package/src/components/OBanner.vue +0 -398
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed,
|
|
3
|
-
import { OIcon
|
|
4
|
-
import { onClickOutside } from '@vueuse/core';
|
|
2
|
+
import { computed, ref, toRef, watch } from 'vue';
|
|
3
|
+
import { OIcon } from '@opensig/opendesign';
|
|
4
|
+
import { onClickOutside, useDebounceFn } from '@vueuse/core';
|
|
5
5
|
import { useScreen } from '@opendesign-plus/composables';
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import SearchImageInput from './search/internal/SearchImageInput.vue';
|
|
8
|
+
import SearchPanel from './search/internal/SearchPanel.vue';
|
|
9
|
+
import { useSearchHistory } from './search/composables/useSearchHistory';
|
|
10
|
+
import { useI18n } from '@/i18n';
|
|
11
|
+
import type {
|
|
12
|
+
OSearchPayload,
|
|
13
|
+
OSearchRecommendItem,
|
|
14
|
+
OSearchUploadImageFn,
|
|
15
|
+
} from './search/types';
|
|
16
|
+
|
|
8
17
|
import IconSearch from '~icons/components/icon-header-search.svg';
|
|
9
|
-
import IconDelete from '~icons/components/icon-header-delete.svg';
|
|
10
|
-
import IconDeleteAll from '~icons/components/icon-delete.svg';
|
|
11
18
|
import IconBack from '~icons/components/icon-header-back.svg';
|
|
12
19
|
|
|
13
|
-
import { useI18n } from '@/i18n';
|
|
14
|
-
|
|
15
20
|
export interface OHeaderSearchPropsT {
|
|
21
|
+
/** ---- Backward-compatible props ---- */
|
|
16
22
|
modelValue?: string;
|
|
17
23
|
placeholder?: string; // 搜索框默认提示
|
|
18
24
|
expandedPlaceholder?: string; // 搜索框展开后提示
|
|
@@ -20,28 +26,39 @@ export interface OHeaderSearchPropsT {
|
|
|
20
26
|
clearable?: boolean; // 是否显示清除按钮,默认显示
|
|
21
27
|
historyItems?: string[]; // 搜索历史记录
|
|
22
28
|
maxHistoryCount?: number; // 最多保存的搜索历史记录数,默认 6 条
|
|
23
|
-
storeHistory?: boolean; // 是否使用 localStorage 存储搜索历史记录,存储之后初始化时会自动加载搜索历史记录,默认为 false
|
|
29
|
+
storeHistory?: boolean; // 是否使用 localStorage 存储搜索历史记录,存储之后初始化时会自动加载搜索历史记录,默认为 false
|
|
24
30
|
historyTitle?: string; // 历史记录标题
|
|
25
31
|
storageKey?: string; // localStorage 存储搜索历史记录的 key,默认为 search-history
|
|
26
32
|
hotItems?: string[]; // 热门搜索
|
|
27
33
|
hotTitle?: string; // 推荐搜索标题
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
/** Legacy plain-string recommend list. Shown when input is empty. */
|
|
35
|
+
recommendItems?: string[];
|
|
36
|
+
searchUrl?: string;
|
|
37
|
+
searchUrlOpenBlank?: boolean;
|
|
38
|
+
searchTextMobile?: string;
|
|
39
|
+
imagePlaceholder?: string;
|
|
40
|
+
enableImageSearch?: boolean;
|
|
41
|
+
imageUrl?: string;
|
|
42
|
+
uploadImage?: OSearchUploadImageFn;
|
|
43
|
+
maxImageSize?: number;
|
|
44
|
+
imageUploadTooltip?: string;
|
|
45
|
+
suggestItems?: OSearchRecommendItem[];
|
|
46
|
+
onestepItems?: OSearchRecommendItem[];
|
|
47
|
+
suggestTitle?: string;
|
|
48
|
+
onestepTitle?: string;
|
|
49
|
+
noDataText?: string;
|
|
50
|
+
highlightKeyword?: boolean;
|
|
51
|
+
/** Debounce ms for the `input` event */
|
|
52
|
+
debounce?: number;
|
|
53
|
+
/** Auto-record history on search; default true */
|
|
54
|
+
autoSaveHistory?: boolean;
|
|
55
|
+
/** Show "no data" empty state in suggest section while typing */
|
|
56
|
+
showSuggestEmpty?: boolean;
|
|
57
|
+
allowedImageTypes?: string[];
|
|
58
|
+
/** 强制指定移动端模式,不传时由内部 lePadV 断点自动判断 */
|
|
59
|
+
mobile?: boolean;
|
|
32
60
|
}
|
|
33
61
|
|
|
34
|
-
export interface OHeaderSearchEmitsT {
|
|
35
|
-
(e: 'update:modelValue', value: string): void;
|
|
36
|
-
(e: 'update:historyItems', value: string[]): void;
|
|
37
|
-
(e: 'clear'): void;
|
|
38
|
-
(e: 'search', value: string): void;
|
|
39
|
-
(e: 'delete-history', value: string[]): void;
|
|
40
|
-
(e: 'delete-history-item', value: string): void;
|
|
41
|
-
}
|
|
42
|
-
const { lePadV } = useScreen();
|
|
43
|
-
const { t } = useI18n();
|
|
44
|
-
|
|
45
62
|
const props = withDefaults(defineProps<OHeaderSearchPropsT>(), {
|
|
46
63
|
modelValue: '',
|
|
47
64
|
expandDirection: 'left',
|
|
@@ -53,235 +70,354 @@ const props = withDefaults(defineProps<OHeaderSearchPropsT>(), {
|
|
|
53
70
|
hotItems: () => [],
|
|
54
71
|
recommendItems: () => [],
|
|
55
72
|
searchUrlOpenBlank: true,
|
|
73
|
+
enableImageSearch: false,
|
|
74
|
+
imageUrl: '',
|
|
75
|
+
maxImageSize: 10 * 1024 * 1024,
|
|
76
|
+
suggestItems: () => [],
|
|
77
|
+
onestepItems: () => [],
|
|
78
|
+
highlightKeyword: true,
|
|
79
|
+
debounce: 300,
|
|
80
|
+
autoSaveHistory: true,
|
|
81
|
+
showSuggestEmpty: true,
|
|
56
82
|
});
|
|
57
83
|
|
|
58
|
-
const emit = defineEmits<
|
|
84
|
+
const emit = defineEmits<{
|
|
85
|
+
(e: 'update:modelValue', value: string): void;
|
|
86
|
+
(e: 'update:historyItems', value: string[]): void;
|
|
87
|
+
(e: 'update:imageUrl', url: string): void;
|
|
88
|
+
(e: 'focus'): void;
|
|
89
|
+
(e: 'blur'): void;
|
|
90
|
+
(e: 'input', val: string): void;
|
|
91
|
+
(e: 'clear'): void;
|
|
92
|
+
/** Backward compatible: previously `(val: string)`. Now emits payload. */
|
|
93
|
+
(e: 'search', payload: OSearchPayload): void;
|
|
94
|
+
(e: 'recommend-click', item: OSearchRecommendItem | string): void;
|
|
95
|
+
(e: 'onestep-click', item: OSearchRecommendItem): void;
|
|
96
|
+
(e: 'history-click', val: string): void;
|
|
97
|
+
(e: 'hot-click', val: string): void;
|
|
98
|
+
(e: 'hot-refresh'): void;
|
|
99
|
+
(e: 'delete-history', value: string[]): void;
|
|
100
|
+
(e: 'delete-history-item', value: string): void;
|
|
101
|
+
(e: 'image-upload-start', file: File): void;
|
|
102
|
+
(e: 'image-upload-success', url: string, file: File): void;
|
|
103
|
+
(e: 'image-upload-error', error: unknown, file: File): void;
|
|
104
|
+
(e: 'image-validate-error', reason: 'size' | 'type', file: File): void;
|
|
105
|
+
}>();
|
|
59
106
|
|
|
60
|
-
const
|
|
61
|
-
const
|
|
107
|
+
const { lePadV } = useScreen();
|
|
108
|
+
const { t } = useI18n();
|
|
109
|
+
|
|
110
|
+
// mobile=true → 强制移动端;未传或 false → 回退到内部断点 lePadV
|
|
111
|
+
const isMobileMode = computed(() => props.mobile === true || lePadV.value);
|
|
112
|
+
|
|
113
|
+
const wrapperRef = ref<HTMLElement | null>(null);
|
|
114
|
+
const inputRef = ref<InstanceType<typeof SearchImageInput>>();
|
|
62
115
|
const isShowDrawer = ref(false);
|
|
63
|
-
const
|
|
116
|
+
const internalImageStaged = ref(false);
|
|
117
|
+
const internalImageUrl = ref('');
|
|
118
|
+
const hasImage = computed(() => !!props.imageUrl || internalImageStaged.value);
|
|
64
119
|
|
|
65
|
-
const
|
|
66
|
-
|
|
120
|
+
const innerValue = computed({
|
|
121
|
+
get: () => props.modelValue,
|
|
122
|
+
set: (val: string) => emit('update:modelValue', val),
|
|
67
123
|
});
|
|
68
124
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
() =>
|
|
80
|
-
|
|
81
|
-
emit('update:modelValue', val);
|
|
82
|
-
}
|
|
83
|
-
);
|
|
125
|
+
const historyItemsRef = toRef(props, 'historyItems');
|
|
126
|
+
const storageKeyRef = toRef(props, 'storageKey');
|
|
127
|
+
const storeHistoryRef = toRef(props, 'storeHistory');
|
|
128
|
+
const maxHistoryRef = toRef(props, 'maxHistoryCount');
|
|
129
|
+
|
|
130
|
+
const history = useSearchHistory({
|
|
131
|
+
initial: historyItemsRef,
|
|
132
|
+
storageKey: storageKeyRef,
|
|
133
|
+
storeHistory: storeHistoryRef,
|
|
134
|
+
maxHistoryCount: maxHistoryRef,
|
|
135
|
+
onChange: (items) => emit('update:historyItems', items),
|
|
136
|
+
});
|
|
84
137
|
|
|
85
|
-
|
|
86
|
-
()
|
|
87
|
-
|
|
88
|
-
if (searchHistoryItems.value !== val) {
|
|
89
|
-
searchHistoryItems.value = val;
|
|
90
|
-
}
|
|
138
|
+
const placeholder = computed(() => {
|
|
139
|
+
if (props.imageUrl) {
|
|
140
|
+
return props.imagePlaceholder ?? t('search.extendedPlaceholder');
|
|
91
141
|
}
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
watch(
|
|
95
|
-
() => searchHistoryItems.value,
|
|
96
|
-
(val) => {
|
|
97
|
-
emit('update:historyItems', val);
|
|
142
|
+
if (isShowDrawer.value && props.enableImageSearch) {
|
|
143
|
+
return props.imagePlaceholder ?? t('search.imagePlaceholder');
|
|
98
144
|
}
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
onMounted(() => {
|
|
102
|
-
if (props.storeHistory && props.storageKey) {
|
|
103
|
-
try {
|
|
104
|
-
const history = JSON.parse(localStorage.getItem(props.storageKey) || '[]');
|
|
105
|
-
if (Array.isArray(history) && history.length) {
|
|
106
|
-
searchHistoryItems.value = Array.from(new Set([...searchHistoryItems.value, ...history]));
|
|
107
|
-
}
|
|
108
|
-
} catch {
|
|
109
|
-
// nothing
|
|
110
|
-
}
|
|
145
|
+
if (isShowDrawer.value) {
|
|
146
|
+
return props.expandedPlaceholder ?? t('search.expandedPlaceholder');
|
|
111
147
|
}
|
|
148
|
+
return props.placeholder ?? t('search.placeholder');
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// debounce input event
|
|
152
|
+
const emitInputDebounced = useDebounceFn((val: string) => emit('input', val), () => props.debounce);
|
|
153
|
+
watch(innerValue, (val) => emitInputDebounced(val));
|
|
154
|
+
|
|
155
|
+
// click outside (desktop only)
|
|
156
|
+
onClickOutside(wrapperRef, () => {
|
|
157
|
+
if (isMobileMode.value) return;
|
|
158
|
+
closeDrawer();
|
|
112
159
|
});
|
|
113
160
|
|
|
114
|
-
const
|
|
161
|
+
const openDrawer = () => {
|
|
115
162
|
isShowDrawer.value = true;
|
|
116
163
|
};
|
|
117
164
|
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
if (!input) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
|
|
165
|
+
const closeDrawer = () => {
|
|
166
|
+
if (isMobileMode.value) return;
|
|
124
167
|
isShowDrawer.value = false;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const handleFocus = () => {
|
|
171
|
+
openDrawer();
|
|
172
|
+
emit('focus');
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const handleBlur = () => {
|
|
176
|
+
emit('blur');
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const runSearch = async (overrideKeyword?: string) => {
|
|
180
|
+
if (inputRef.value?.getIsUploading?.()) {
|
|
181
|
+
await inputRef.value.awaitUpload?.();
|
|
129
182
|
}
|
|
183
|
+
const keyword = overrideKeyword !== undefined ? overrideKeyword.trim() : innerValue.value.trim();
|
|
184
|
+
const imageUrl = internalImageUrl.value || inputRef.value?.getUploadedUrl?.() || props.imageUrl;
|
|
130
185
|
|
|
131
|
-
if (
|
|
132
|
-
|
|
186
|
+
if (!keyword && !imageUrl) return;
|
|
187
|
+
|
|
188
|
+
if (props.autoSaveHistory && keyword) {
|
|
189
|
+
history.push(keyword);
|
|
133
190
|
}
|
|
134
|
-
|
|
191
|
+
|
|
192
|
+
emit('search', { keyword, imageUrl: imageUrl || undefined });
|
|
193
|
+
inputRef.value?.blur?.();
|
|
194
|
+
isShowDrawer.value = false;
|
|
135
195
|
|
|
136
196
|
if (props.searchUrl) {
|
|
137
|
-
|
|
197
|
+
const params = new URLSearchParams();
|
|
198
|
+
if (keyword) params.set('q', keyword);
|
|
199
|
+
if (imageUrl) params.set('imageUrl', imageUrl);
|
|
200
|
+
const sep = props.searchUrl.includes('?') ? '&' : '?';
|
|
201
|
+
const url = `${props.searchUrl}${sep}${params.toString()}`;
|
|
202
|
+
if (typeof window !== 'undefined') {
|
|
203
|
+
window.open(url, props.searchUrlOpenBlank ? '_blank' : '_self', props.searchUrlOpenBlank ? 'noopener,noreferrer' : '');
|
|
204
|
+
}
|
|
138
205
|
}
|
|
139
206
|
};
|
|
140
207
|
|
|
141
|
-
const
|
|
142
|
-
|
|
208
|
+
const handleClear = () => {
|
|
209
|
+
innerValue.value = '';
|
|
143
210
|
emit('clear');
|
|
144
|
-
|
|
145
|
-
isShowDrawer.value = false;
|
|
146
|
-
}
|
|
211
|
+
inputRef.value?.focus?.();
|
|
147
212
|
};
|
|
148
213
|
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
214
|
+
const handleSuggestClick = (item: OSearchRecommendItem) => {
|
|
215
|
+
emit('recommend-click', item);
|
|
216
|
+
innerValue.value = item.key;
|
|
217
|
+
runSearch();
|
|
218
|
+
};
|
|
155
219
|
|
|
156
|
-
|
|
220
|
+
const handleRecommendClick = (val: string) => {
|
|
221
|
+
emit('recommend-click', val);
|
|
222
|
+
runSearch(val);
|
|
157
223
|
};
|
|
158
224
|
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
if (
|
|
162
|
-
|
|
163
|
-
localStorage.setItem(props.storageKey, JSON.stringify(searchHistoryItems.value));
|
|
164
|
-
} else {
|
|
165
|
-
localStorage.removeItem(props.storageKey);
|
|
166
|
-
}
|
|
225
|
+
const handleOnestepClick = (item: OSearchRecommendItem) => {
|
|
226
|
+
emit('onestep-click', item);
|
|
227
|
+
if (item.path && typeof window !== 'undefined') {
|
|
228
|
+
window.open(item.path, '_blank', 'noopener,noreferrer');
|
|
167
229
|
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const handleHistoryClick = (val: string) => {
|
|
233
|
+
emit('history-click', val);
|
|
234
|
+
runSearch(val);
|
|
235
|
+
};
|
|
168
236
|
|
|
237
|
+
const handleHotClick = (val: string) => {
|
|
238
|
+
emit('hot-click', val);
|
|
239
|
+
runSearch(val);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const handleHistoryRemove = (val: string) => {
|
|
243
|
+
history.remove(val);
|
|
169
244
|
emit('delete-history-item', val);
|
|
170
245
|
};
|
|
171
246
|
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
247
|
+
const handleHistoryClear = () => {
|
|
248
|
+
const removed = [...history.items.value];
|
|
249
|
+
history.clearAll();
|
|
250
|
+
emit('delete-history', removed);
|
|
175
251
|
};
|
|
176
252
|
|
|
177
|
-
const
|
|
178
|
-
|
|
253
|
+
const handleBack = () => {
|
|
254
|
+
innerValue.value = '';
|
|
255
|
+
internalImageStaged.value = false;
|
|
256
|
+
emit('update:imageUrl', '');
|
|
179
257
|
isShowDrawer.value = false;
|
|
180
258
|
};
|
|
181
259
|
|
|
182
|
-
const
|
|
183
|
-
|
|
260
|
+
const handleImageUploadStart = (file: File) => {
|
|
261
|
+
internalImageStaged.value = true;
|
|
262
|
+
internalImageUrl.value = '';
|
|
263
|
+
emit('image-upload-start', file);
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const handleImageUploadSuccess = (url: string, file: File) => {
|
|
267
|
+
internalImageUrl.value = url;
|
|
268
|
+
emit('update:imageUrl', url);
|
|
269
|
+
emit('image-upload-success', url, file);
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const handleImageClear = () => {
|
|
273
|
+
internalImageStaged.value = false;
|
|
274
|
+
internalImageUrl.value = '';
|
|
275
|
+
emit('update:imageUrl', '');
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const showPanel = computed(() => {
|
|
279
|
+
if (!isShowDrawer.value) return false;
|
|
280
|
+
if (hasImage.value) return false;
|
|
281
|
+
return true;
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
defineExpose({
|
|
285
|
+
focus: () => inputRef.value?.focus?.(),
|
|
286
|
+
blur: () => inputRef.value?.blur?.(),
|
|
287
|
+
open: openDrawer,
|
|
288
|
+
close: closeDrawer,
|
|
289
|
+
search: runSearch,
|
|
290
|
+
});
|
|
184
291
|
</script>
|
|
185
292
|
|
|
186
293
|
<template>
|
|
187
|
-
<div class="o-header-search">
|
|
294
|
+
<div class="o-header-search" :class="{ 'is-mobile-mode': isMobileMode }">
|
|
188
295
|
<div
|
|
189
|
-
ref="
|
|
296
|
+
ref="wrapperRef"
|
|
297
|
+
class="o-header-search-pos"
|
|
190
298
|
:class="{
|
|
191
|
-
'
|
|
192
|
-
'
|
|
193
|
-
'
|
|
194
|
-
'
|
|
195
|
-
focus: isShowDrawer,
|
|
299
|
+
'is-pc': !isMobileMode,
|
|
300
|
+
'is-mobile': isMobileMode,
|
|
301
|
+
'is-left': expandDirection === 'left',
|
|
302
|
+
'is-right': expandDirection === 'right',
|
|
303
|
+
'is-focus': isShowDrawer,
|
|
196
304
|
}"
|
|
197
305
|
>
|
|
198
|
-
<div class="o-header-search-
|
|
199
|
-
<OIcon v-if="
|
|
306
|
+
<div class="o-header-search-row" :class="{ 'is-focus': isShowDrawer }">
|
|
307
|
+
<OIcon v-if="isMobileMode && isShowDrawer" class="o-header-search-back-icon" @click="handleBack">
|
|
200
308
|
<IconBack />
|
|
201
309
|
</OIcon>
|
|
202
310
|
|
|
203
|
-
<
|
|
311
|
+
<SearchImageInput
|
|
204
312
|
ref="inputRef"
|
|
205
|
-
v-model="
|
|
313
|
+
v-model="innerValue"
|
|
314
|
+
:image-url="imageUrl"
|
|
315
|
+
:placeholder="placeholder"
|
|
316
|
+
:enable-image-search="enableImageSearch"
|
|
317
|
+
:upload-image="uploadImage"
|
|
318
|
+
:max-image-size="maxImageSize"
|
|
319
|
+
:image-upload-tooltip="imageUploadTooltip"
|
|
320
|
+
:clearable="clearable && isShowDrawer"
|
|
321
|
+
:expanded="isShowDrawer && hasImage"
|
|
322
|
+
:allowed-image-types="allowedImageTypes"
|
|
323
|
+
size="medium"
|
|
206
324
|
class="o-header-search-input"
|
|
207
|
-
:
|
|
208
|
-
@
|
|
209
|
-
@
|
|
325
|
+
:class="{ 'is-collapsed': !isShowDrawer }"
|
|
326
|
+
@update:imageUrl="(url: string) => emit('update:imageUrl', url)"
|
|
327
|
+
@focus="handleFocus"
|
|
328
|
+
@blur="handleBlur"
|
|
329
|
+
@enter="runSearch"
|
|
330
|
+
@clear="handleClear"
|
|
331
|
+
@image-clear="handleImageClear"
|
|
332
|
+
@image-upload-start="handleImageUploadStart"
|
|
333
|
+
@image-upload-success="handleImageUploadSuccess"
|
|
334
|
+
@image-upload-error="(error: unknown, file: File) => emit('image-upload-error', error, file)"
|
|
335
|
+
@image-validate-error="(reason: 'size' | 'type', file: File) => emit('image-validate-error', reason, file)"
|
|
210
336
|
>
|
|
211
|
-
<template #prefix>
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
</OIcon>
|
|
216
|
-
</slot>
|
|
217
|
-
</template>
|
|
218
|
-
|
|
219
|
-
<template #suffix>
|
|
220
|
-
<slot name="input-suffix">
|
|
221
|
-
<OIcon v-if="clearable && isShowClearIcon" class="o-header-search-icon close" @click="onClear">
|
|
222
|
-
<IconClose />
|
|
223
|
-
</OIcon>
|
|
224
|
-
</slot>
|
|
337
|
+
<template #prefix><slot name="input-prefix" /></template>
|
|
338
|
+
<template #suffix="slotProps"><slot name="input-suffix" v-bind="slotProps" /></template>
|
|
339
|
+
<template v-if="$slots['image-preview']" #preview="slotProps">
|
|
340
|
+
<slot name="image-preview" v-bind="slotProps" />
|
|
225
341
|
</template>
|
|
226
|
-
</
|
|
342
|
+
</SearchImageInput>
|
|
227
343
|
|
|
228
|
-
<span v-if="
|
|
344
|
+
<span v-if="isMobileMode && isShowDrawer" class="o-header-search-text" @click="runSearch">
|
|
345
|
+
{{ searchTextMobile ?? t('search') }}
|
|
346
|
+
</span>
|
|
229
347
|
</div>
|
|
230
348
|
|
|
231
|
-
<
|
|
232
|
-
<
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
<
|
|
276
|
-
<
|
|
277
|
-
</
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
349
|
+
<Transition name="o-header-search-drawer">
|
|
350
|
+
<div v-if="showPanel" class="o-header-search-drawer">
|
|
351
|
+
<slot
|
|
352
|
+
name="drawer"
|
|
353
|
+
:recommend-items="recommendItems"
|
|
354
|
+
:history-items="history.items.value"
|
|
355
|
+
:hot-items="hotItems"
|
|
356
|
+
:suggest-items="suggestItems"
|
|
357
|
+
:onestep-items="onestepItems"
|
|
358
|
+
:keyword="modelValue"
|
|
359
|
+
>
|
|
360
|
+
<SearchPanel
|
|
361
|
+
:keyword="modelValue"
|
|
362
|
+
:onestep-items="onestepItems"
|
|
363
|
+
:onestep-title="onestepTitle"
|
|
364
|
+
:suggest-items="suggestItems"
|
|
365
|
+
:suggest-title="suggestTitle"
|
|
366
|
+
:recommend-items="recommendItems"
|
|
367
|
+
:history-items="history.items.value"
|
|
368
|
+
:history-title="historyTitle"
|
|
369
|
+
:hot-items="hotItems"
|
|
370
|
+
:hot-title="hotTitle"
|
|
371
|
+
:no-data-text="noDataText"
|
|
372
|
+
:highlight-keyword="highlightKeyword"
|
|
373
|
+
:hide-on-keyword="true"
|
|
374
|
+
:show-suggest-empty="showSuggestEmpty"
|
|
375
|
+
@onestep-click="handleOnestepClick"
|
|
376
|
+
@suggest-click="handleSuggestClick"
|
|
377
|
+
@recommend-click="handleRecommendClick"
|
|
378
|
+
@history-click="handleHistoryClick"
|
|
379
|
+
@history-remove="handleHistoryRemove"
|
|
380
|
+
@history-clear="handleHistoryClear"
|
|
381
|
+
@hot-click="handleHotClick"
|
|
382
|
+
@hot-refresh="emit('hot-refresh')"
|
|
383
|
+
>
|
|
384
|
+
<template v-if="$slots['recommend-header']" #recommend-header="slotProps">
|
|
385
|
+
<slot name="recommend-header" v-bind="slotProps" />
|
|
386
|
+
</template>
|
|
387
|
+
<template v-if="$slots['recommend-content']" #recommend-content="slotProps">
|
|
388
|
+
<slot name="recommend-content" v-bind="slotProps" />
|
|
389
|
+
</template>
|
|
390
|
+
<template v-if="$slots['onestep-header']" #onestep-header="slotProps">
|
|
391
|
+
<slot name="onestep-header" v-bind="slotProps" />
|
|
392
|
+
</template>
|
|
393
|
+
<template v-if="$slots['onestep-content']" #onestep-content="slotProps">
|
|
394
|
+
<slot name="onestep-content" v-bind="slotProps" />
|
|
395
|
+
</template>
|
|
396
|
+
<template v-if="$slots['suggest-header']" #suggest-header="slotProps">
|
|
397
|
+
<slot name="suggest-header" v-bind="slotProps" />
|
|
398
|
+
</template>
|
|
399
|
+
<template v-if="$slots['suggest-content']" #suggest-content="slotProps">
|
|
400
|
+
<slot name="suggest-content" v-bind="slotProps" />
|
|
401
|
+
</template>
|
|
402
|
+
<template v-if="$slots['history-header']" #history-header="slotProps">
|
|
403
|
+
<slot name="history-header" v-bind="slotProps" />
|
|
404
|
+
</template>
|
|
405
|
+
<template v-if="$slots['history-content']" #history-content="slotProps">
|
|
406
|
+
<slot name="history-content" v-bind="slotProps" />
|
|
407
|
+
</template>
|
|
408
|
+
<template v-if="$slots['hot-header']" #hot-header="slotProps">
|
|
409
|
+
<slot name="hot-header" v-bind="slotProps" />
|
|
410
|
+
</template>
|
|
411
|
+
<template v-if="$slots['hot-content']" #hot-content="slotProps">
|
|
412
|
+
<slot name="hot-content" v-bind="slotProps" />
|
|
413
|
+
</template>
|
|
414
|
+
</SearchPanel>
|
|
415
|
+
</slot>
|
|
416
|
+
</div>
|
|
417
|
+
</Transition>
|
|
282
418
|
</div>
|
|
283
419
|
|
|
284
|
-
<OIcon v-if="
|
|
420
|
+
<OIcon v-if="isMobileMode" class="o-header-search-mobile-icon" @click="openDrawer">
|
|
285
421
|
<IconSearch />
|
|
286
422
|
</OIcon>
|
|
287
423
|
</div>
|
|
@@ -293,133 +429,132 @@ onClickOutside(posWrapper, onClear);
|
|
|
293
429
|
width: 160px;
|
|
294
430
|
height: 32px;
|
|
295
431
|
|
|
296
|
-
@include respond('<=laptop') {
|
|
432
|
+
@include respond-to('<=laptop') {
|
|
297
433
|
width: 120px;
|
|
298
434
|
}
|
|
299
435
|
|
|
300
|
-
@
|
|
436
|
+
@include respond-to('<=pad_v') {
|
|
301
437
|
width: 24px;
|
|
302
438
|
height: 24px;
|
|
439
|
+
margin-left: auto;
|
|
303
440
|
}
|
|
304
441
|
}
|
|
305
442
|
|
|
306
|
-
.o-header-search-
|
|
307
|
-
cursor: pointer;
|
|
308
|
-
color: var(--o-color-info1);
|
|
309
|
-
@include h4;
|
|
310
|
-
|
|
311
|
-
@include respond('<=pad_v') {
|
|
312
|
-
font-size: 20px;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
.close {
|
|
316
|
-
@include x-svg-hover;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
.o-header-search-icon-mobile {
|
|
321
|
-
font-size: 24px;
|
|
322
|
-
line-height: 28px;
|
|
323
|
-
color: var(--o-color-info1);
|
|
324
|
-
cursor: pointer;
|
|
325
|
-
display: none;
|
|
326
|
-
|
|
327
|
-
@include respond('<=pad_v') {
|
|
328
|
-
display: block;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
.o-header-search-input-pc-wrapper {
|
|
443
|
+
.o-header-search-pos {
|
|
333
444
|
position: absolute;
|
|
334
|
-
right: 0;
|
|
335
445
|
top: 0;
|
|
336
446
|
width: fit-content;
|
|
337
447
|
background-color: var(--o-color-fill2);
|
|
338
448
|
z-index: 100;
|
|
339
|
-
}
|
|
340
449
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
450
|
+
&.is-left {
|
|
451
|
+
right: 0;
|
|
452
|
+
}
|
|
453
|
+
&.is-right {
|
|
454
|
+
left: 0;
|
|
455
|
+
}
|
|
456
|
+
&.is-mobile {
|
|
457
|
+
display: none;
|
|
458
|
+
}
|
|
459
|
+
&.is-pc.is-focus {
|
|
460
|
+
box-shadow: var(--o-shadow-2);
|
|
461
|
+
top: calc(-1 * var(--o-gap-4));
|
|
462
|
+
border-radius: var(--o-radius-xs);
|
|
463
|
+
}
|
|
344
464
|
|
|
345
|
-
.
|
|
346
|
-
|
|
465
|
+
&.is-mobile.is-focus {
|
|
466
|
+
position: fixed;
|
|
467
|
+
top: 0;
|
|
468
|
+
right: 0;
|
|
469
|
+
bottom: 0;
|
|
470
|
+
left: 0;
|
|
471
|
+
width: 100%;
|
|
472
|
+
display: block;
|
|
473
|
+
height: 100vh;
|
|
474
|
+
background-color: var(--o-color-fill2);
|
|
475
|
+
z-index: 100;
|
|
476
|
+
overflow-y: auto;
|
|
477
|
+
}
|
|
347
478
|
}
|
|
348
479
|
|
|
349
|
-
.o-header-search-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
480
|
+
.o-header-search-row {
|
|
481
|
+
display: flex;
|
|
482
|
+
align-items: start;
|
|
353
483
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
484
|
+
&.is-focus {
|
|
485
|
+
padding: var(--o-gap-4);
|
|
486
|
+
border-radius: var(--o-radius-xs);
|
|
357
487
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
display: block;
|
|
365
|
-
height: 100vh;
|
|
366
|
-
background-color: var(--o-color-fill2);
|
|
367
|
-
z-index: 100;
|
|
368
|
-
overflow: hidden;
|
|
488
|
+
@include respond-to('<=pad_v') {
|
|
489
|
+
gap: var(--o-gap-4);
|
|
490
|
+
padding: 10px var(--o-gap-4) var(--o-gap-4) var(--o-gap-4);
|
|
491
|
+
border-radius: unset;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
369
494
|
}
|
|
370
495
|
|
|
371
|
-
.o-header-search-input
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
transition: width var(--o-easing-standard-in) var(--o-duration-m2);
|
|
496
|
+
.o-header-search-input {
|
|
497
|
+
width: 160px;
|
|
498
|
+
transition: width var(--o-duration-m2) var(--o-easing-standard-in);
|
|
375
499
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
}
|
|
500
|
+
@include respond-to('<=laptop') {
|
|
501
|
+
width: 120px;
|
|
379
502
|
}
|
|
380
503
|
}
|
|
381
504
|
|
|
382
|
-
.o-header-search-
|
|
383
|
-
|
|
505
|
+
.o-header-search-row.is-focus .o-header-search-input {
|
|
506
|
+
width: 480px;
|
|
384
507
|
|
|
385
|
-
@include respond('
|
|
386
|
-
|
|
387
|
-
align-items: center;
|
|
388
|
-
gap: var(--o-gap-4);
|
|
389
|
-
padding: 10px var(--o-gap-4) var(--o-gap-4) var(--o-gap-4);
|
|
508
|
+
@include respond-to('laptop') {
|
|
509
|
+
width: 360px;
|
|
390
510
|
}
|
|
391
511
|
|
|
392
|
-
|
|
393
|
-
width:
|
|
394
|
-
|
|
395
|
-
@include respond('<=laptop') {
|
|
396
|
-
width: 240px;
|
|
397
|
-
}
|
|
512
|
+
@include respond-to('pad_h') {
|
|
513
|
+
width: 272px;
|
|
514
|
+
}
|
|
398
515
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
516
|
+
@include respond-to('<=pad_v') {
|
|
517
|
+
flex: 1;
|
|
518
|
+
width: auto;
|
|
402
519
|
}
|
|
403
520
|
}
|
|
404
521
|
|
|
405
|
-
.o-header-search-icon
|
|
406
|
-
|
|
522
|
+
.o-header-search-back-icon {
|
|
523
|
+
cursor: pointer;
|
|
524
|
+
color: var(--o-color-info1);
|
|
525
|
+
font-size: 20px;
|
|
526
|
+
height: 30px;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.o-header-search-text {
|
|
530
|
+
white-space: nowrap;
|
|
531
|
+
font-size: 16px;
|
|
532
|
+
line-height: 24px;
|
|
533
|
+
cursor: pointer;
|
|
534
|
+
color: var(--o-color-info1);
|
|
535
|
+
height: 30px;
|
|
536
|
+
|
|
537
|
+
@include hover {
|
|
538
|
+
color: var(--o-color-primary1);
|
|
539
|
+
}
|
|
407
540
|
}
|
|
408
541
|
|
|
409
542
|
.o-header-search-drawer {
|
|
410
543
|
position: absolute;
|
|
411
544
|
width: 100%;
|
|
412
|
-
padding: var(--o-gap-
|
|
413
|
-
padding-top:
|
|
545
|
+
padding: var(--o-gap-4);
|
|
546
|
+
padding-top: 0;
|
|
414
547
|
background-color: var(--o-color-fill2);
|
|
415
548
|
box-shadow: var(--o-shadow-2);
|
|
549
|
+
border-radius: 0 0 var(--o-radius-xs) var(--o-radius-xs);
|
|
416
550
|
|
|
417
|
-
@include respond('<=pad_v') {
|
|
551
|
+
@include respond-to('<=pad_v') {
|
|
418
552
|
position: static;
|
|
419
553
|
height: calc(100vh - 50px);
|
|
420
554
|
padding-top: 0;
|
|
421
555
|
overflow-y: auto;
|
|
422
556
|
box-shadow: unset;
|
|
557
|
+
border-radius: unset;
|
|
423
558
|
}
|
|
424
559
|
}
|
|
425
560
|
|
|
@@ -428,174 +563,66 @@ onClickOutside(posWrapper, onClear);
|
|
|
428
563
|
position: absolute;
|
|
429
564
|
left: 0;
|
|
430
565
|
right: 0;
|
|
431
|
-
top: -
|
|
432
|
-
height:
|
|
566
|
+
top: calc(-1 * var(--o-gap-4));
|
|
567
|
+
height: calc(var(--o-gap-4) + 1px);
|
|
433
568
|
background-color: var(--o-color-fill2);
|
|
434
|
-
box-shadow: unset;
|
|
435
569
|
|
|
436
|
-
@include respond('<=
|
|
437
|
-
top: -10px;
|
|
438
|
-
height: 10px;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
@include respond('<=pad') {
|
|
442
|
-
top: -8px;
|
|
443
|
-
height: 8px;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
@include respond('<=pad_v') {
|
|
570
|
+
@include respond-to('<=pad_v') {
|
|
447
571
|
display: none;
|
|
448
572
|
}
|
|
449
573
|
}
|
|
450
574
|
|
|
451
|
-
.o-header-search-
|
|
575
|
+
.o-header-search-mobile-icon {
|
|
576
|
+
font-size: 24px;
|
|
577
|
+
line-height: 28px;
|
|
452
578
|
color: var(--o-color-info1);
|
|
453
|
-
margin-bottom: var(--o-gap-3);
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
.o-header-search-recommend-item {
|
|
457
579
|
cursor: pointer;
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
@include hover {
|
|
461
|
-
color: var(--o-color-primary1);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
@include respond('<=pad_v') {
|
|
465
|
-
font-size: 12px;
|
|
466
|
-
line-height: 18px;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
& + & {
|
|
470
|
-
margin-top: var(--o-gap-3);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
.o-header-search-history-container {
|
|
475
|
-
@include respond('<=pad_v') {
|
|
476
|
-
margin-bottom: var(--o-gap-5);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
.o-header-search-history-header {
|
|
481
|
-
display: flex;
|
|
482
|
-
align-items: center;
|
|
483
|
-
justify-content: space-between;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
.o-header-search-history-header-title {
|
|
487
|
-
@include tip2;
|
|
488
|
-
color: var(--o-color-info3);
|
|
580
|
+
display: none;
|
|
489
581
|
|
|
490
|
-
@include respond('<=pad_v') {
|
|
491
|
-
|
|
492
|
-
color: var(--o-color-info1);
|
|
582
|
+
@include respond-to('<=pad_v') {
|
|
583
|
+
display: block;
|
|
493
584
|
}
|
|
494
585
|
}
|
|
495
586
|
|
|
496
|
-
.o-header-search-
|
|
497
|
-
|
|
498
|
-
gap: 8px;
|
|
499
|
-
flex-wrap: wrap;
|
|
500
|
-
margin-top: var(--o-gap-2);
|
|
587
|
+
.o-header-search-drawer-enter-active {
|
|
588
|
+
transition: opacity var(--o-duration-m1);
|
|
501
589
|
}
|
|
502
590
|
|
|
503
|
-
.o-header-search-
|
|
504
|
-
|
|
505
|
-
right: -8px;
|
|
506
|
-
top: -8px;
|
|
507
|
-
display: none;
|
|
508
|
-
align-items: center;
|
|
509
|
-
justify-content: center;
|
|
510
|
-
width: 16px;
|
|
511
|
-
height: 16px;
|
|
512
|
-
border-radius: 50%;
|
|
513
|
-
background-color: rgb(var(--o-grey-9));
|
|
514
|
-
|
|
515
|
-
.icon-delete {
|
|
516
|
-
height: 16px;
|
|
517
|
-
width: 16px;
|
|
518
|
-
color: var(--o-color-white);
|
|
519
|
-
}
|
|
591
|
+
.o-header-search-drawer-enter-from {
|
|
592
|
+
opacity: 0;
|
|
520
593
|
}
|
|
521
594
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
align-items: center;
|
|
526
|
-
max-width: 224px;
|
|
595
|
+
// 外部传入 mobile=true 时,复制 <=pad_v 的全部样式,不依赖媒体查询
|
|
596
|
+
.o-header-search.is-mobile-mode {
|
|
597
|
+
width: 24px;
|
|
527
598
|
height: 24px;
|
|
528
|
-
padding: 0 var(--o-gap-3);
|
|
529
|
-
background-color: var(--o-color-fill3);
|
|
530
|
-
border-radius: var(--o-radius-xs);
|
|
531
|
-
cursor: pointer;
|
|
532
|
-
|
|
533
|
-
@include hover {
|
|
534
|
-
background-color: var(--o-color-control2-light);
|
|
535
|
-
color: var(--o-color-primary1);
|
|
536
|
-
|
|
537
|
-
.o-header-search-history-item-icon {
|
|
538
|
-
display: flex;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
.o-header-search-history-item-text {
|
|
544
|
-
max-width: 200px;
|
|
545
|
-
overflow: hidden;
|
|
546
|
-
text-overflow: ellipsis;
|
|
547
|
-
white-space: nowrap;
|
|
548
|
-
@include tip2;
|
|
549
|
-
|
|
550
|
-
@include respond('<=pad_v') {
|
|
551
|
-
@include text1;
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
599
|
|
|
555
|
-
.o-header-search-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
@include respond('<=pad_v') {
|
|
559
|
-
display: none;
|
|
600
|
+
.o-header-search-mobile-icon {
|
|
601
|
+
display: block;
|
|
560
602
|
}
|
|
561
|
-
}
|
|
562
603
|
|
|
563
|
-
.o-header-search-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
@include respond('<=pad_v') {
|
|
568
|
-
margin-bottom: var(--o-gap-3);
|
|
569
|
-
@include text2;
|
|
604
|
+
.o-header-search-row.is-focus {
|
|
605
|
+
gap: var(--o-gap-4);
|
|
606
|
+
padding: 10px var(--o-gap-4) var(--o-gap-4) var(--o-gap-4);
|
|
607
|
+
border-radius: unset;
|
|
570
608
|
}
|
|
571
|
-
}
|
|
572
609
|
|
|
573
|
-
.o-header-search-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
gap: var(--o-gap-4);
|
|
577
|
-
margin-top: var(--o-gap-3);
|
|
578
|
-
@include tip2;
|
|
579
|
-
|
|
580
|
-
@include respond('<=pad_v') {
|
|
581
|
-
flex-direction: column;
|
|
582
|
-
gap: 12px;
|
|
583
|
-
font-size: 12px;
|
|
584
|
-
line-height: 18px;
|
|
610
|
+
.o-header-search-row.is-focus .o-header-search-input {
|
|
611
|
+
flex: 1;
|
|
612
|
+
width: auto;
|
|
585
613
|
}
|
|
586
|
-
}
|
|
587
614
|
|
|
588
|
-
.o-header-search-
|
|
589
|
-
|
|
590
|
-
|
|
615
|
+
.o-header-search-drawer {
|
|
616
|
+
position: static;
|
|
617
|
+
height: calc(100vh - 50px);
|
|
618
|
+
padding-top: 0;
|
|
619
|
+
overflow-y: auto;
|
|
620
|
+
box-shadow: unset;
|
|
621
|
+
border-radius: unset;
|
|
591
622
|
|
|
592
|
-
|
|
593
|
-
|
|
623
|
+
&::before {
|
|
624
|
+
display: none;
|
|
625
|
+
}
|
|
594
626
|
}
|
|
595
627
|
}
|
|
596
|
-
|
|
597
|
-
.o-header-search-text {
|
|
598
|
-
font-size: 16px;
|
|
599
|
-
line-height: 24px;
|
|
600
|
-
}
|
|
601
628
|
</style>
|