@scalar/api-reference 1.52.0 → 1.52.2
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/CHANGELOG.md +22 -0
- package/dist/blocks/scalar-client-selector-block/components/ClientDropdown.vue.d.ts +1 -1
- package/dist/blocks/scalar-client-selector-block/components/ClientDropdown.vue.d.ts.map +1 -1
- package/dist/blocks/scalar-client-selector-block/components/ClientDropdown.vue.js +1 -1
- package/dist/blocks/scalar-client-selector-block/components/ClientDropdown.vue.js.map +1 -1
- package/dist/blocks/scalar-client-selector-block/components/ClientDropdown.vue.script.js +1 -1
- package/dist/blocks/scalar-client-selector-block/components/ClientDropdown.vue.script.js.map +1 -1
- package/dist/blocks/scalar-client-selector-block/components/ClientSelector.vue.d.ts +2 -2
- package/dist/blocks/scalar-client-selector-block/components/ClientSelector.vue.d.ts.map +1 -1
- package/dist/blocks/scalar-client-selector-block/components/ClientSelector.vue.js +1 -1
- package/dist/blocks/scalar-client-selector-block/components/ClientSelector.vue.js.map +1 -1
- package/dist/blocks/scalar-client-selector-block/components/ClientSelector.vue.script.js +1 -1
- package/dist/blocks/scalar-client-selector-block/components/ClientSelector.vue.script.js.map +1 -1
- package/dist/blocks/scalar-client-selector-block/helpers/featured-clients.d.ts +1 -1
- package/dist/blocks/scalar-client-selector-block/helpers/featured-clients.d.ts.map +1 -1
- package/dist/blocks/scalar-client-selector-block/helpers/featured-clients.js.map +1 -1
- package/dist/blocks/scalar-server-selector-block/components/ServerSelector.vue.js.map +1 -1
- package/dist/blocks/scalar-server-selector-block/components/ServerSelector.vue.script.js +2 -2
- package/dist/blocks/scalar-server-selector-block/components/ServerSelector.vue.script.js.map +1 -1
- package/dist/browser/standalone.js +405 -422
- package/dist/browser/webpack-stats.json +1 -1
- package/dist/components/AgentScalar/OpenMCPButton.vue.js +1 -1
- package/dist/components/AgentScalar/OpenMCPButton.vue.js.map +1 -1
- package/dist/components/AgentScalar/OpenMCPButton.vue.script.js +1 -1
- package/dist/components/AgentScalar/OpenMCPButton.vue.script.js.map +1 -1
- package/dist/components/ApiReference.vue.d.ts.map +1 -1
- package/dist/components/ApiReference.vue.js +1 -1
- package/dist/components/ApiReference.vue.js.map +1 -1
- package/dist/components/ApiReference.vue.script.js +20 -7
- package/dist/components/ApiReference.vue.script.js.map +1 -1
- package/dist/components/Content/Auth/Auth.vue.js.map +1 -1
- package/dist/components/Content/Auth/Auth.vue.script.js +1 -1
- package/dist/components/Content/Auth/Auth.vue.script.js.map +1 -1
- package/dist/components/Content/Content.vue.d.ts +1 -1
- package/dist/components/Content/Content.vue.d.ts.map +1 -1
- package/dist/components/Content/Content.vue.js.map +1 -1
- package/dist/components/Content/Content.vue.script.js +2 -2
- package/dist/components/Content/Content.vue.script.js.map +1 -1
- package/dist/components/Content/Models/Model.vue.d.ts +1 -1
- package/dist/components/Content/Models/Model.vue.d.ts.map +1 -1
- package/dist/components/Content/Models/Model.vue.js.map +1 -1
- package/dist/components/Content/Models/Model.vue.script.js.map +1 -1
- package/dist/components/Content/Models/components/ClassicLayout.vue.d.ts +1 -1
- package/dist/components/Content/Models/components/ClassicLayout.vue.d.ts.map +1 -1
- package/dist/components/Content/Models/components/ClassicLayout.vue.js +1 -1
- package/dist/components/Content/Models/components/ClassicLayout.vue.js.map +1 -1
- package/dist/components/Content/Models/components/ClassicLayout.vue.script.js +4 -0
- package/dist/components/Content/Models/components/ClassicLayout.vue.script.js.map +1 -1
- package/dist/components/Content/Models/components/ModernLayout.vue.d.ts +1 -0
- package/dist/components/Content/Models/components/ModernLayout.vue.d.ts.map +1 -1
- package/dist/components/Content/Models/components/ModernLayout.vue.js.map +1 -1
- package/dist/components/Content/Models/components/ModernLayout.vue.script.js +2 -1
- package/dist/components/Content/Models/components/ModernLayout.vue.script.js.map +1 -1
- package/dist/components/Content/Operations/TraversedEntry.vue.d.ts +2 -2
- package/dist/components/Content/Operations/TraversedEntry.vue.d.ts.map +1 -1
- package/dist/components/Content/Operations/TraversedEntry.vue.js.map +1 -1
- package/dist/components/Content/Operations/TraversedEntry.vue.script.js.map +1 -1
- package/dist/components/Content/Schema/SchemaComposition.vue.d.ts +2 -0
- package/dist/components/Content/Schema/SchemaComposition.vue.d.ts.map +1 -1
- package/dist/components/Content/Schema/SchemaComposition.vue.js.map +1 -1
- package/dist/components/Content/Schema/SchemaComposition.vue.script.js +5 -0
- package/dist/components/Content/Schema/SchemaComposition.vue.script.js.map +1 -1
- package/dist/components/Content/Schema/SchemaObjectExampleCodeBlock.vue.js.map +1 -1
- package/dist/components/Content/Schema/SchemaObjectExampleCodeBlock.vue.script.js +1 -1
- package/dist/components/Content/Schema/SchemaObjectExampleCodeBlock.vue.script.js.map +1 -1
- package/dist/components/Content/Schema/SchemaProperty.vue.d.ts.map +1 -1
- package/dist/components/Content/Schema/SchemaProperty.vue.js +1 -1
- package/dist/components/Content/Schema/SchemaProperty.vue.js.map +1 -1
- package/dist/components/Content/Schema/SchemaProperty.vue.script.js +16 -10
- package/dist/components/Content/Schema/SchemaProperty.vue.script.js.map +1 -1
- package/dist/components/Content/Schema/SchemaPropertyExamples.vue.d.ts.map +1 -1
- package/dist/components/Content/Schema/SchemaPropertyExamples.vue.js +1 -1
- package/dist/components/Content/Schema/SchemaPropertyExamples.vue.js.map +1 -1
- package/dist/components/Content/Schema/SchemaPropertyExamples.vue.script.js.map +1 -1
- package/dist/features/Operation/Operation.vue.d.ts +2 -2
- package/dist/features/Operation/Operation.vue.d.ts.map +1 -1
- package/dist/features/Operation/Operation.vue.js.map +1 -1
- package/dist/features/Operation/Operation.vue.script.js.map +1 -1
- package/dist/features/Operation/components/OperationParameters.vue.d.ts +1 -1
- package/dist/features/Operation/components/OperationParameters.vue.d.ts.map +1 -1
- package/dist/features/Operation/components/OperationParameters.vue.js.map +1 -1
- package/dist/features/Operation/components/OperationParameters.vue.script.js +1 -1
- package/dist/features/Operation/components/OperationParameters.vue.script.js.map +1 -1
- package/dist/features/Operation/components/OperationResponses.vue.d.ts +1 -1
- package/dist/features/Operation/components/OperationResponses.vue.d.ts.map +1 -1
- package/dist/features/Operation/components/OperationResponses.vue.js.map +1 -1
- package/dist/features/Operation/components/OperationResponses.vue.script.js.map +1 -1
- package/dist/features/Operation/components/ParameterList.vue.d.ts +1 -1
- package/dist/features/Operation/components/ParameterList.vue.d.ts.map +1 -1
- package/dist/features/Operation/components/ParameterList.vue.js.map +1 -1
- package/dist/features/Operation/components/ParameterList.vue.script.js.map +1 -1
- package/dist/features/Operation/components/ParameterListItem.vue.d.ts +1 -1
- package/dist/features/Operation/components/ParameterListItem.vue.d.ts.map +1 -1
- package/dist/features/Operation/components/ParameterListItem.vue.js +1 -1
- package/dist/features/Operation/components/ParameterListItem.vue.js.map +1 -1
- package/dist/features/Operation/components/ParameterListItem.vue.script.js +22 -13
- package/dist/features/Operation/components/ParameterListItem.vue.script.js.map +1 -1
- package/dist/features/Operation/components/RequestBody.vue.d.ts +1 -0
- package/dist/features/Operation/components/RequestBody.vue.d.ts.map +1 -1
- package/dist/features/Operation/components/RequestBody.vue.js +1 -1
- package/dist/features/Operation/components/RequestBody.vue.js.map +1 -1
- package/dist/features/Operation/components/RequestBody.vue.script.js.map +1 -1
- package/dist/features/Operation/components/callbacks/Callback.vue.d.ts +1 -1
- package/dist/features/Operation/components/callbacks/Callback.vue.d.ts.map +1 -1
- package/dist/features/Operation/components/callbacks/Callback.vue.js +1 -1
- package/dist/features/Operation/components/callbacks/Callback.vue.js.map +1 -1
- package/dist/features/Operation/components/callbacks/Callback.vue.script.js.map +1 -1
- package/dist/features/Operation/components/callbacks/Callbacks.vue.d.ts +1 -1
- package/dist/features/Operation/components/callbacks/Callbacks.vue.d.ts.map +1 -1
- package/dist/features/Operation/components/callbacks/Callbacks.vue.js.map +1 -1
- package/dist/features/Operation/components/callbacks/Callbacks.vue.script.js.map +1 -1
- package/dist/features/Operation/helpers/operation-stability.d.ts +19 -0
- package/dist/features/Operation/helpers/operation-stability.d.ts.map +1 -0
- package/dist/features/Operation/helpers/operation-stability.js +25 -0
- package/dist/features/Operation/helpers/operation-stability.js.map +1 -0
- package/dist/features/Operation/helpers/should-ignore-entity.d.ts +8 -0
- package/dist/features/Operation/helpers/should-ignore-entity.d.ts.map +1 -0
- package/dist/features/Operation/helpers/should-ignore-entity.js +9 -0
- package/dist/features/Operation/helpers/should-ignore-entity.js.map +1 -0
- package/dist/features/Operation/layouts/ClassicLayout.vue.d.ts.map +1 -1
- package/dist/features/Operation/layouts/ClassicLayout.vue.js +1 -1
- package/dist/features/Operation/layouts/ClassicLayout.vue.js.map +1 -1
- package/dist/features/Operation/layouts/ClassicLayout.vue.script.js +3 -3
- package/dist/features/Operation/layouts/ClassicLayout.vue.script.js.map +1 -1
- package/dist/features/Operation/layouts/ModernLayout.vue.d.ts.map +1 -1
- package/dist/features/Operation/layouts/ModernLayout.vue.js +1 -1
- package/dist/features/Operation/layouts/ModernLayout.vue.js.map +1 -1
- package/dist/features/Operation/layouts/ModernLayout.vue.script.js +2 -2
- package/dist/features/Operation/layouts/ModernLayout.vue.script.js.map +1 -1
- package/dist/features/Search/components/SearchModal.vue.js +1 -1
- package/dist/features/Search/components/SearchModal.vue.js.map +1 -1
- package/dist/features/Search/components/SearchModal.vue.script.js +1 -1
- package/dist/features/Search/components/SearchModal.vue.script.js.map +1 -1
- package/dist/features/Search/hooks/useSearchIndex.d.ts.map +1 -1
- package/dist/features/Search/hooks/useSearchIndex.js +3 -2
- package/dist/features/Search/hooks/useSearchIndex.js.map +1 -1
- package/dist/features/example-responses/ExampleResponse.vue.js +1 -1
- package/dist/features/example-responses/ExampleResponse.vue.js.map +1 -1
- package/dist/features/example-responses/ExampleResponse.vue.script.js +1 -1
- package/dist/features/example-responses/ExampleResponse.vue.script.js.map +1 -1
- package/dist/features/example-responses/ExampleResponses.vue.d.ts.map +1 -1
- package/dist/features/example-responses/ExampleResponses.vue.js +1 -1
- package/dist/features/example-responses/ExampleResponses.vue.js.map +1 -1
- package/dist/features/example-responses/ExampleResponses.vue.script.js +6 -5
- package/dist/features/example-responses/ExampleResponses.vue.script.js.map +1 -1
- package/dist/features/example-responses/ExampleSchema.vue.js.map +1 -1
- package/dist/features/example-responses/ExampleSchema.vue.script.js +1 -1
- package/dist/features/example-responses/ExampleSchema.vue.script.js.map +1 -1
- package/dist/features/example-responses/helpers/has-response-content.d.ts.map +1 -0
- package/dist/features/example-responses/{has-response-content.js → helpers/has-response-content.js} +4 -3
- package/dist/features/example-responses/helpers/has-response-content.js.map +1 -0
- package/dist/features/example-responses/helpers/normalize-mime-type-object.d.ts +8 -0
- package/dist/features/example-responses/helpers/normalize-mime-type-object.d.ts.map +1 -0
- package/dist/features/example-responses/helpers/normalize-mime-type-object.js +20 -0
- package/dist/features/example-responses/helpers/normalize-mime-type-object.js.map +1 -0
- package/dist/features/example-responses/helpers/normalize-mime-type.d.ts +10 -0
- package/dist/features/example-responses/helpers/normalize-mime-type.d.ts.map +1 -0
- package/dist/features/example-responses/helpers/normalize-mime-type.js +9 -0
- package/dist/features/example-responses/helpers/normalize-mime-type.js.map +1 -0
- package/dist/features/multiple-documents/DocumentSelector.vue.js.map +1 -1
- package/dist/features/multiple-documents/DocumentSelector.vue.script.js +1 -1
- package/dist/features/multiple-documents/DocumentSelector.vue.script.js.map +1 -1
- package/dist/helpers/load-from-perssistance.js +1 -1
- package/dist/helpers/load-from-perssistance.js.map +1 -1
- package/dist/helpers/map-config-to-workspace-store.js +1 -1
- package/dist/helpers/map-config-to-workspace-store.js.map +1 -1
- package/dist/helpers/normalize-configurations.js +1 -1
- package/dist/hooks/use-intersection.d.ts +12 -1
- package/dist/hooks/use-intersection.d.ts.map +1 -1
- package/dist/hooks/use-intersection.js +7 -5
- package/dist/hooks/use-intersection.js.map +1 -1
- package/dist/style.css +4726 -6054
- package/package.json +15 -15
- package/dist/features/example-responses/has-response-content.d.ts.map +0 -1
- package/dist/features/example-responses/has-response-content.js.map +0 -1
- /package/dist/features/example-responses/{has-response-content.d.ts → helpers/has-response-content.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExampleResponses.vue.d.ts","sourceRoot":"","sources":["../../../src/features/example-responses/ExampleResponses.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ExampleResponses.vue.d.ts","sourceRoot":"","sources":["../../../src/features/example-responses/ExampleResponses.vue"],"names":[],"mappings":"AAmWA,OAAO,KAAK,EAEV,eAAe,EAChB,MAAM,8DAA8D,CAAA;AAYrE;;GAEG;AAEH,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,eAAe,CAAA;CAC3B,CAAC;AA4WF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -2,7 +2,7 @@ import _plugin_vue_export_helper_default from "../../_virtual/_plugin-vue_export
|
|
|
2
2
|
import ExampleResponses_vue_vue_type_script_setup_true_lang_default from "./ExampleResponses.vue.script.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
//#region src/features/example-responses/ExampleResponses.vue
|
|
5
|
-
var ExampleResponses_default = /* @__PURE__ */ _plugin_vue_export_helper_default(ExampleResponses_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-
|
|
5
|
+
var ExampleResponses_default = /* @__PURE__ */ _plugin_vue_export_helper_default(ExampleResponses_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-4e56e3cf"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { ExampleResponses_default as default };
|
|
8
8
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExampleResponses.vue.js","names":[],"sources":["../../../src/features/example-responses/ExampleResponses.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { ExamplePicker } from '@scalar/api-client/v2/blocks/operation-code-sample'\nimport {\n ScalarCard,\n ScalarCardFooter,\n ScalarCardSection,\n ScalarIcon,\n ScalarMarkdown,\n} from '@scalar/components'\nimport {\n getObjectKeys,\n normalizeMimeTypeObject,\n} from '@scalar/oas-utils/helpers'\nimport { useClipboard } from '@scalar/use-hooks/useClipboard'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { getExample } from '@scalar/workspace-store/request-example'\nimport type {\n MediaTypeObject,\n ResponsesObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, toValue, useId, watch } from 'vue'\n\nimport ScreenReader from '@/components/ScreenReader.vue'\nimport ExampleSchema from '@/features/example-responses/ExampleSchema.vue'\n\nimport ExampleResponse from './ExampleResponse.vue'\nimport ExampleResponseTab from './ExampleResponseTab.vue'\nimport ExampleResponseTabList from './ExampleResponseTabList.vue'\nimport { hasResponseContent } from './has-response-content'\n\n/**\n * TODO: copyToClipboard isn't using the right content if there are multiple examples\n */\n\nconst { responses } = defineProps<{\n responses: ResponsesObject\n}>()\n\nconst id = useId()\nconst { copyToClipboard } = useClipboard()\n\n// Bring the status codes in the right order.\nconst orderedStatusCodes = computed<string[]>(() =>\n Object.keys(responses ?? {}).sort(),\n)\n\n// Filter to only valid response keys that should render in the example responses panel\nconst statusCodesWithContent = computed<string[]>(() =>\n orderedStatusCodes.value.filter((statusCode) =>\n hasResponseContent(getResolvedRef(responses?.[statusCode]), statusCode),\n ),\n)\n\n// Keep track of the current selected tab\nconst selectedResponseIndex = ref<number>(0)\n\n/**\n * Clamp the selected index when the filtered list shrinks.\n * Without this, the index can become out of bounds and cause a mismatch\n * between the visible tabs and the displayed content.\n *\n * We also reset `selectedExampleKey` to match the behavior of `changeTab`,\n * since the new response may not have the same example keys.\n */\nwatch(statusCodesWithContent, (codes) => {\n if (codes.length === 0) {\n selectedResponseIndex.value = 0\n selectedExampleKey.value = ''\n } else if (selectedResponseIndex.value >= codes.length) {\n selectedResponseIndex.value = codes.length - 1\n selectedExampleKey.value = ''\n }\n})\n\n// Return the whole response object\nconst currentResponse = computed(() => {\n const currentStatusCode =\n toValue(statusCodesWithContent)[toValue(selectedResponseIndex)] ?? ''\n\n return getResolvedRef(responses?.[currentStatusCode])\n})\n\nconst currentResponseContent = computed<MediaTypeObject | undefined>(() => {\n const normalizedContent = normalizeMimeTypeObject(\n currentResponse.value?.content,\n )\n\n /** All the keys of the normalized content */\n const keys = getObjectKeys(normalizedContent ?? {})\n\n return (\n // OpenAPI 3.x\n normalizedContent?.['application/json'] ??\n normalizedContent?.['application/xml'] ??\n normalizedContent?.['text/plain'] ??\n normalizedContent?.['text/html'] ??\n normalizedContent?.['*/*'] ??\n // Take the first key - in the future we may want to use the selected content type\n normalizedContent?.[keys[0] ?? ''] ??\n undefined\n )\n})\n\nconst hasMultipleExamples = computed<boolean>(\n () =>\n !!currentResponseContent.value?.examples &&\n Object.keys(currentResponseContent.value?.examples ?? {}).length > 1,\n)\n\nconst selectedExampleKey = ref<string>(\n Object.keys(currentResponseContent.value?.examples ?? {})[0] ?? '',\n)\n\n/** Get the current example to display */\nconst currentExample = computed(() => {\n if (!currentResponseContent.value) {\n return undefined\n }\n\n // When multiple examples exist and one is selected, we access it directly\n if (hasMultipleExamples.value && selectedExampleKey.value) {\n return currentResponseContent.value.examples?.[selectedExampleKey.value]\n }\n\n // Otherwise, we use getExample with an undefined exampleKey to handle fallbacks\n return getExample(currentResponseContent.value, undefined, undefined)\n})\n\nconst changeTab = (index: number) => {\n selectedResponseIndex.value = index\n selectedExampleKey.value = ''\n}\n\nconst showSchema = ref(false)\n</script>\n<template>\n <ScalarCard\n v-if=\"statusCodesWithContent.length\"\n aria-label=\"Example Responses\"\n class=\"response-card\"\n role=\"region\">\n <ExampleResponseTabList @change=\"changeTab\">\n <ExampleResponseTab\n v-for=\"statusCode in statusCodesWithContent\"\n :key=\"statusCode\"\n :aria-controls=\"id\">\n <ScreenReader>Status:</ScreenReader>\n {{ statusCode }}\n </ExampleResponseTab>\n\n <template #actions>\n <button\n v-if=\"currentResponseContent?.example\"\n class=\"code-copy\"\n type=\"button\"\n @click=\"() => copyToClipboard(currentResponseContent?.example)\">\n <ScalarIcon\n icon=\"Clipboard\"\n width=\"12px\" />\n </button>\n <label\n v-if=\"currentResponseContent?.schema\"\n class=\"scalar-card-checkbox\">\n Show Schema\n <input\n v-model=\"showSchema\"\n :aria-controls=\"id\"\n class=\"scalar-card-checkbox-input\"\n type=\"checkbox\" />\n <span class=\"scalar-card-checkbox-checkmark\" />\n </label>\n </template>\n </ExampleResponseTabList>\n <ScalarCardSection class=\"grid flex-1\">\n <!-- Schema -->\n <ExampleSchema\n v-if=\"currentResponseContent?.schema && showSchema\"\n :id=\"id\"\n :schema=\"currentResponseContent?.schema\" />\n\n <!-- Example -->\n <ExampleResponse\n v-else\n :id=\"id\"\n :example=\"currentExample\"\n :response=\"currentResponseContent\" />\n </ScalarCardSection>\n <ScalarCardFooter\n v-if=\"currentResponse?.description || hasMultipleExamples\"\n class=\"response-card-footer\">\n <ExamplePicker\n v-if=\"hasMultipleExamples\"\n v-model=\"selectedExampleKey\"\n class=\"response-example-selector px-0\"\n :examples=\"currentResponseContent?.examples\" />\n <div class=\"response-description\">\n <ScalarMarkdown\n v-if=\"currentResponse?.description\"\n class=\"response-description-markdown\"\n :value=\"currentResponse.description\" />\n </div>\n </ScalarCardFooter>\n </ScalarCard>\n</template>\n\n<style scoped>\n.response-card {\n font-size: var(--scalar-font-size-3);\n}\n\n.code-copy {\n display: flex;\n align-items: center;\n justify-content: center;\n appearance: none;\n -webkit-appearance: none;\n outline: none;\n background: transparent;\n cursor: pointer;\n color: var(--scalar-color-3);\n border: none;\n padding: 0;\n margin-right: 12px;\n}\n.code-copy:hover {\n color: var(--scalar-color-1);\n}\n.code-copy svg {\n width: 13px;\n height: 13px;\n}\n.response-card-footer {\n display: flex;\n flex-direction: row-reverse;\n flex-wrap: wrap;\n justify-content: start;\n flex-shrink: 0;\n padding: 7px 12px;\n column-gap: 8px;\n}\n.response-example-selector {\n flex-shrink: 0;\n margin: -4px;\n}\n.response-description {\n font-weight: var(--scalar-semibold);\n font-size: var(--scalar-small);\n color: var(--scalar-color--1);\n\n box-sizing: border-box;\n\n flex-grow: 1;\n}\n.response-description-markdown {\n max-height: 3lh;\n}\n\n.response-description-markdown :deep(*) {\n margin: 0;\n}\n.schema-type {\n font-size: var(--scalar-micro);\n color: var(--scalar-color-2);\n font-weight: var(--scalar-semibold);\n background: var(--scalar-background-3);\n padding: 2px 4px;\n border-radius: 4px;\n margin-right: 4px;\n}\n.schema-example {\n font-size: var(--scalar-micro);\n color: var(--scalar-color-2);\n font-weight: var(--scalar-semibold);\n}\n\n.example-response-tab {\n display: block;\n margin: 6px;\n}\n\n.scalar-card-checkbox {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n min-height: 17px;\n cursor: pointer;\n user-select: none;\n font-size: var(--scalar-small);\n font-weight: var(--scalar-font-normal);\n color: var(--scalar-color-2);\n width: fit-content;\n white-space: nowrap;\n gap: 6px;\n padding: 7px 6px;\n}\n.scalar-card-checkbox:has(.scalar-card-checkbox-input:focus-visible)\n .scalar-card-checkbox-checkmark {\n outline: 1px solid var(--scalar-color-accent);\n}\n.scalar-card-checkbox:hover {\n color: var(--scalar-color--1);\n}\n.scalar-card-checkbox .scalar-card-checkbox-input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n height: 0;\n width: 0;\n}\n\n.scalar-card-checkbox-checkmark {\n height: 16px;\n width: 16px;\n border-radius: var(--scalar-radius);\n background-color: transparent;\n background-color: var(--scalar-background-3);\n box-shadow: inset 0 0 0 var(--scalar-border-width) var(--scalar-border-color);\n}\n.scalar-card-checkbox:has(.scalar-card-checkbox-input:checked) {\n color: var(--scalar-color-1);\n font-weight: var(--scalar-semibold);\n}\n\n.scalar-card-checkbox\n .scalar-card-checkbox-input:checked\n ~ .scalar-card-checkbox-checkmark {\n background-color: var(--scalar-button-1);\n box-shadow: none;\n}\n\n.scalar-card-checkbox-checkmark:after {\n content: '';\n position: absolute;\n display: none;\n}\n\n.scalar-card-checkbox\n .scalar-card-checkbox-input:checked\n ~ .scalar-card-checkbox-checkmark:after {\n display: block;\n}\n\n.scalar-card-checkbox .scalar-card-checkbox-checkmark:after {\n right: 11.5px;\n top: 12.5px;\n width: 5px;\n height: 9px;\n border: solid 1px var(--scalar-button-1-color);\n border-width: 0 1.5px 1.5px 0;\n transform: rotate(45deg);\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"ExampleResponses.vue.js","names":[],"sources":["../../../src/features/example-responses/ExampleResponses.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { ExamplePicker } from '@scalar/api-client/blocks/operation-code-sample'\nimport {\n ScalarCard,\n ScalarCardFooter,\n ScalarCardSection,\n ScalarIcon,\n ScalarMarkdown,\n} from '@scalar/components'\nimport { objectKeys } from '@scalar/helpers/object/object-keys'\nimport { useClipboard } from '@scalar/use-hooks/useClipboard'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { getExample } from '@scalar/workspace-store/request-example'\nimport type {\n MediaTypeObject,\n ResponsesObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, toValue, useId, watch } from 'vue'\n\nimport ScreenReader from '@/components/ScreenReader.vue'\nimport ExampleSchema from '@/features/example-responses/ExampleSchema.vue'\n\nimport ExampleResponse from './ExampleResponse.vue'\nimport ExampleResponseTab from './ExampleResponseTab.vue'\nimport ExampleResponseTabList from './ExampleResponseTabList.vue'\nimport { hasResponseContent } from './helpers/has-response-content'\nimport { normalizeMimeTypeObject } from './helpers/normalize-mime-type-object'\n\n/**\n * TODO: copyToClipboard isn't using the right content if there are multiple examples\n */\n\nconst { responses } = defineProps<{\n responses: ResponsesObject\n}>()\n\nconst id = useId()\nconst { copyToClipboard } = useClipboard()\n\n// Bring the status codes in the right order.\nconst orderedStatusCodes = computed<string[]>(() =>\n Object.keys(responses ?? {}).sort(),\n)\n\n// Filter to only valid response keys that should render in the example responses panel\nconst statusCodesWithContent = computed<string[]>(() =>\n orderedStatusCodes.value.filter((statusCode) =>\n hasResponseContent(getResolvedRef(responses?.[statusCode]), statusCode),\n ),\n)\n\n// Keep track of the current selected tab\nconst selectedResponseIndex = ref<number>(0)\n\n/**\n * Clamp the selected index when the filtered list shrinks.\n * Without this, the index can become out of bounds and cause a mismatch\n * between the visible tabs and the displayed content.\n *\n * We also reset `selectedExampleKey` to match the behavior of `changeTab`,\n * since the new response may not have the same example keys.\n */\nwatch(statusCodesWithContent, (codes) => {\n if (codes.length === 0) {\n selectedResponseIndex.value = 0\n selectedExampleKey.value = ''\n } else if (selectedResponseIndex.value >= codes.length) {\n selectedResponseIndex.value = codes.length - 1\n selectedExampleKey.value = ''\n }\n})\n\n// Return the whole response object\nconst currentResponse = computed(() => {\n const currentStatusCode =\n toValue(statusCodesWithContent)[toValue(selectedResponseIndex)] ?? ''\n\n return getResolvedRef(responses?.[currentStatusCode])\n})\n\nconst currentResponseContent = computed<MediaTypeObject | undefined>(() => {\n const normalizedContent = normalizeMimeTypeObject(\n currentResponse.value?.content,\n )\n\n /** All the keys of the normalized content */\n const keys = objectKeys(normalizedContent ?? {})\n return normalizedContent?.[keys[0] ?? '']\n})\n\nconst hasMultipleExamples = computed<boolean>(\n () =>\n !!currentResponseContent.value?.examples &&\n Object.keys(currentResponseContent.value?.examples ?? {}).length > 1,\n)\n\nconst selectedExampleKey = ref<string>(\n Object.keys(currentResponseContent.value?.examples ?? {})[0] ?? '',\n)\n\n/** Get the current example to display */\nconst currentExample = computed(() => {\n if (!currentResponseContent.value) {\n return undefined\n }\n\n // When multiple examples exist and one is selected, we access it directly\n if (hasMultipleExamples.value && selectedExampleKey.value) {\n return currentResponseContent.value.examples?.[selectedExampleKey.value]\n }\n\n // Otherwise, we use getExample with an undefined exampleKey to handle fallbacks\n return getExample(currentResponseContent.value, undefined, undefined)\n})\n\nconst changeTab = (index: number) => {\n selectedResponseIndex.value = index\n selectedExampleKey.value = ''\n}\n\nconst showSchema = ref(false)\n</script>\n<template>\n <ScalarCard\n v-if=\"statusCodesWithContent.length\"\n aria-label=\"Example Responses\"\n class=\"response-card\"\n role=\"region\">\n <ExampleResponseTabList @change=\"changeTab\">\n <ExampleResponseTab\n v-for=\"statusCode in statusCodesWithContent\"\n :key=\"statusCode\"\n :aria-controls=\"id\">\n <ScreenReader>Status:</ScreenReader>\n {{ statusCode }}\n </ExampleResponseTab>\n\n <template #actions>\n <button\n v-if=\"currentResponseContent?.example\"\n class=\"code-copy\"\n type=\"button\"\n @click=\"() => copyToClipboard(currentResponseContent?.example)\">\n <ScalarIcon\n icon=\"Clipboard\"\n width=\"12px\" />\n </button>\n <label\n v-if=\"currentResponseContent?.schema\"\n class=\"scalar-card-checkbox\">\n Show Schema\n <input\n v-model=\"showSchema\"\n :aria-controls=\"id\"\n class=\"scalar-card-checkbox-input\"\n type=\"checkbox\" />\n <span class=\"scalar-card-checkbox-checkmark\" />\n </label>\n </template>\n </ExampleResponseTabList>\n <ScalarCardSection class=\"grid flex-1\">\n <!-- Schema -->\n <ExampleSchema\n v-if=\"currentResponseContent?.schema && showSchema\"\n :id=\"id\"\n :schema=\"currentResponseContent?.schema\" />\n\n <!-- Example -->\n <ExampleResponse\n v-else\n :id=\"id\"\n :example=\"currentExample\"\n :response=\"currentResponseContent\" />\n </ScalarCardSection>\n <ScalarCardFooter\n v-if=\"currentResponse?.description || hasMultipleExamples\"\n class=\"response-card-footer\">\n <ExamplePicker\n v-if=\"hasMultipleExamples\"\n v-model=\"selectedExampleKey\"\n class=\"response-example-selector px-0\"\n :examples=\"currentResponseContent?.examples\" />\n <div class=\"response-description\">\n <ScalarMarkdown\n v-if=\"currentResponse?.description\"\n class=\"response-description-markdown\"\n :value=\"currentResponse.description\" />\n </div>\n </ScalarCardFooter>\n </ScalarCard>\n</template>\n\n<style scoped>\n.response-card {\n font-size: var(--scalar-font-size-3);\n}\n\n.code-copy {\n display: flex;\n align-items: center;\n justify-content: center;\n appearance: none;\n -webkit-appearance: none;\n outline: none;\n background: transparent;\n cursor: pointer;\n color: var(--scalar-color-3);\n border: none;\n padding: 0;\n margin-right: 12px;\n}\n.code-copy:hover {\n color: var(--scalar-color-1);\n}\n.code-copy svg {\n width: 13px;\n height: 13px;\n}\n.response-card-footer {\n display: flex;\n flex-direction: row-reverse;\n flex-wrap: wrap;\n justify-content: start;\n flex-shrink: 0;\n padding: 7px 12px;\n column-gap: 8px;\n}\n.response-example-selector {\n flex-shrink: 0;\n margin: -4px;\n}\n.response-description {\n font-weight: var(--scalar-semibold);\n font-size: var(--scalar-small);\n color: var(--scalar-color--1);\n\n box-sizing: border-box;\n\n flex-grow: 1;\n}\n.response-description-markdown {\n max-height: 3lh;\n}\n\n.response-description-markdown :deep(*) {\n margin: 0;\n}\n.schema-type {\n font-size: var(--scalar-micro);\n color: var(--scalar-color-2);\n font-weight: var(--scalar-semibold);\n background: var(--scalar-background-3);\n padding: 2px 4px;\n border-radius: 4px;\n margin-right: 4px;\n}\n.schema-example {\n font-size: var(--scalar-micro);\n color: var(--scalar-color-2);\n font-weight: var(--scalar-semibold);\n}\n\n.example-response-tab {\n display: block;\n margin: 6px;\n}\n\n.scalar-card-checkbox {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n min-height: 17px;\n cursor: pointer;\n user-select: none;\n font-size: var(--scalar-small);\n font-weight: var(--scalar-font-normal);\n color: var(--scalar-color-2);\n width: fit-content;\n white-space: nowrap;\n gap: 6px;\n padding: 7px 6px;\n}\n.scalar-card-checkbox:has(.scalar-card-checkbox-input:focus-visible)\n .scalar-card-checkbox-checkmark {\n outline: 1px solid var(--scalar-color-accent);\n}\n.scalar-card-checkbox:hover {\n color: var(--scalar-color--1);\n}\n.scalar-card-checkbox .scalar-card-checkbox-input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n height: 0;\n width: 0;\n}\n\n.scalar-card-checkbox-checkmark {\n height: 16px;\n width: 16px;\n border-radius: var(--scalar-radius);\n background-color: transparent;\n background-color: var(--scalar-background-3);\n box-shadow: inset 0 0 0 var(--scalar-border-width) var(--scalar-border-color);\n}\n.scalar-card-checkbox:has(.scalar-card-checkbox-input:checked) {\n color: var(--scalar-color-1);\n font-weight: var(--scalar-semibold);\n}\n\n.scalar-card-checkbox\n .scalar-card-checkbox-input:checked\n ~ .scalar-card-checkbox-checkmark {\n background-color: var(--scalar-button-1);\n box-shadow: none;\n}\n\n.scalar-card-checkbox-checkmark:after {\n content: '';\n position: absolute;\n display: none;\n}\n\n.scalar-card-checkbox\n .scalar-card-checkbox-input:checked\n ~ .scalar-card-checkbox-checkmark:after {\n display: block;\n}\n\n.scalar-card-checkbox .scalar-card-checkbox-checkmark:after {\n right: 11.5px;\n top: 12.5px;\n width: 5px;\n height: 9px;\n border: solid 1px var(--scalar-button-1-color);\n border-width: 0 1.5px 1.5px 0;\n transform: rotate(45deg);\n}\n</style>\n"],"mappings":""}
|
|
@@ -3,14 +3,15 @@ import ExampleSchema_default from "./ExampleSchema.vue.js";
|
|
|
3
3
|
import ExampleResponse_default from "./ExampleResponse.vue.js";
|
|
4
4
|
import ExampleResponseTab_default from "./ExampleResponseTab.vue.js";
|
|
5
5
|
import ExampleResponseTabList_default from "./ExampleResponseTabList.vue.js";
|
|
6
|
-
import {
|
|
6
|
+
import { normalizeMimeTypeObject } from "./helpers/normalize-mime-type-object.js";
|
|
7
|
+
import { hasResponseContent } from "./helpers/has-response-content.js";
|
|
7
8
|
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, openBlock, ref, renderList, toDisplayString, toValue, unref, useId, vModelCheckbox, watch, withCtx, withDirectives } from "vue";
|
|
8
9
|
import { ScalarCard, ScalarCardFooter, ScalarCardSection, ScalarIcon, ScalarMarkdown } from "@scalar/components";
|
|
9
10
|
import { useClipboard } from "@scalar/use-hooks/useClipboard";
|
|
10
11
|
import { getExample } from "@scalar/workspace-store/request-example";
|
|
11
|
-
import {
|
|
12
|
-
import { ExamplePicker } from "@scalar/api-client/v2/blocks/operation-code-sample";
|
|
12
|
+
import { ExamplePicker } from "@scalar/api-client/blocks/operation-code-sample";
|
|
13
13
|
import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref";
|
|
14
|
+
import { objectKeys } from "@scalar/helpers/object/object-keys";
|
|
14
15
|
//#region src/features/example-responses/ExampleResponses.vue?vue&type=script&setup=true&lang.ts
|
|
15
16
|
var _hoisted_1 = {
|
|
16
17
|
key: 1,
|
|
@@ -54,8 +55,8 @@ var ExampleResponses_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
|
|
|
54
55
|
const currentResponseContent = computed(() => {
|
|
55
56
|
const normalizedContent = normalizeMimeTypeObject(currentResponse.value?.content);
|
|
56
57
|
/** All the keys of the normalized content */
|
|
57
|
-
const keys =
|
|
58
|
-
return normalizedContent?.[
|
|
58
|
+
const keys = objectKeys(normalizedContent ?? {});
|
|
59
|
+
return normalizedContent?.[keys[0] ?? ""];
|
|
59
60
|
});
|
|
60
61
|
const hasMultipleExamples = computed(() => !!currentResponseContent.value?.examples && Object.keys(currentResponseContent.value?.examples ?? {}).length > 1);
|
|
61
62
|
const selectedExampleKey = ref(Object.keys(currentResponseContent.value?.examples ?? {})[0] ?? "");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExampleResponses.vue.script.js","names":[],"sources":["../../../src/features/example-responses/ExampleResponses.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { ExamplePicker } from '@scalar/api-client/v2/blocks/operation-code-sample'\nimport {\n ScalarCard,\n ScalarCardFooter,\n ScalarCardSection,\n ScalarIcon,\n ScalarMarkdown,\n} from '@scalar/components'\nimport {\n getObjectKeys,\n normalizeMimeTypeObject,\n} from '@scalar/oas-utils/helpers'\nimport { useClipboard } from '@scalar/use-hooks/useClipboard'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { getExample } from '@scalar/workspace-store/request-example'\nimport type {\n MediaTypeObject,\n ResponsesObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, toValue, useId, watch } from 'vue'\n\nimport ScreenReader from '@/components/ScreenReader.vue'\nimport ExampleSchema from '@/features/example-responses/ExampleSchema.vue'\n\nimport ExampleResponse from './ExampleResponse.vue'\nimport ExampleResponseTab from './ExampleResponseTab.vue'\nimport ExampleResponseTabList from './ExampleResponseTabList.vue'\nimport { hasResponseContent } from './has-response-content'\n\n/**\n * TODO: copyToClipboard isn't using the right content if there are multiple examples\n */\n\nconst { responses } = defineProps<{\n responses: ResponsesObject\n}>()\n\nconst id = useId()\nconst { copyToClipboard } = useClipboard()\n\n// Bring the status codes in the right order.\nconst orderedStatusCodes = computed<string[]>(() =>\n Object.keys(responses ?? {}).sort(),\n)\n\n// Filter to only valid response keys that should render in the example responses panel\nconst statusCodesWithContent = computed<string[]>(() =>\n orderedStatusCodes.value.filter((statusCode) =>\n hasResponseContent(getResolvedRef(responses?.[statusCode]), statusCode),\n ),\n)\n\n// Keep track of the current selected tab\nconst selectedResponseIndex = ref<number>(0)\n\n/**\n * Clamp the selected index when the filtered list shrinks.\n * Without this, the index can become out of bounds and cause a mismatch\n * between the visible tabs and the displayed content.\n *\n * We also reset `selectedExampleKey` to match the behavior of `changeTab`,\n * since the new response may not have the same example keys.\n */\nwatch(statusCodesWithContent, (codes) => {\n if (codes.length === 0) {\n selectedResponseIndex.value = 0\n selectedExampleKey.value = ''\n } else if (selectedResponseIndex.value >= codes.length) {\n selectedResponseIndex.value = codes.length - 1\n selectedExampleKey.value = ''\n }\n})\n\n// Return the whole response object\nconst currentResponse = computed(() => {\n const currentStatusCode =\n toValue(statusCodesWithContent)[toValue(selectedResponseIndex)] ?? ''\n\n return getResolvedRef(responses?.[currentStatusCode])\n})\n\nconst currentResponseContent = computed<MediaTypeObject | undefined>(() => {\n const normalizedContent = normalizeMimeTypeObject(\n currentResponse.value?.content,\n )\n\n /** All the keys of the normalized content */\n const keys = getObjectKeys(normalizedContent ?? {})\n\n return (\n // OpenAPI 3.x\n normalizedContent?.['application/json'] ??\n normalizedContent?.['application/xml'] ??\n normalizedContent?.['text/plain'] ??\n normalizedContent?.['text/html'] ??\n normalizedContent?.['*/*'] ??\n // Take the first key - in the future we may want to use the selected content type\n normalizedContent?.[keys[0] ?? ''] ??\n undefined\n )\n})\n\nconst hasMultipleExamples = computed<boolean>(\n () =>\n !!currentResponseContent.value?.examples &&\n Object.keys(currentResponseContent.value?.examples ?? {}).length > 1,\n)\n\nconst selectedExampleKey = ref<string>(\n Object.keys(currentResponseContent.value?.examples ?? {})[0] ?? '',\n)\n\n/** Get the current example to display */\nconst currentExample = computed(() => {\n if (!currentResponseContent.value) {\n return undefined\n }\n\n // When multiple examples exist and one is selected, we access it directly\n if (hasMultipleExamples.value && selectedExampleKey.value) {\n return currentResponseContent.value.examples?.[selectedExampleKey.value]\n }\n\n // Otherwise, we use getExample with an undefined exampleKey to handle fallbacks\n return getExample(currentResponseContent.value, undefined, undefined)\n})\n\nconst changeTab = (index: number) => {\n selectedResponseIndex.value = index\n selectedExampleKey.value = ''\n}\n\nconst showSchema = ref(false)\n</script>\n<template>\n <ScalarCard\n v-if=\"statusCodesWithContent.length\"\n aria-label=\"Example Responses\"\n class=\"response-card\"\n role=\"region\">\n <ExampleResponseTabList @change=\"changeTab\">\n <ExampleResponseTab\n v-for=\"statusCode in statusCodesWithContent\"\n :key=\"statusCode\"\n :aria-controls=\"id\">\n <ScreenReader>Status:</ScreenReader>\n {{ statusCode }}\n </ExampleResponseTab>\n\n <template #actions>\n <button\n v-if=\"currentResponseContent?.example\"\n class=\"code-copy\"\n type=\"button\"\n @click=\"() => copyToClipboard(currentResponseContent?.example)\">\n <ScalarIcon\n icon=\"Clipboard\"\n width=\"12px\" />\n </button>\n <label\n v-if=\"currentResponseContent?.schema\"\n class=\"scalar-card-checkbox\">\n Show Schema\n <input\n v-model=\"showSchema\"\n :aria-controls=\"id\"\n class=\"scalar-card-checkbox-input\"\n type=\"checkbox\" />\n <span class=\"scalar-card-checkbox-checkmark\" />\n </label>\n </template>\n </ExampleResponseTabList>\n <ScalarCardSection class=\"grid flex-1\">\n <!-- Schema -->\n <ExampleSchema\n v-if=\"currentResponseContent?.schema && showSchema\"\n :id=\"id\"\n :schema=\"currentResponseContent?.schema\" />\n\n <!-- Example -->\n <ExampleResponse\n v-else\n :id=\"id\"\n :example=\"currentExample\"\n :response=\"currentResponseContent\" />\n </ScalarCardSection>\n <ScalarCardFooter\n v-if=\"currentResponse?.description || hasMultipleExamples\"\n class=\"response-card-footer\">\n <ExamplePicker\n v-if=\"hasMultipleExamples\"\n v-model=\"selectedExampleKey\"\n class=\"response-example-selector px-0\"\n :examples=\"currentResponseContent?.examples\" />\n <div class=\"response-description\">\n <ScalarMarkdown\n v-if=\"currentResponse?.description\"\n class=\"response-description-markdown\"\n :value=\"currentResponse.description\" />\n </div>\n </ScalarCardFooter>\n </ScalarCard>\n</template>\n\n<style scoped>\n.response-card {\n font-size: var(--scalar-font-size-3);\n}\n\n.code-copy {\n display: flex;\n align-items: center;\n justify-content: center;\n appearance: none;\n -webkit-appearance: none;\n outline: none;\n background: transparent;\n cursor: pointer;\n color: var(--scalar-color-3);\n border: none;\n padding: 0;\n margin-right: 12px;\n}\n.code-copy:hover {\n color: var(--scalar-color-1);\n}\n.code-copy svg {\n width: 13px;\n height: 13px;\n}\n.response-card-footer {\n display: flex;\n flex-direction: row-reverse;\n flex-wrap: wrap;\n justify-content: start;\n flex-shrink: 0;\n padding: 7px 12px;\n column-gap: 8px;\n}\n.response-example-selector {\n flex-shrink: 0;\n margin: -4px;\n}\n.response-description {\n font-weight: var(--scalar-semibold);\n font-size: var(--scalar-small);\n color: var(--scalar-color--1);\n\n box-sizing: border-box;\n\n flex-grow: 1;\n}\n.response-description-markdown {\n max-height: 3lh;\n}\n\n.response-description-markdown :deep(*) {\n margin: 0;\n}\n.schema-type {\n font-size: var(--scalar-micro);\n color: var(--scalar-color-2);\n font-weight: var(--scalar-semibold);\n background: var(--scalar-background-3);\n padding: 2px 4px;\n border-radius: 4px;\n margin-right: 4px;\n}\n.schema-example {\n font-size: var(--scalar-micro);\n color: var(--scalar-color-2);\n font-weight: var(--scalar-semibold);\n}\n\n.example-response-tab {\n display: block;\n margin: 6px;\n}\n\n.scalar-card-checkbox {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n min-height: 17px;\n cursor: pointer;\n user-select: none;\n font-size: var(--scalar-small);\n font-weight: var(--scalar-font-normal);\n color: var(--scalar-color-2);\n width: fit-content;\n white-space: nowrap;\n gap: 6px;\n padding: 7px 6px;\n}\n.scalar-card-checkbox:has(.scalar-card-checkbox-input:focus-visible)\n .scalar-card-checkbox-checkmark {\n outline: 1px solid var(--scalar-color-accent);\n}\n.scalar-card-checkbox:hover {\n color: var(--scalar-color--1);\n}\n.scalar-card-checkbox .scalar-card-checkbox-input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n height: 0;\n width: 0;\n}\n\n.scalar-card-checkbox-checkmark {\n height: 16px;\n width: 16px;\n border-radius: var(--scalar-radius);\n background-color: transparent;\n background-color: var(--scalar-background-3);\n box-shadow: inset 0 0 0 var(--scalar-border-width) var(--scalar-border-color);\n}\n.scalar-card-checkbox:has(.scalar-card-checkbox-input:checked) {\n color: var(--scalar-color-1);\n font-weight: var(--scalar-semibold);\n}\n\n.scalar-card-checkbox\n .scalar-card-checkbox-input:checked\n ~ .scalar-card-checkbox-checkmark {\n background-color: var(--scalar-button-1);\n box-shadow: none;\n}\n\n.scalar-card-checkbox-checkmark:after {\n content: '';\n position: absolute;\n display: none;\n}\n\n.scalar-card-checkbox\n .scalar-card-checkbox-input:checked\n ~ .scalar-card-checkbox-checkmark:after {\n display: block;\n}\n\n.scalar-card-checkbox .scalar-card-checkbox-checkmark:after {\n right: 11.5px;\n top: 12.5px;\n width: 5px;\n height: 9px;\n border: solid 1px var(--scalar-button-1-color);\n border-width: 0 1.5px 1.5px 0;\n transform: rotate(45deg);\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ExampleResponses.vue.script.js","names":[],"sources":["../../../src/features/example-responses/ExampleResponses.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { ExamplePicker } from '@scalar/api-client/blocks/operation-code-sample'\nimport {\n ScalarCard,\n ScalarCardFooter,\n ScalarCardSection,\n ScalarIcon,\n ScalarMarkdown,\n} from '@scalar/components'\nimport { objectKeys } from '@scalar/helpers/object/object-keys'\nimport { useClipboard } from '@scalar/use-hooks/useClipboard'\nimport { getResolvedRef } from '@scalar/workspace-store/helpers/get-resolved-ref'\nimport { getExample } from '@scalar/workspace-store/request-example'\nimport type {\n MediaTypeObject,\n ResponsesObject,\n} from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport { computed, ref, toValue, useId, watch } from 'vue'\n\nimport ScreenReader from '@/components/ScreenReader.vue'\nimport ExampleSchema from '@/features/example-responses/ExampleSchema.vue'\n\nimport ExampleResponse from './ExampleResponse.vue'\nimport ExampleResponseTab from './ExampleResponseTab.vue'\nimport ExampleResponseTabList from './ExampleResponseTabList.vue'\nimport { hasResponseContent } from './helpers/has-response-content'\nimport { normalizeMimeTypeObject } from './helpers/normalize-mime-type-object'\n\n/**\n * TODO: copyToClipboard isn't using the right content if there are multiple examples\n */\n\nconst { responses } = defineProps<{\n responses: ResponsesObject\n}>()\n\nconst id = useId()\nconst { copyToClipboard } = useClipboard()\n\n// Bring the status codes in the right order.\nconst orderedStatusCodes = computed<string[]>(() =>\n Object.keys(responses ?? {}).sort(),\n)\n\n// Filter to only valid response keys that should render in the example responses panel\nconst statusCodesWithContent = computed<string[]>(() =>\n orderedStatusCodes.value.filter((statusCode) =>\n hasResponseContent(getResolvedRef(responses?.[statusCode]), statusCode),\n ),\n)\n\n// Keep track of the current selected tab\nconst selectedResponseIndex = ref<number>(0)\n\n/**\n * Clamp the selected index when the filtered list shrinks.\n * Without this, the index can become out of bounds and cause a mismatch\n * between the visible tabs and the displayed content.\n *\n * We also reset `selectedExampleKey` to match the behavior of `changeTab`,\n * since the new response may not have the same example keys.\n */\nwatch(statusCodesWithContent, (codes) => {\n if (codes.length === 0) {\n selectedResponseIndex.value = 0\n selectedExampleKey.value = ''\n } else if (selectedResponseIndex.value >= codes.length) {\n selectedResponseIndex.value = codes.length - 1\n selectedExampleKey.value = ''\n }\n})\n\n// Return the whole response object\nconst currentResponse = computed(() => {\n const currentStatusCode =\n toValue(statusCodesWithContent)[toValue(selectedResponseIndex)] ?? ''\n\n return getResolvedRef(responses?.[currentStatusCode])\n})\n\nconst currentResponseContent = computed<MediaTypeObject | undefined>(() => {\n const normalizedContent = normalizeMimeTypeObject(\n currentResponse.value?.content,\n )\n\n /** All the keys of the normalized content */\n const keys = objectKeys(normalizedContent ?? {})\n return normalizedContent?.[keys[0] ?? '']\n})\n\nconst hasMultipleExamples = computed<boolean>(\n () =>\n !!currentResponseContent.value?.examples &&\n Object.keys(currentResponseContent.value?.examples ?? {}).length > 1,\n)\n\nconst selectedExampleKey = ref<string>(\n Object.keys(currentResponseContent.value?.examples ?? {})[0] ?? '',\n)\n\n/** Get the current example to display */\nconst currentExample = computed(() => {\n if (!currentResponseContent.value) {\n return undefined\n }\n\n // When multiple examples exist and one is selected, we access it directly\n if (hasMultipleExamples.value && selectedExampleKey.value) {\n return currentResponseContent.value.examples?.[selectedExampleKey.value]\n }\n\n // Otherwise, we use getExample with an undefined exampleKey to handle fallbacks\n return getExample(currentResponseContent.value, undefined, undefined)\n})\n\nconst changeTab = (index: number) => {\n selectedResponseIndex.value = index\n selectedExampleKey.value = ''\n}\n\nconst showSchema = ref(false)\n</script>\n<template>\n <ScalarCard\n v-if=\"statusCodesWithContent.length\"\n aria-label=\"Example Responses\"\n class=\"response-card\"\n role=\"region\">\n <ExampleResponseTabList @change=\"changeTab\">\n <ExampleResponseTab\n v-for=\"statusCode in statusCodesWithContent\"\n :key=\"statusCode\"\n :aria-controls=\"id\">\n <ScreenReader>Status:</ScreenReader>\n {{ statusCode }}\n </ExampleResponseTab>\n\n <template #actions>\n <button\n v-if=\"currentResponseContent?.example\"\n class=\"code-copy\"\n type=\"button\"\n @click=\"() => copyToClipboard(currentResponseContent?.example)\">\n <ScalarIcon\n icon=\"Clipboard\"\n width=\"12px\" />\n </button>\n <label\n v-if=\"currentResponseContent?.schema\"\n class=\"scalar-card-checkbox\">\n Show Schema\n <input\n v-model=\"showSchema\"\n :aria-controls=\"id\"\n class=\"scalar-card-checkbox-input\"\n type=\"checkbox\" />\n <span class=\"scalar-card-checkbox-checkmark\" />\n </label>\n </template>\n </ExampleResponseTabList>\n <ScalarCardSection class=\"grid flex-1\">\n <!-- Schema -->\n <ExampleSchema\n v-if=\"currentResponseContent?.schema && showSchema\"\n :id=\"id\"\n :schema=\"currentResponseContent?.schema\" />\n\n <!-- Example -->\n <ExampleResponse\n v-else\n :id=\"id\"\n :example=\"currentExample\"\n :response=\"currentResponseContent\" />\n </ScalarCardSection>\n <ScalarCardFooter\n v-if=\"currentResponse?.description || hasMultipleExamples\"\n class=\"response-card-footer\">\n <ExamplePicker\n v-if=\"hasMultipleExamples\"\n v-model=\"selectedExampleKey\"\n class=\"response-example-selector px-0\"\n :examples=\"currentResponseContent?.examples\" />\n <div class=\"response-description\">\n <ScalarMarkdown\n v-if=\"currentResponse?.description\"\n class=\"response-description-markdown\"\n :value=\"currentResponse.description\" />\n </div>\n </ScalarCardFooter>\n </ScalarCard>\n</template>\n\n<style scoped>\n.response-card {\n font-size: var(--scalar-font-size-3);\n}\n\n.code-copy {\n display: flex;\n align-items: center;\n justify-content: center;\n appearance: none;\n -webkit-appearance: none;\n outline: none;\n background: transparent;\n cursor: pointer;\n color: var(--scalar-color-3);\n border: none;\n padding: 0;\n margin-right: 12px;\n}\n.code-copy:hover {\n color: var(--scalar-color-1);\n}\n.code-copy svg {\n width: 13px;\n height: 13px;\n}\n.response-card-footer {\n display: flex;\n flex-direction: row-reverse;\n flex-wrap: wrap;\n justify-content: start;\n flex-shrink: 0;\n padding: 7px 12px;\n column-gap: 8px;\n}\n.response-example-selector {\n flex-shrink: 0;\n margin: -4px;\n}\n.response-description {\n font-weight: var(--scalar-semibold);\n font-size: var(--scalar-small);\n color: var(--scalar-color--1);\n\n box-sizing: border-box;\n\n flex-grow: 1;\n}\n.response-description-markdown {\n max-height: 3lh;\n}\n\n.response-description-markdown :deep(*) {\n margin: 0;\n}\n.schema-type {\n font-size: var(--scalar-micro);\n color: var(--scalar-color-2);\n font-weight: var(--scalar-semibold);\n background: var(--scalar-background-3);\n padding: 2px 4px;\n border-radius: 4px;\n margin-right: 4px;\n}\n.schema-example {\n font-size: var(--scalar-micro);\n color: var(--scalar-color-2);\n font-weight: var(--scalar-semibold);\n}\n\n.example-response-tab {\n display: block;\n margin: 6px;\n}\n\n.scalar-card-checkbox {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n min-height: 17px;\n cursor: pointer;\n user-select: none;\n font-size: var(--scalar-small);\n font-weight: var(--scalar-font-normal);\n color: var(--scalar-color-2);\n width: fit-content;\n white-space: nowrap;\n gap: 6px;\n padding: 7px 6px;\n}\n.scalar-card-checkbox:has(.scalar-card-checkbox-input:focus-visible)\n .scalar-card-checkbox-checkmark {\n outline: 1px solid var(--scalar-color-accent);\n}\n.scalar-card-checkbox:hover {\n color: var(--scalar-color--1);\n}\n.scalar-card-checkbox .scalar-card-checkbox-input {\n position: absolute;\n opacity: 0;\n cursor: pointer;\n height: 0;\n width: 0;\n}\n\n.scalar-card-checkbox-checkmark {\n height: 16px;\n width: 16px;\n border-radius: var(--scalar-radius);\n background-color: transparent;\n background-color: var(--scalar-background-3);\n box-shadow: inset 0 0 0 var(--scalar-border-width) var(--scalar-border-color);\n}\n.scalar-card-checkbox:has(.scalar-card-checkbox-input:checked) {\n color: var(--scalar-color-1);\n font-weight: var(--scalar-semibold);\n}\n\n.scalar-card-checkbox\n .scalar-card-checkbox-input:checked\n ~ .scalar-card-checkbox-checkmark {\n background-color: var(--scalar-button-1);\n box-shadow: none;\n}\n\n.scalar-card-checkbox-checkmark:after {\n content: '';\n position: absolute;\n display: none;\n}\n\n.scalar-card-checkbox\n .scalar-card-checkbox-input:checked\n ~ .scalar-card-checkbox-checkmark:after {\n display: block;\n}\n\n.scalar-card-checkbox .scalar-card-checkbox-checkmark:after {\n right: 11.5px;\n top: 12.5px;\n width: 5px;\n height: 9px;\n border: solid 1px var(--scalar-button-1-color);\n border-width: 0 1.5px 1.5px 0;\n transform: rotate(45deg);\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExampleSchema.vue.js","names":[],"sources":["../../../src/features/example-responses/ExampleSchema.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { getResolvedRefDeep } from '@scalar/api-client/
|
|
1
|
+
{"version":3,"file":"ExampleSchema.vue.js","names":[],"sources":["../../../src/features/example-responses/ExampleSchema.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { getResolvedRefDeep } from '@scalar/api-client/blocks/operation-code-sample'\nimport { ScalarCodeBlock, ScalarVirtualText } from '@scalar/components'\nimport { prettyPrintJson } from '@scalar/helpers/json/pretty-print-json'\nimport type { ReferenceType } from '@scalar/workspace-store/schemas/v3.1/strict/reference'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/schema'\nimport { computed } from 'vue'\n\nconst { id, schema } = defineProps<{\n id: string\n schema: ReferenceType<SchemaObject>\n}>()\n\nconst schemaContent = computed(() => {\n if (!schema) {\n return undefined\n }\n\n return prettyPrintJson(getResolvedRefDeep(schema))\n})\n\nconst VIRTUALIZATION_THRESHOLD = 20_000\n\nconst shouldVirtualizeSchema = computed(() => {\n return (schemaContent.value?.length ?? 0) > VIRTUALIZATION_THRESHOLD\n})\n</script>\n\n<template>\n <ScalarCodeBlock\n v-if=\"!shouldVirtualizeSchema\"\n :id=\"id\"\n class=\"bg-b-2\"\n lang=\"json\"\n :prettyPrintedContent=\"schemaContent ?? ''\" />\n <ScalarVirtualText\n v-else\n :id=\"id\"\n containerClass=\"custom-scroll scalar-code-block border rounded-b flex flex-1 max-h-screen\"\n contentClass=\"language-plaintext whitespace-pre font-code text-base\"\n :lineHeight=\"20\"\n :text=\"schemaContent ?? ''\" />\n</template>\n"],"mappings":""}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { computed, createBlock, defineComponent, openBlock, unref } from "vue";
|
|
2
2
|
import { ScalarCodeBlock, ScalarVirtualText } from "@scalar/components";
|
|
3
|
-
import { getResolvedRefDeep } from "@scalar/api-client/
|
|
3
|
+
import { getResolvedRefDeep } from "@scalar/api-client/blocks/operation-code-sample";
|
|
4
4
|
import { prettyPrintJson } from "@scalar/helpers/json/pretty-print-json";
|
|
5
5
|
//#region src/features/example-responses/ExampleSchema.vue?vue&type=script&setup=true&lang.ts
|
|
6
6
|
var VIRTUALIZATION_THRESHOLD = 2e4;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExampleSchema.vue.script.js","names":[],"sources":["../../../src/features/example-responses/ExampleSchema.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { getResolvedRefDeep } from '@scalar/api-client/
|
|
1
|
+
{"version":3,"file":"ExampleSchema.vue.script.js","names":[],"sources":["../../../src/features/example-responses/ExampleSchema.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { getResolvedRefDeep } from '@scalar/api-client/blocks/operation-code-sample'\nimport { ScalarCodeBlock, ScalarVirtualText } from '@scalar/components'\nimport { prettyPrintJson } from '@scalar/helpers/json/pretty-print-json'\nimport type { ReferenceType } from '@scalar/workspace-store/schemas/v3.1/strict/reference'\nimport type { SchemaObject } from '@scalar/workspace-store/schemas/v3.1/strict/schema'\nimport { computed } from 'vue'\n\nconst { id, schema } = defineProps<{\n id: string\n schema: ReferenceType<SchemaObject>\n}>()\n\nconst schemaContent = computed(() => {\n if (!schema) {\n return undefined\n }\n\n return prettyPrintJson(getResolvedRefDeep(schema))\n})\n\nconst VIRTUALIZATION_THRESHOLD = 20_000\n\nconst shouldVirtualizeSchema = computed(() => {\n return (schemaContent.value?.length ?? 0) > VIRTUALIZATION_THRESHOLD\n})\n</script>\n\n<template>\n <ScalarCodeBlock\n v-if=\"!shouldVirtualizeSchema\"\n :id=\"id\"\n class=\"bg-b-2\"\n lang=\"json\"\n :prettyPrintedContent=\"schemaContent ?? ''\" />\n <ScalarVirtualText\n v-else\n :id=\"id\"\n containerClass=\"custom-scroll scalar-code-block border rounded-b flex flex-1 max-h-screen\"\n contentClass=\"language-plaintext whitespace-pre font-code text-base\"\n :lineHeight=\"20\"\n :text=\"schemaContent ?? ''\" />\n</template>\n"],"mappings":";;;;;AAqBA,IAAM,2BAA2B;;;;;;;;EARjC,MAAM,gBAAgB,eAAe;AACnC,OAAI,CAAC,QAAA,OACH;AAGF,UAAO,gBAAgB,mBAAmB,QAAA,OAAO,CAAA;IAClD;EAID,MAAM,yBAAyB,eAAe;AAC5C,WAAQ,cAAc,OAAO,UAAU,KAAK;IAC7C;;WAKU,uBAAA,SAAA,WAAA,EADT,YAKgD,MAAA,gBAAA,EAAA;;IAH7C,IAAI,QAAA;IACL,OAAM;IACN,MAAK;IACJ,sBAAsB,cAAA,SAAa;gEACtC,YAMgC,MAAA,kBAAA,EAAA;;IAJ7B,IAAI,QAAA;IACL,gBAAe;IACf,cAAa;IACZ,YAAY;IACZ,MAAM,cAAA,SAAa"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"has-response-content.d.ts","sourceRoot":"","sources":["../../../../src/features/example-responses/helpers/has-response-content.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,8DAA8D,CAAA;AA4BnH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAqBtG"}
|
package/dist/features/example-responses/{has-response-content.js → helpers/has-response-content.js}
RENAMED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { normalizeMimeTypeObject } from "./normalize-mime-type-object.js";
|
|
2
|
+
import { objectKeys } from "@scalar/helpers/object/object-keys";
|
|
3
|
+
//#region src/features/example-responses/helpers/has-response-content.ts
|
|
3
4
|
/**
|
|
4
5
|
* Checks if a media type object has any displayable content.
|
|
5
6
|
* This includes having a schema, a single example, or multiple examples.
|
|
@@ -28,7 +29,7 @@ function hasResponseContent(response, responseKey) {
|
|
|
28
29
|
return Boolean(response);
|
|
29
30
|
}
|
|
30
31
|
const normalizedContent = normalizeMimeTypeObject(response?.content);
|
|
31
|
-
const keys =
|
|
32
|
+
const keys = objectKeys(normalizedContent ?? {});
|
|
32
33
|
return hasMediaTypeContent(normalizedContent?.["application/json"] ?? normalizedContent?.["application/xml"] ?? normalizedContent?.["text/plain"] ?? normalizedContent?.["text/html"] ?? normalizedContent?.["*/*"] ?? normalizedContent?.[keys[0] ?? ""]);
|
|
33
34
|
}
|
|
34
35
|
//#endregion
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"has-response-content.js","names":[],"sources":["../../../../src/features/example-responses/helpers/has-response-content.ts"],"sourcesContent":["import { objectKeys } from '@scalar/helpers/object/object-keys'\nimport type { MediaTypeObject, ResponseObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport { normalizeMimeTypeObject } from './normalize-mime-type-object'\n\n/**\n * Checks if a media type object has any displayable content.\n * This includes having a schema, a single example, or multiple examples.\n *\n * Note: We use explicit property checks for `example` because falsy values\n * like `0`, `false`, and `\"\"` are valid JSON examples that should be displayed.\n * We still treat `null` as \"no content\" since it explicitly indicates absence.\n */\nfunction hasMediaTypeContent(mediaType: MediaTypeObject | undefined): boolean {\n if (!mediaType) {\n return false\n }\n\n const hasSchema = Boolean(mediaType.schema)\n const hasExample = 'example' in mediaType && mediaType.example !== null\n const hasExamples = Boolean(mediaType.examples)\n\n return hasSchema || hasExample || hasExamples\n}\n\nfunction isResponseKey(responseKey: string): boolean {\n return responseKey === 'default' || /^[1-5][0-9]{2}$/.test(responseKey) || /^[1-5]XX$/.test(responseKey)\n}\n\n/**\n * Checks if a response object has body content (schema, example, or examples).\n * Looks through common media types in priority order.\n */\nexport function hasResponseContent(response: ResponseObject | undefined, responseKey?: string): boolean {\n if (responseKey !== undefined) {\n if (!isResponseKey(responseKey)) {\n return false\n }\n\n return Boolean(response)\n }\n\n const normalizedContent = normalizeMimeTypeObject(response?.content)\n const keys = objectKeys(normalizedContent ?? {})\n\n const mediaType =\n normalizedContent?.['application/json'] ??\n normalizedContent?.['application/xml'] ??\n normalizedContent?.['text/plain'] ??\n normalizedContent?.['text/html'] ??\n normalizedContent?.['*/*'] ??\n normalizedContent?.[keys[0] ?? '']\n\n return hasMediaTypeContent(mediaType)\n}\n"],"mappings":";;;;;;;;;;;AAaA,SAAS,oBAAoB,WAAiD;AAC5E,KAAI,CAAC,UACH,QAAO;CAGT,MAAM,YAAY,QAAQ,UAAU,OAAO;CAC3C,MAAM,aAAa,aAAa,aAAa,UAAU,YAAY;CACnE,MAAM,cAAc,QAAQ,UAAU,SAAS;AAE/C,QAAO,aAAa,cAAc;;AAGpC,SAAS,cAAc,aAA8B;AACnD,QAAO,gBAAgB,aAAa,kBAAkB,KAAK,YAAY,IAAI,YAAY,KAAK,YAAY;;;;;;AAO1G,SAAgB,mBAAmB,UAAsC,aAA+B;AACtG,KAAI,gBAAgB,KAAA,GAAW;AAC7B,MAAI,CAAC,cAAc,YAAY,CAC7B,QAAO;AAGT,SAAO,QAAQ,SAAS;;CAG1B,MAAM,oBAAoB,wBAAwB,UAAU,QAAQ;CACpE,MAAM,OAAO,WAAW,qBAAqB,EAAE,CAAC;AAUhD,QAAO,oBAPL,oBAAoB,uBACpB,oBAAoB,sBACpB,oBAAoB,iBACpB,oBAAoB,gBACpB,oBAAoB,UACpB,oBAAoB,KAAK,MAAM,IAEI"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ResponseObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document';
|
|
2
|
+
/**
|
|
3
|
+
* Remove charset from content types
|
|
4
|
+
*
|
|
5
|
+
* Example: `application/json; charset=utf-8` -> `application/json`
|
|
6
|
+
*/
|
|
7
|
+
export declare function normalizeMimeTypeObject(content?: ResponseObject['content']): ResponseObject['content'];
|
|
8
|
+
//# sourceMappingURL=normalize-mime-type-object.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-mime-type-object.d.ts","sourceRoot":"","sources":["../../../../src/features/example-responses/helpers/normalize-mime-type-object.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8DAA8D,CAAA;AAIlG;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,GAAG,cAAc,CAAC,SAAS,CAAC,CAiBtG"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { normalizeMimeType } from "./normalize-mime-type.js";
|
|
2
|
+
//#region src/features/example-responses/helpers/normalize-mime-type-object.ts
|
|
3
|
+
/**
|
|
4
|
+
* Remove charset from content types
|
|
5
|
+
*
|
|
6
|
+
* Example: `application/json; charset=utf-8` -> `application/json`
|
|
7
|
+
*/
|
|
8
|
+
function normalizeMimeTypeObject(content) {
|
|
9
|
+
if (!content) return content;
|
|
10
|
+
const newContent = { ...content };
|
|
11
|
+
Object.entries(newContent).forEach(([key, value]) => {
|
|
12
|
+
const normalizedKey = normalizeMimeType(key);
|
|
13
|
+
if (normalizedKey) newContent[normalizedKey] = value;
|
|
14
|
+
});
|
|
15
|
+
return newContent;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { normalizeMimeTypeObject };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=normalize-mime-type-object.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-mime-type-object.js","names":[],"sources":["../../../../src/features/example-responses/helpers/normalize-mime-type-object.ts"],"sourcesContent":["import type { ResponseObject } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\n\nimport { normalizeMimeType } from './normalize-mime-type'\n\n/**\n * Remove charset from content types\n *\n * Example: `application/json; charset=utf-8` -> `application/json`\n */\nexport function normalizeMimeTypeObject(content?: ResponseObject['content']): ResponseObject['content'] {\n if (!content) {\n return content\n }\n\n const newContent: ResponseObject['content'] = {\n ...content,\n }\n\n Object.entries(newContent).forEach(([key, value]) => {\n const normalizedKey = normalizeMimeType(key)\n if (normalizedKey) {\n newContent[normalizedKey] = value\n }\n })\n\n return newContent\n}\n"],"mappings":";;;;;;;AASA,SAAgB,wBAAwB,SAAgE;AACtG,KAAI,CAAC,QACH,QAAO;CAGT,MAAM,aAAwC,EAC5C,GAAG,SACJ;AAED,QAAO,QAAQ,WAAW,CAAC,SAAS,CAAC,KAAK,WAAW;EACnD,MAAM,gBAAgB,kBAAkB,IAAI;AAC5C,MAAI,cACF,YAAW,iBAAiB;GAE9B;AAEF,QAAO"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ContentType } from '@scalar/types/legacy';
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a MIME type to a standard format.
|
|
4
|
+
*
|
|
5
|
+
* Input: application/problem+json; charset=utf-8
|
|
6
|
+
* Output: application/json
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeMimeType(contentType: undefined): undefined;
|
|
9
|
+
export declare function normalizeMimeType(contentType: string): ContentType;
|
|
10
|
+
//# sourceMappingURL=normalize-mime-type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-mime-type.d.ts","sourceRoot":"","sources":["../../../../src/features/example-responses/helpers/normalize-mime-type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAEvD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,SAAS,GAAG,SAAS,CAAA;AACpE,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/features/example-responses/helpers/normalize-mime-type.ts
|
|
2
|
+
function normalizeMimeType(contentType) {
|
|
3
|
+
if (typeof contentType !== "string") return;
|
|
4
|
+
return contentType.replace(/;.*$/, "").replace(/\/(?!.*vnd\.|fhir\+).*\+/, "/").trim();
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
export { normalizeMimeType };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=normalize-mime-type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-mime-type.js","names":[],"sources":["../../../../src/features/example-responses/helpers/normalize-mime-type.ts"],"sourcesContent":["import type { ContentType } from '@scalar/types/legacy'\n\n/**\n * Normalizes a MIME type to a standard format.\n *\n * Input: application/problem+json; charset=utf-8\n * Output: application/json\n */\nexport function normalizeMimeType(contentType: undefined): undefined\nexport function normalizeMimeType(contentType: string): ContentType\nexport function normalizeMimeType(contentType: string | undefined): ContentType | undefined {\n if (typeof contentType !== 'string') {\n return undefined\n }\n\n return (\n contentType\n // Remove '; charset=utf-8'\n .replace(/;.*$/, '')\n // Remove 'problem+' but keep vendor-specific vnd and fhir mime types\n .replace(/\\/(?!.*vnd\\.|fhir\\+).*\\+/, '/')\n // Remove whitespace\n .trim() as ContentType\n )\n}\n"],"mappings":";AAUA,SAAgB,kBAAkB,aAA0D;AAC1F,KAAI,OAAO,gBAAgB,SACzB;AAGF,QACE,YAEG,QAAQ,QAAQ,GAAG,CAEnB,QAAQ,4BAA4B,IAAI,CAExC,MAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentSelector.vue.js","names":[],"sources":["../../../src/features/multiple-documents/DocumentSelector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarListbox } from '@scalar/components'\nimport { ScalarIconCaretDown } from '@scalar/icons'\nimport { computed } from 'vue'\n\nconst props = defineProps<{\n options: { label: string; id: string }[]\n modelValue?: string\n}>()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', id: string): void\n}>()\n\nconst formattedOptions = computed(() =>\n props.options.map((o) => ({ id: o.id, label: o.label })),\n)\n\nconst selected = computed(() =>\n formattedOptions.value.find((o) => o.id === props.modelValue),\n)\n</script>\n\n<template>\n <div\n v-if=\"options.length > 1\"\n class=\"document-selector
|
|
1
|
+
{"version":3,"file":"DocumentSelector.vue.js","names":[],"sources":["../../../src/features/multiple-documents/DocumentSelector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarListbox } from '@scalar/components'\nimport { ScalarIconCaretDown } from '@scalar/icons'\nimport { computed } from 'vue'\n\nconst props = defineProps<{\n options: { label: string; id: string }[]\n modelValue?: string\n}>()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', id: string): void\n}>()\n\nconst formattedOptions = computed(() =>\n props.options.map((o) => ({ id: o.id, label: o.label })),\n)\n\nconst selected = computed(() =>\n formattedOptions.value.find((o) => o.id === props.modelValue),\n)\n</script>\n\n<template>\n <div\n v-if=\"options.length > 1\"\n class=\"document-selector px-3 pt-3\">\n <ScalarListbox\n v-slot=\"{ open }\"\n :modelValue=\"selected\"\n :options=\"formattedOptions\"\n resize\n @update:modelValue=\"(e) => emit('update:modelValue', e.id)\">\n <button\n class=\"group/dropdown-label text-c-2 hover:text-c-1 flex w-full cursor-pointer items-center gap-1 font-medium\"\n type=\"button\">\n <span class=\"overflow-hidden text-base text-ellipsis\">\n {{ selected?.label || 'Select API' }}\n </span>\n <ScalarIconCaretDown\n class=\"size-3 text-current transition-transform\"\n :class=\"{ 'rotate-180': open }\"\n weight=\"bold\" />\n </button>\n </ScalarListbox>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -4,7 +4,7 @@ import { ScalarIconCaretDown } from "@scalar/icons";
|
|
|
4
4
|
//#region src/features/multiple-documents/DocumentSelector.vue?vue&type=script&setup=true&lang.ts
|
|
5
5
|
var _hoisted_1 = {
|
|
6
6
|
key: 0,
|
|
7
|
-
class: "document-selector
|
|
7
|
+
class: "document-selector px-3 pt-3"
|
|
8
8
|
};
|
|
9
9
|
var _hoisted_2 = {
|
|
10
10
|
class: "group/dropdown-label text-c-2 hover:text-c-1 flex w-full cursor-pointer items-center gap-1 font-medium",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentSelector.vue.script.js","names":[],"sources":["../../../src/features/multiple-documents/DocumentSelector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarListbox } from '@scalar/components'\nimport { ScalarIconCaretDown } from '@scalar/icons'\nimport { computed } from 'vue'\n\nconst props = defineProps<{\n options: { label: string; id: string }[]\n modelValue?: string\n}>()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', id: string): void\n}>()\n\nconst formattedOptions = computed(() =>\n props.options.map((o) => ({ id: o.id, label: o.label })),\n)\n\nconst selected = computed(() =>\n formattedOptions.value.find((o) => o.id === props.modelValue),\n)\n</script>\n\n<template>\n <div\n v-if=\"options.length > 1\"\n class=\"document-selector
|
|
1
|
+
{"version":3,"file":"DocumentSelector.vue.script.js","names":[],"sources":["../../../src/features/multiple-documents/DocumentSelector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarListbox } from '@scalar/components'\nimport { ScalarIconCaretDown } from '@scalar/icons'\nimport { computed } from 'vue'\n\nconst props = defineProps<{\n options: { label: string; id: string }[]\n modelValue?: string\n}>()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', id: string): void\n}>()\n\nconst formattedOptions = computed(() =>\n props.options.map((o) => ({ id: o.id, label: o.label })),\n)\n\nconst selected = computed(() =>\n formattedOptions.value.find((o) => o.id === props.modelValue),\n)\n</script>\n\n<template>\n <div\n v-if=\"options.length > 1\"\n class=\"document-selector px-3 pt-3\">\n <ScalarListbox\n v-slot=\"{ open }\"\n :modelValue=\"selected\"\n :options=\"formattedOptions\"\n resize\n @update:modelValue=\"(e) => emit('update:modelValue', e.id)\">\n <button\n class=\"group/dropdown-label text-c-2 hover:text-c-1 flex w-full cursor-pointer items-center gap-1 font-medium\"\n type=\"button\">\n <span class=\"overflow-hidden text-base text-ellipsis\">\n {{ selected?.label || 'Select API' }}\n </span>\n <ScalarIconCaretDown\n class=\"size-3 text-current transition-transform\"\n :class=\"{ 'rotate-180': open }\"\n weight=\"bold\" />\n </button>\n </ScalarListbox>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAKA,MAAM,QAAQ;EAKd,MAAM,OAAO;EAIb,MAAM,mBAAmB,eACvB,MAAM,QAAQ,KAAK,OAAO;GAAE,IAAI,EAAE;GAAI,OAAO,EAAE;GAAO,EAAE,CAC1D;EAEA,MAAM,WAAW,eACf,iBAAiB,MAAM,MAAM,MAAM,EAAE,OAAO,MAAM,WAAW,CAC/D;;UAKU,QAAA,QAAQ,SAAM,KAAA,WAAA,EADtB,mBAqBM,OArBN,YAqBM,CAlBJ,YAiBgB,MAAA,cAAA,EAAA;IAfb,YAAY,SAAA;IACZ,SAAS,iBAAA;IACV,QAAA;IACC,uBAAiB,OAAA,OAAA,OAAA,MAAG,MAAM,KAAI,qBAAsB,EAAE,GAAE;;sBAWhD,EAfC,WAAI,CAKd,mBAUS,UAVT,YAUS,CAPP,mBAEO,QAFP,YAEO,gBADF,SAAA,OAAU,SAAK,aAAA,EAAA,EAAA,EAEpB,YAGkB,MAAA,oBAAA,EAAA;KAFhB,OAAK,eAAA,CAAC,4CAA0C,EAAA,cACxB,MAAI,CAAA,CAAA;KAC5B,QAAO"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { authStorage, clientStorage } from "./storage.js";
|
|
2
|
-
import { isClient } from "@scalar/api-client/
|
|
2
|
+
import { isClient } from "@scalar/api-client/blocks/operation-code-sample";
|
|
3
3
|
//#region src/helpers/load-from-perssistance.ts
|
|
4
4
|
/**
|
|
5
5
|
* Loads the default HTTP client from storage and applies it to the workspace.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-from-perssistance.js","names":[],"sources":["../../src/helpers/load-from-perssistance.ts"],"sourcesContent":["import { isClient } from '@scalar/api-client/
|
|
1
|
+
{"version":3,"file":"load-from-perssistance.js","names":[],"sources":["../../src/helpers/load-from-perssistance.ts"],"sourcesContent":["import { isClient } from '@scalar/api-client/blocks/operation-code-sample'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\n\nimport { authStorage, clientStorage } from '@/helpers/storage'\n\n/**\n * Loads the default HTTP client from storage and applies it to the workspace.\n * Only updates if no default client is already set.\n */\nexport const loadClientFromStorage = (store: WorkspaceStore): void => {\n const storedClient = clientStorage().get()\n\n if (isClient(storedClient) && !store.workspace['x-scalar-default-client']) {\n store.update('x-scalar-default-client', storedClient)\n }\n}\n\n/**\n * Loads the authentication data from storage and applies it to the workspace.\n * Only updates if no authentication data is already set.\n */\nexport const loadAuthFromStorage = (store: WorkspaceStore, slug: string): void => {\n const authPersistence = authStorage()\n const auth = authPersistence.getAuth(slug)\n store.auth.load({ [slug]: auth })\n}\n"],"mappings":";;;;;;;AASA,IAAa,yBAAyB,UAAgC;CACpE,MAAM,eAAe,eAAe,CAAC,KAAK;AAE1C,KAAI,SAAS,aAAa,IAAI,CAAC,MAAM,UAAU,2BAC7C,OAAM,OAAO,2BAA2B,aAAa;;;;;;AAQzD,IAAa,uBAAuB,OAAuB,SAAuB;CAEhF,MAAM,OADkB,aAAa,CACR,QAAQ,KAAK;AAC1C,OAAM,KAAK,KAAK,GAAG,OAAO,MAAM,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { computed, toValue, watch } from "vue";
|
|
2
2
|
import { useFavicon } from "@vueuse/core";
|
|
3
|
-
import { isClient } from "@scalar/api-client/
|
|
3
|
+
import { isClient } from "@scalar/api-client/blocks/operation-code-sample";
|
|
4
4
|
import { useSeoMeta } from "@unhead/vue";
|
|
5
5
|
//#region src/helpers/map-config-to-workspace-store.ts
|
|
6
6
|
var mapConfigToWorkspaceStore = ({ config, store, isDarkMode }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-config-to-workspace-store.js","names":[],"sources":["../../src/helpers/map-config-to-workspace-store.ts"],"sourcesContent":["import { isClient } from '@scalar/api-client/
|
|
1
|
+
{"version":3,"file":"map-config-to-workspace-store.js","names":[],"sources":["../../src/helpers/map-config-to-workspace-store.ts"],"sourcesContent":["import { isClient } from '@scalar/api-client/blocks/operation-code-sample'\nimport type { ApiReferenceConfigurationRaw } from '@scalar/types/api-reference'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { useSeoMeta } from '@unhead/vue'\nimport { useFavicon } from '@vueuse/core'\nimport { type MaybeRefOrGetter, type Ref, computed, toValue, watch } from 'vue'\n\nexport const mapConfigToWorkspaceStore = ({\n config,\n store,\n isDarkMode,\n}: {\n config: MaybeRefOrGetter<ApiReferenceConfigurationRaw>\n store: WorkspaceStore\n isDarkMode: Ref<boolean>\n}) => {\n // Update the workspace store if default client changes\n watch(\n () => toValue(config).defaultHttpClient,\n (newValue) => {\n if (newValue) {\n const { targetKey, clientKey } = newValue\n\n const clientId = `${targetKey}/${clientKey}`\n if (isClient(clientId)) {\n store.update('x-scalar-default-client', clientId)\n }\n }\n },\n { immediate: true },\n )\n\n /** Update the dark mode state when props change */\n watch(\n () => toValue(config).darkMode,\n (isDark) => store.update('x-scalar-color-mode', isDark ? 'dark' : 'light'),\n )\n\n // Temporary mapping of isDarkMode until we update the standalone component\n watch(\n () => isDarkMode.value,\n (newIsDark) => store.update('x-scalar-color-mode', newIsDark ? 'dark' : 'light'),\n { immediate: true },\n )\n\n if (toValue(config).metaData) {\n useSeoMeta(toValue(config).metaData)\n }\n\n // Update the active proxy when the proxyUrl changes\n watch(\n () => toValue(config).proxyUrl,\n (newProxyUrl) => store.update('x-scalar-active-proxy', newProxyUrl),\n { immediate: true },\n )\n\n const favicon = computed(() => toValue(config).favicon)\n useFavicon(favicon)\n}\n"],"mappings":";;;;;AAOA,IAAa,6BAA6B,EACxC,QACA,OACA,iBAKI;AAEJ,aACQ,QAAQ,OAAO,CAAC,oBACrB,aAAa;AACZ,MAAI,UAAU;GACZ,MAAM,EAAE,WAAW,cAAc;GAEjC,MAAM,WAAW,GAAG,UAAU,GAAG;AACjC,OAAI,SAAS,SAAS,CACpB,OAAM,OAAO,2BAA2B,SAAS;;IAIvD,EAAE,WAAW,MAAM,CACpB;;AAGD,aACQ,QAAQ,OAAO,CAAC,WACrB,WAAW,MAAM,OAAO,uBAAuB,SAAS,SAAS,QAAQ,CAC3E;AAGD,aACQ,WAAW,QAChB,cAAc,MAAM,OAAO,uBAAuB,YAAY,SAAS,QAAQ,EAChF,EAAE,WAAW,MAAM,CACpB;AAED,KAAI,QAAQ,OAAO,CAAC,SAClB,YAAW,QAAQ,OAAO,CAAC,SAAS;AAItC,aACQ,QAAQ,OAAO,CAAC,WACrB,gBAAgB,MAAM,OAAO,yBAAyB,YAAY,EACnE,EAAE,WAAW,MAAM,CACpB;AAGD,YADgB,eAAe,QAAQ,OAAO,CAAC,QAAQ,CACpC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { apiReferenceConfigurationWithSourceSchema, isConfigurationWithSources } from "@scalar/types/api-reference";
|
|
2
|
-
import { parseJsonOrYaml } from "@scalar/oas-utils/helpers";
|
|
3
2
|
import GithubSlugger from "github-slugger";
|
|
3
|
+
import { parseJsonOrYaml } from "@scalar/oas-utils/helpers";
|
|
4
4
|
//#region src/helpers/normalize-configurations.ts
|
|
5
5
|
/**
|
|
6
6
|
* Take any configuration and return a flat array of configurations.
|
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
import { type TemplateRef } from 'vue';
|
|
2
|
-
|
|
2
|
+
type UseIntersectionOptions = {
|
|
3
|
+
/** Called when the element stops intersecting. */
|
|
4
|
+
onExit?: () => void;
|
|
5
|
+
/**
|
|
6
|
+
* Whether to immediately fire the intersection as soon as the element is on the screen.
|
|
7
|
+
*
|
|
8
|
+
* When false (default) we use a root margin that is 2% of the viewport height on the middle of the viewport.
|
|
9
|
+
*/
|
|
10
|
+
immediate?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare const useIntersection: (el: TemplateRef<HTMLElement | undefined>, onIntersect: () => void, options?: UseIntersectionOptions) => void;
|
|
13
|
+
export {};
|
|
3
14
|
//# sourceMappingURL=use-intersection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-intersection.d.ts","sourceRoot":"","sources":["../../src/hooks/use-intersection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAAa,MAAM,KAAK,CAAA;AAQjD,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"use-intersection.d.ts","sourceRoot":"","sources":["../../src/hooks/use-intersection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAAa,MAAM,KAAK,CAAA;AAQjD,KAAK,sBAAsB,GAAG;IAC5B,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,eAAe,GAC1B,IAAI,WAAW,CAAC,WAAW,GAAG,SAAS,CAAC,EACxC,aAAa,MAAM,IAAI,EACvB,UAAU,sBAAsB,SAsBjC,CAAA"}
|
|
@@ -6,14 +6,16 @@ import { useIntersectionObserver } from "@vueuse/core";
|
|
|
6
6
|
* the viewport (~2% of viewport height). Emits only while the target overlaps that line.
|
|
7
7
|
*/
|
|
8
8
|
var VIEWPORT_VERTICAL_CENTER_ROOT_MARGIN = "-49% 0px -49% 0px";
|
|
9
|
-
var useIntersection = (el, onIntersect) => {
|
|
9
|
+
var useIntersection = (el, onIntersect, options) => {
|
|
10
10
|
onMounted(() => {
|
|
11
|
+
const observerOptions = {
|
|
12
|
+
rootMargin: options?.immediate ? "0px 0px 0px 0px" : VIEWPORT_VERTICAL_CENTER_ROOT_MARGIN,
|
|
13
|
+
threshold: 0
|
|
14
|
+
};
|
|
11
15
|
if (el.value) useIntersectionObserver(el, ([entry]) => {
|
|
12
16
|
if (entry?.isIntersecting) onIntersect();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
threshold: 0
|
|
16
|
-
});
|
|
17
|
+
else options?.onExit?.();
|
|
18
|
+
}, observerOptions);
|
|
17
19
|
});
|
|
18
20
|
};
|
|
19
21
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-intersection.js","names":[],"sources":["../../src/hooks/use-intersection.ts"],"sourcesContent":["import { useIntersectionObserver } from '@vueuse/core'\nimport { type TemplateRef, onMounted } from 'vue'\n\n/**\n * Shrinks the observation root to a thin horizontal strip at the vertical middle of\n * the viewport (~2% of viewport height). Emits only while the target overlaps that line.\n */\nconst VIEWPORT_VERTICAL_CENTER_ROOT_MARGIN = '-49% 0px -49% 0px'\n\nexport const useIntersection = (el: TemplateRef<HTMLElement | undefined
|
|
1
|
+
{"version":3,"file":"use-intersection.js","names":[],"sources":["../../src/hooks/use-intersection.ts"],"sourcesContent":["import { useIntersectionObserver } from '@vueuse/core'\nimport { type TemplateRef, onMounted } from 'vue'\n\n/**\n * Shrinks the observation root to a thin horizontal strip at the vertical middle of\n * the viewport (~2% of viewport height). Emits only while the target overlaps that line.\n */\nconst VIEWPORT_VERTICAL_CENTER_ROOT_MARGIN = '-49% 0px -49% 0px'\n\ntype UseIntersectionOptions = {\n /** Called when the element stops intersecting. */\n onExit?: () => void\n /**\n * Whether to immediately fire the intersection as soon as the element is on the screen.\n *\n * When false (default) we use a root margin that is 2% of the viewport height on the middle of the viewport.\n */\n immediate?: boolean\n}\n\nexport const useIntersection = (\n el: TemplateRef<HTMLElement | undefined>,\n onIntersect: () => void,\n options?: UseIntersectionOptions,\n) => {\n onMounted(() => {\n const observerOptions = {\n rootMargin: options?.immediate ? '0px 0px 0px 0px' : VIEWPORT_VERTICAL_CENTER_ROOT_MARGIN,\n threshold: 0,\n } as const\n\n if (el.value) {\n useIntersectionObserver(\n el,\n ([entry]) => {\n if (entry?.isIntersecting) {\n onIntersect()\n } else {\n options?.onExit?.()\n }\n },\n observerOptions,\n )\n }\n })\n}\n"],"mappings":";;;;;;;AAOA,IAAM,uCAAuC;AAa7C,IAAa,mBACX,IACA,aACA,YACG;AACH,iBAAgB;EACd,MAAM,kBAAkB;GACtB,YAAY,SAAS,YAAY,oBAAoB;GACrD,WAAW;GACZ;AAED,MAAI,GAAG,MACL,yBACE,KACC,CAAC,WAAW;AACX,OAAI,OAAO,eACT,cAAa;OAEb,UAAS,UAAU;KAGvB,gBACD;GAEH"}
|