UNPKG

@scalar/api-reference

Version:

Generate beautiful API references from OpenAPI documents

121 lines (120 loc) 5.01 kB
import { defineComponent, ref, watch, computed, createBlock, openBlock, unref, withCtx, createElementVNode, createVNode, withKeys, withModifiers, isRef, createElementBlock, Fragment, renderList, createTextVNode, toDisplayString } from "vue"; import { ScalarModal, ScalarSearchInput, ScalarSearchResultList } from "@scalar/components"; import { nanoid } from "nanoid"; import { useSearchIndex } from "../hooks/useSearchIndex.js"; import _sfc_main$1 from "./SearchResult.vue.js"; const _hoisted_1 = { class: "mb-0 flex flex-col", role: "search" }; const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "SearchModal", props: { modalState: {}, document: {}, eventBus: {} }, setup(__props) { const props = __props; const id = nanoid(); const listboxId = `${id}-search-result`; const instructionsId = `${id}-search-instructions`; const { query, results } = useSearchIndex(() => props.document); const selectedIndex = ref(void 0); watch( () => props.modalState.open, (open) => { if (open) { query.value = ""; } } ); const navigateSearchResults = (direction) => { const offset = direction === "up" ? -1 : 1; const length = results.value.length; if (typeof selectedIndex.value === "number") { selectedIndex.value = (selectedIndex.value + offset + length) % length; } else { selectedIndex.value = offset === -1 ? length - 1 : 0; } }; function handleSelect(idx) { if (typeof idx !== "number" || !results.value[idx]) { return; } const result = results.value[idx]; props.modalState.hide(); props.eventBus.emit("scroll-to:nav-item", { id: result.item.id }); } const activeDescendantId = computed(() => { const selectedResult = results.value[selectedIndex.value ?? -1]; return selectedResult ? `search-result-${selectedResult.item.id}` : void 0; }); return (_ctx, _cache) => { return openBlock(), createBlock(unref(ScalarModal), { "aria-label": "Reference Search", state: __props.modalState, variant: "search" }, { default: withCtx(() => [ createElementVNode("div", _hoisted_1, [ createVNode(unref(ScalarSearchInput), { modelValue: unref(query), "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(query) ? query.value = $event : null), "aria-activedescendant": activeDescendantId.value, "aria-autocomplete": "list", "aria-controls": listboxId, "aria-describedby": instructionsId, role: "combobox", onBlur: _cache[1] || (_cache[1] = ($event) => selectedIndex.value = void 0), onKeydown: [ _cache[2] || (_cache[2] = withKeys(withModifiers(($event) => navigateSearchResults("down"), ["stop", "prevent"]), ["down"])), _cache[3] || (_cache[3] = withKeys(withModifiers(() => handleSelect(selectedIndex.value), ["stop", "prevent"]), ["enter"])), _cache[4] || (_cache[4] = withKeys(withModifiers(($event) => navigateSearchResults("up"), ["stop", "prevent"]), ["up"])) ] }, null, 8, ["modelValue", "aria-activedescendant"]) ]), createVNode(unref(ScalarSearchResultList), { id: listboxId, "aria-label": "Reference Search Results", class: "custom-scroll p-1 pt-0", noResults: !unref(results).length }, { query: withCtx(() => [ createTextVNode(toDisplayString(unref(query)), 1) ]), default: withCtx(() => [ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(results), (result, idx) => { return openBlock(), createBlock(_sfc_main$1, { id: `search-result-${result.item.id}`, key: result.refIndex, isSelected: selectedIndex.value === idx, result, onClick: withModifiers(() => handleSelect(idx), ["prevent"]) }, null, 8, ["id", "isSelected", "result", "onClick"]); }), 128)) ]), _: 1 }, 8, ["noResults"]), createElementVNode("div", { id: instructionsId, class: "ref-search-meta" }, [..._cache[5] || (_cache[5] = [ createElementVNode("span", { "aria-hidden": "true", class: "contents" }, [ createElementVNode("span", null, "↑↓ Navigate"), createElementVNode("span", null, "⏎ Select") ], -1), createElementVNode("span", { class: "sr-only" }, " Press up arrow / down arrow to navigate, enter to select, type to filter results ", -1) ])]) ]), _: 1 }, 8, ["state"]); }; } }); export { _sfc_main as default };