vp-search.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <script setup lang="ts">
  2. import '@docsearch/css'
  3. import { getCurrentInstance, onMounted, watch } from 'vue'
  4. import { useRoute, useRouter } from 'vitepress'
  5. import docsearch from '@docsearch/js'
  6. import { isClient } from '@vueuse/core'
  7. // import { useLang } from '../../composables/lang'
  8. // import type { DefaultTheme } from '../config'
  9. import type { DocSearchHit } from '@docsearch/react/dist/esm/types'
  10. const props = defineProps<{
  11. options: any
  12. multilang?: boolean
  13. }>()
  14. const vm = getCurrentInstance()
  15. const route = useRoute()
  16. const router = useRouter()
  17. watch(
  18. () => props.options,
  19. value => {
  20. update(value)
  21. }
  22. )
  23. onMounted(() => {
  24. initialize(props.options)
  25. })
  26. function isSpecialClick(event: MouseEvent) {
  27. return event.button === 1 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey
  28. }
  29. function getRelativePath(absoluteUrl: string) {
  30. const { pathname, hash } = new URL(absoluteUrl)
  31. return pathname + hash
  32. }
  33. function update(options: any) {
  34. if (vm && vm.vnode.el) {
  35. vm.vnode.el.innerHTML = '<div class="algolia-search-box" id="docsearch"></div>'
  36. initialize(options)
  37. }
  38. }
  39. // const lang = useLang()
  40. function initialize(userOptions: any) {
  41. // if the user has multiple locales, the search results should be filtered
  42. // based on the language
  43. // const facetFilters = props.multilang ? [`language:${lang.value}`] : []
  44. docsearch(
  45. Object.assign({}, userOptions, {
  46. container: '#docsearch',
  47. indexName: 'element-plus',
  48. // searchParameters: Object.assign({}, userOptions.searchParameters, {
  49. // // pass a custom lang facetFilter to allow multiple language search
  50. // // https://github.com/algolia/docsearch-configs/pull/3942
  51. // facetFilters: facetFilters.concat(
  52. // userOptions.searchParameters?.facetFilters || []
  53. // ),
  54. // }),
  55. navigator: {
  56. navigate: ({ suggestionUrl }: { suggestionUrl: string }) => {
  57. if (!isClient) return
  58. const { pathname: hitPathname } = new URL(window.location.origin + suggestionUrl)
  59. // Router doesn't handle same-page navigation so we use the native
  60. // browser location API for anchor navigation
  61. if (route.path === hitPathname) {
  62. window.location.assign(window.location.origin + suggestionUrl)
  63. } else {
  64. router.go(suggestionUrl)
  65. }
  66. },
  67. },
  68. transformItems: (items: DocSearchHit[]) => {
  69. return items.map(item => {
  70. return Object.assign({}, item, {
  71. url: getRelativePath(item.url),
  72. })
  73. })
  74. },
  75. hitComponent: ({ hit, children }: { hit: DocSearchHit; children: any }) => {
  76. const relativeHit = hit.url.startsWith('http') ? getRelativePath(hit.url as string) : hit.url
  77. return {
  78. type: 'a',
  79. ref: undefined,
  80. constructor: undefined,
  81. key: undefined,
  82. props: {
  83. href: hit.url,
  84. onClick: (event: MouseEvent) => {
  85. if (isSpecialClick(event)) {
  86. return
  87. }
  88. // we rely on the native link scrolling when user is already on
  89. // the right anchor because Router doesn't support duplicated
  90. // history entries
  91. if (route.path === relativeHit) {
  92. return
  93. }
  94. // if the hits goes to another page, we prevent the native link
  95. // behavior to leverage the Router loading feature
  96. if (route.path !== relativeHit) {
  97. event.preventDefault()
  98. }
  99. router.go(relativeHit)
  100. },
  101. children,
  102. },
  103. __v: null,
  104. }
  105. },
  106. })
  107. )
  108. }
  109. </script>
  110. <template>
  111. <div id="docsearch" class="algolia-search-box" />
  112. </template>
  113. <style lang="scss">
  114. @use '../../styles/mixins' as *;
  115. .algolia-search-box {
  116. // display: flex;
  117. // align-items: center;
  118. // line-height: var(--header-height);
  119. // padding-left: 0.5rem;
  120. // padding-top: 1px;
  121. // margin-right: 12px;
  122. // .search-box-placeholder,
  123. // .search-box-key {
  124. // display: flex;
  125. // }
  126. @include respond-to('md') {
  127. min-width: 176.3px;
  128. }
  129. }
  130. .DocSearch {
  131. --docsearch-primary-color: var(--brand-color);
  132. --docsearch-key-gradient: rgba(125, 125, 125, 0.1);
  133. // --docsearch-key-shadow: rgba(125, 125, 125, 0.3);
  134. --docsearch-footer-height: 44px;
  135. --docsearch-footer-background: var(--bg-color);
  136. --docsearch-footer-shadow: 0 -1px 0 0 #e0e3e8, 0 -3px 6px 0 rgba(69, 98, 155, 0.12);
  137. --docsearch-searchbox-background: rgba(var(--bg-color-rgb), 0.8);
  138. --docsearch-searchbox-focus-background: var(--bg-color-mute);
  139. --docsearch-muted-color: var(--text-color-lighter);
  140. --docsearch-text-color: var(--text-color-light);
  141. --docsearch-modal-background: var(--bg-color-soft);
  142. --docsearch-modal-shadow: var(--el-box-shadow);
  143. transition: background-color var(--el-transition-duration-fast);
  144. &.DocSearch-Container {
  145. z-index: 20000;
  146. }
  147. &.DocSearch-Button {
  148. margin-right: 8px;
  149. }
  150. @media (max-width: 749px) {
  151. &.DocSearch-Button {
  152. margin: 0 12px;
  153. padding: 0;
  154. }
  155. }
  156. .dark & {
  157. --docsearch-text-color: var(--text-color-light);
  158. --docsearch-key-shadow: none;
  159. --docsearch-modal-shadow: none;
  160. --docsearch-footer-shadow: none;
  161. // --docsearch-searchbox-focus-background: var(--bg-color-mute);
  162. .DocSearch-Button {
  163. .DocSearch-Button-Key {
  164. box-shadow: unset;
  165. }
  166. }
  167. }
  168. background-color: transparent;
  169. @include respond-to('md') {
  170. background-color: var(--docsearch-searchbox-background);
  171. }
  172. }
  173. </style>