123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- <template>
- <div
- ref="searchMoreRef"
- :class="['tui-search-more', !isPC && 'tui-search-more-h5']"
- >
- <div
- class="more"
- @click="toggleMore()"
- >
- <Icon
- class="more-icon"
- :file="searchMoreSVG"
- :width="isPC ? '28px' : '34px'"
- :height="isPC ? '28px' : '34px'"
- />
- </div>
- <ul
- v-if="isListShow"
- class="tui-search-more-list"
- >
- <li
- v-for="(extension, index) in extensionList"
- :key="index"
- class="list-item"
- @click="handleMenu(extension)"
- >
- <Icon
- v-if="extension.icon"
- class="list-item-icon"
- :file="extension.icon"
- />
- <div class="list-item-title">
- {{ extension.text }}
- </div>
- </li>
- </ul>
- </div>
- </template>
- <script lang="ts" setup>
- import { ref, watch, onMounted } from '../../../adapter-vue';
- import { TUIStore, StoreName } from '@tencentcloud/chat-uikit-engine';
- import TUICore, { ExtensionInfo, TUIConstants } from '@tencentcloud/tui-core';
- import { outsideClick } from '@tencentcloud/universal-api';
- import Icon from '../../common/Icon.vue';
- import searchMoreSVG from '../../../assets/icon/search-more.svg';
- import { isPC, isUniFrameWork } from '../../../utils/env';
- const props = defineProps({
- searchType: {
- type: String,
- default: 'global', // "global" / "conversation"
- validator(value: string) {
- return ['global', 'conversation'].includes(value);
- },
- },
- });
- const searchMoreRef = ref<HTMLElement | null>();
- const isListShow = ref<boolean>(false);
- const toggleMore = () => {
- isListShow.value = !isListShow.value;
- if (!isUniFrameWork && isListShow.value) {
- outsideClick.listen({
- domRefs: searchMoreRef.value,
- handler: closeSearchMore,
- });
- }
- };
- const extensionList = ref<ExtensionInfo[]>([]);
- const handleMenu = (item: ExtensionInfo) => {
- const { listener = { onClicked: () => { } } } = item;
- listener?.onClicked?.(item);
- toggleMore();
- };
- const closeSearchMore = () => {
- isListShow.value = false;
- };
- onMounted(() => {
- // extensions
- extensionList.value = [
- ...TUICore.getExtensionList(TUIConstants.TUISearch.EXTENSION.SEARCH_MORE.EXT_ID),
- ];
- // hide conversation header
- TUICore.callService({
- serviceName: TUIConstants.TUIConversation.SERVICE.NAME,
- method: TUIConstants.TUIConversation.SERVICE.METHOD.HIDE_CONVERSATION_HEADER,
- params: {},
- });
- });
- watch(
- () => isListShow.value,
- () => {
- if (isListShow.value) {
- TUIStore.update(StoreName.SEARCH, 'currentSearchingStatus', {
- isSearching: false,
- searchType: props.searchType,
- });
- }
- },
- );
- </script>
- <style lang="scss" scoped>
- .tui-search-more {
- display: flex;
- flex-direction: column;
- position: relative;
- .more {
- width: 28px;
- height: 28px;
- margin-right: 6px;
- }
- &-list {
- margin: 10px 0;
- position: absolute;
- list-style: none;
- cursor: pointer;
- right: 6px;
- top: 20px;
- z-index: 1000;
- background: #fff;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: flex-start;
- padding: 0;
- box-shadow: rgba(0,0,0,0.16) 0 3px 6px, rgba(0,0,0,0.23) 0 3px 6px;
- .list-item {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: center;
- height: 40px;
- padding: 0 10px;
- &-icon {
- margin-right: 2px;
- }
- &-title {
- font-size: 14px;
- text-wrap: nowrap;
- word-break: keep-all;
- }
- }
- }
- }
- .tui-search-more-h5{
- .more{
- width: 34px;
- height: 34px;
- }
- }
- </style>
|