import { useLayout } from "../../hooks/useLayout.js";
import EnvironmentVariableDropdown_default from "../../views/Environment/EnvironmentVariableDropdown.vue.js";
import DataTableInputSelect_default from "../DataTable/DataTableInputSelect.vue.js";
import { backspaceCommand, pillPlugin } from "./codeVariableWidget.js";
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, mergeProps, normalizeClass, openBlock, ref, renderSlot, toDisplayString, toRef, unref, useAttrs, watch, withKeys, withModifiers } from "vue";
import { colorPicker, useCodeMirror, useDropdown } from "@scalar/use-codemirror";
import { nanoid } from "nanoid";
//#region src/components/CodeInput/CodeInput.vue?vue&type=script&setup=true&lang.ts
var _hoisted_1 = { class: "whitespace-nowrap" };
var _hoisted_2 = ["id"];
var _hoisted_3 = {
	key: 0,
	class: "z-context text-c-2 absolute right-1.5 bottom-1 hidden font-sans group-has-[:focus-visible]/input:block",
	role: "alert"
};
var _hoisted_4 = {
	key: 5,
	class: "centered-y text-orange absolute right-7 text-xs"
};
var _hoisted_5 = {
	key: 6,
	class: "centered-y absolute right-0 flex h-full items-center p-1.5 group-has-[.cm-focused]:z-1"
};
var _hoisted_6 = {
	key: 7,
	class: "required centered-y text-xxs text-c-3 group-[.error]:text-red bg-b-1 pointer-events-none absolute right-0 mr-0.5 pt-px pr-2 opacity-100 shadow-[-8px_0_4px_var(--scalar-background-1)] transition-opacity duration-150 group-[.alert]:bg-transparent group-[.alert]:shadow-none group-[.error]:bg-transparent group-[.error]:shadow-none peer-has-[.cm-focused]:opacity-0"
};
var CodeInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
	inheritAttrs: false,
	__name: "CodeInput",
	props: {
		colorPicker: {
			type: Boolean,
			default: false
		},
		disabled: {
			type: Boolean,
			default: false
		},
		modelValue: {},
		error: { type: Boolean },
		emitOnBlur: {
			type: Boolean,
			default: true
		},
		extensions: { default: () => [] },
		lineNumbers: { type: Boolean },
		lint: { type: Boolean },
		disableTabIndent: {
			type: Boolean,
			default: false
		},
		language: {},
		handleFieldSubmit: {},
		handleFieldChange: {},
		placeholder: {},
		required: { type: Boolean },
		disableEnter: {
			type: Boolean,
			default: false
		},
		disableCloseBrackets: {
			type: Boolean,
			default: false
		},
		enum: {},
		examples: {},
		type: {},
		nullable: {
			type: Boolean,
			default: false
		},
		withVariables: {
			type: Boolean,
			default: true
		},
		importCurl: { type: Boolean },
		default: {},
		environment: {},
		envVariables: {},
		lineWrapping: {
			type: Boolean,
			default: false
		}
	},
	emits: [
		"submit",
		"update:modelValue",
		"curl",
		"blur"
	],
	setup(__props, { expose: __expose, emit: __emit }) {
		const props = __props;
		const emit = __emit;
		const attrs = useAttrs();
		const uid = attrs.id || `id-${nanoid()}`;
		const isFocused = ref(false);
		const showDropdown = ref(false);
		const dropdownQuery = ref("");
		const dropdownPosition = ref({
			left: 0,
			top: 0
		});
		const dropdownRef = ref(null);
		const { layout } = useLayout();
		/** Change is emitted during typing. This does not trigger validation */
		function handleChange(value) {
			if (value === props.modelValue) return null;
			if (props.importCurl && value.trim().toLowerCase().startsWith("curl")) {
				emit("curl", value);
				codeMirror.value?.dispatch({ changes: {
					from: 0,
					to: codeMirror.value.state.doc.length,
					insert: String(props.modelValue)
				} });
				return null;
			}
			return props.handleFieldChange ? props.handleFieldChange(value) : emit("update:modelValue", value);
		}
		/** Submit is emitted on blur and enter. This will trigger validation */
		function handleSubmit(value) {
			return props.handleFieldSubmit ? props.handleFieldSubmit(value) : emit("submit", value);
		}
		/** Optional submit on blur.  */
		function handleBlur(value) {
			isFocused.value = false;
			if (props.emitOnBlur && props.modelValue) handleSubmit(value);
			emit("blur", value);
		}
		const extensions = [...props.extensions];
		if (props.colorPicker) extensions.push(colorPicker);
		const pillPluginExtension = computed(() => pillPlugin({
			environment: props.environment,
			envVariables: props.envVariables,
			isReadOnly: layout === "modal"
		}));
		const baseExtensions = computed(() => [
			...extensions,
			pillPluginExtension.value,
			backspaceCommand
		]);
		const codeMirrorRef = ref(null);
		const { codeMirror } = useCodeMirror({
			content: toRef(() => props.modelValue !== void 0 ? String(props.modelValue) : ""),
			onChange: (value) => {
				handleChange(value);
				updateDropdownVisibility();
			},
			onFocus: () => isFocused.value = true,
			onBlur: (val) => handleBlur(val),
			codeMirrorRef,
			disableTabIndent: toRef(() => props.disableTabIndent),
			disableEnter: toRef(() => props.disableEnter),
			disableCloseBrackets: toRef(() => props.disableCloseBrackets),
			lineNumbers: toRef(() => props.lineNumbers),
			language: toRef(() => props.language),
			lint: toRef(() => props.lint),
			extensions: baseExtensions,
			placeholder: toRef(() => props.placeholder)
		});
		codeMirror.value?.focus();
		watch(codeMirror, () => {
			if (codeMirror.value && Object.hasOwn(attrs, "autofocus")) codeMirror.value.focus();
		});
		const { handleDropdownSelect, updateDropdownVisibility } = useDropdown({
			codeMirror,
			query: dropdownQuery,
			showDropdown,
			dropdownPosition
		});
		const booleanOptions = computed(() => props.nullable ? [
			"true",
			"false",
			"null"
		] : ["true", "false"]);
		const handleKeyDown = (key, event) => {
			if (showDropdown.value) {
				if (key === "down") {
					event.preventDefault();
					dropdownRef.value?.handleArrowKey("down");
				} else if (key === "up") {
					event.preventDefault();
					dropdownRef.value?.handleArrowKey("up");
				} else if (key === "enter") {
					event.preventDefault();
					dropdownRef.value?.handleSelect();
				}
			} else if (key === "escape") {
				if (!props.disableTabIndent) event.stopPropagation();
			} else if (key === "enter" && event.target instanceof HTMLDivElement) handleSubmit(event.target.textContent ?? "");
		};
		const defaultType = computed(() => {
			return Array.isArray(props.type) ? props.type.find((type) => type !== "null") ?? "string" : props.type;
		});
		const displayVariablesDropdown = computed(() => showDropdown.value && props.withVariables && layout !== "modal" && props.environment);
		__expose({
			focus: () => {
				codeMirror.value?.focus();
			},
			handleChange,
			handleSubmit,
			handleBlur,
			booleanOptions,
			codeMirror,
			modelValue: props.modelValue
		});
		return (_ctx, _cache) => {
			return openBlock(), createElementBlock(Fragment, null, [
				__props.disabled ? (openBlock(), createElementBlock("div", {
					key: 0,
					class: normalizeClass(["text-c-2 flex cursor-default items-center justify-center", unref(layout) === "modal" ? "font-code pr-2 pl-1 text-base" : "px-2"]),
					"data-testid": "code-input-disabled"
				}, [createElementVNode("span", _hoisted_1, toDisplayString(__props.modelValue), 1)], 2)) : props.enum && props.enum.length ? (openBlock(), createBlock(DataTableInputSelect_default, {
					key: 1,
					default: props.default,
					modelValue: __props.modelValue,
					type: defaultType.value,
					value: props.enum,
					"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", $event))
				}, null, 8, [
					"default",
					"modelValue",
					"type",
					"value"
				])) : __props.type === "boolean" || __props.type?.includes("boolean") ? (openBlock(), createBlock(DataTableInputSelect_default, {
					key: 2,
					default: props.default,
					modelValue: __props.modelValue,
					value: booleanOptions.value,
					"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => emit("update:modelValue", $event))
				}, null, 8, [
					"default",
					"modelValue",
					"value"
				])) : props.examples && props.examples.length ? (openBlock(), createBlock(DataTableInputSelect_default, {
					key: 3,
					default: props.default,
					modelValue: props.modelValue,
					value: props.examples,
					"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => emit("update:modelValue", $event))
				}, null, 8, [
					"default",
					"modelValue",
					"value"
				])) : (openBlock(), createElementBlock("div", mergeProps({
					key: 4,
					id: unref(uid)
				}, _ctx.$attrs, {
					ref_key: "codeMirrorRef",
					ref: codeMirrorRef,
					class: ["group/input group-[.alert]:outline-orange group-[.error]:outline-red font-code peer relative w-full overflow-hidden text-xs leading-[1.44] whitespace-nowrap -outline-offset-1 has-[:focus-visible]:rounded-[4px] has-[:focus-visible]:outline", {
						"line-wrapping has-[:focus-visible]:bg-b-1 has-[:focus-visible]:absolute has-[:focus-visible]:z-1": __props.lineWrapping,
						"flow-code-input--error": __props.error
					}],
					onKeydown: [
						_cache[3] || (_cache[3] = withKeys(withModifiers(($event) => handleKeyDown("down", $event), ["stop"]), ["down"])),
						_cache[4] || (_cache[4] = withKeys(($event) => handleKeyDown("enter", $event), ["enter"])),
						_cache[5] || (_cache[5] = withKeys(($event) => handleKeyDown("escape", $event), ["escape"])),
						_cache[6] || (_cache[6] = withKeys(withModifiers(($event) => handleKeyDown("up", $event), ["stop"]), ["up"]))
					]
				}), [!__props.disableTabIndent ? (openBlock(), createElementBlock("div", _hoisted_3, [..._cache[7] || (_cache[7] = [
					createTextVNode(" Press ", -1),
					createElementVNode("kbd", { class: "-mx-0.25 rounded border px-0.5 font-mono" }, "Esc", -1),
					createTextVNode(" then ", -1),
					createElementVNode("kbd", { class: "-mx-0.25 rounded border px-0.5 font-mono" }, "Tab", -1),
					createTextVNode(" to exit ", -1)
				])])) : createCommentVNode("", true)], 16, _hoisted_2)),
				_ctx.$slots.warning ? (openBlock(), createElementBlock("div", _hoisted_4, [renderSlot(_ctx.$slots, "warning", {}, void 0, true)])) : createCommentVNode("", true),
				_ctx.$slots.icon ? (openBlock(), createElementBlock("div", _hoisted_5, [renderSlot(_ctx.$slots, "icon", {}, void 0, true)])) : createCommentVNode("", true),
				__props.required ? (openBlock(), createElementBlock("div", _hoisted_6, " Required ")) : createCommentVNode("", true),
				displayVariablesDropdown.value ? (openBlock(), createBlock(EnvironmentVariableDropdown_default, {
					key: 8,
					ref_key: "dropdownRef",
					ref: dropdownRef,
					dropdownPosition: dropdownPosition.value,
					envVariables: __props.envVariables,
					environment: __props.environment,
					query: dropdownQuery.value,
					onSelect: unref(handleDropdownSelect)
				}, null, 8, [
					"dropdownPosition",
					"envVariables",
					"environment",
					"query",
					"onSelect"
				])) : createCommentVNode("", true)
			], 64);
		};
	}
});
//#endregion
export { CodeInput_vue_vue_type_script_setup_true_lang_default as default };

//# sourceMappingURL=CodeInput.vue.script.js.map