UNPKG

@scalar/api-client

Version:

the open source API testing client

214 lines (213 loc) 9.2 kB
import { defineComponent as W, useAttrs as H, ref as u, computed as d, toRef as r, watch as J, createElementBlock as i, openBlock as l, Fragment as Q, createBlock as m, createCommentVNode as f, normalizeClass as G, createElementVNode as V, toDisplayString as X, mergeProps as Y, unref as T, withKeys as b, withModifiers as A, createTextVNode as B, renderSlot as N } from "vue"; import { isDefined as Z } from "@scalar/helpers/array/is-defined"; import { useCodeMirror as _, useDropdown as ee, colorPicker as te } from "@scalar/use-codemirror"; import { nanoid as ne } from "nanoid"; import p from "../data-table/DataTableInputSelect.vue.js"; import le from "../../features/environments/components/EnvironmentVariablesDropdown.vue.js"; import { pillPlugin as oe, backspaceCommand as ae } from "./code-variable-widget.js"; const re = { class: "whitespace-nowrap" }, ie = ["id"], ue = { 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" }, de = { key: 5, class: "centered-y text-orange absolute right-7 text-xs" }, se = { key: 6, class: "centered-y absolute right-0 flex h-full items-center p-1.5 group-has-[.cm-focused]:z-1" }, fe = { 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" }, ce = { inheritAttrs: !1 }, xe = /* @__PURE__ */ W({ ...ce, __name: "CodeInput", props: { modelValue: { type: [String, Number, Boolean, Array, Object] }, environment: {}, type: {}, disabled: { type: Boolean, default: !1 }, error: { type: Boolean, default: !1 }, layout: { default: "desktop" }, enum: {}, examples: {}, default: { type: [String, Number, Boolean, Array, Object] }, nullable: { type: Boolean, default: !1 }, placeholder: {}, required: { type: Boolean }, colorPicker: { type: Boolean, default: !1 }, lineNumbers: { type: Boolean, default: !1 }, lint: { type: Boolean, default: !1 }, lineWrapping: { type: Boolean, default: !1 }, language: {}, extensions: { default: () => [] }, disableTabIndent: { type: Boolean, default: !1 }, disableEnter: { type: Boolean, default: !1 }, disableCloseBrackets: { type: Boolean, default: !1 }, emitOnBlur: { type: Boolean, default: !0 }, withVariables: { type: Boolean, default: !0 }, alwaysEmitChange: { type: Boolean, default: !1 }, handleFieldChange: { type: Function }, handleFieldSubmit: { type: Function }, linethrough: { type: Boolean } }, emits: ["update:modelValue", "submit", "blur", "redirectToEnvironment"], setup(e, { expose: O, emit: $ }) { const s = $, k = H(), I = k.id || `id-${ne()}`, y = u(!1), M = d(() => e.enum?.length ? !1 : e.type === "boolean" || Array.isArray(e.type) && e.type.includes("boolean")), C = d( () => e.nullable ? ["true", "false", "null"] : ["true", "false"] ), R = d(() => Array.isArray(e.type) ? e.type.find((t) => t !== "null") ?? "string" : e.type), E = (t) => { !e.alwaysEmitChange && t === v(e.modelValue) || (e.handleFieldChange ? e.handleFieldChange(t) : s("update:modelValue", t)); }, h = (t) => { e.handleFieldSubmit ? e.handleFieldSubmit(t) : s("submit", t); }, S = (t) => { y.value = !1, e.emitOnBlur && e.modelValue && h(t), s("blur", t); }, g = (t) => s("update:modelValue", t), q = () => { const t = [...e.extensions]; return e.colorPicker && t.push(te), t; }, z = d( () => oe({ environment: e.environment, isReadOnly: e.layout === "modal" }) ), j = d(() => [ ...q(), z.value, ae ]), P = u(null), v = (t) => typeof t == "string" ? t : JSON.stringify(t), { codeMirror: o } = _({ content: r(() => v(e.modelValue)), onChange: (t) => { E(t), U(); }, onFocus: () => { y.value = !0; }, onBlur: S, codeMirrorRef: P, disableTabIndent: r(() => e.disableTabIndent), disableEnter: r(() => e.disableEnter), disableCloseBrackets: r(() => e.disableCloseBrackets), lineNumbers: r(() => e.lineNumbers), language: r(() => e.language), lint: r(() => e.lint), extensions: j, placeholder: r(() => e.placeholder) }); J(o, () => { o.value && Object.hasOwn(k, "autofocus") && o.value.focus(); }); const w = u(!1), D = u(""), F = u({ left: 0, top: 0 }), x = u(null), { handleDropdownSelect: K, updateDropdownVisibility: U } = ee({ codeMirror: o, query: D, showDropdown: w, dropdownPosition: F }), L = d(() => w.value && e.withVariables && e.layout !== "modal" && !!e.environment), c = (t, n) => { if (w.value) { t === "down" || t === "up" ? (n.preventDefault(), x.value?.handleArrowKey(t)) : t === "enter" && (n.preventDefault(), x.value?.handleSelect()); return; } t === "escape" && !e.disableTabIndent && n.stopPropagation(), t === "enter" && n.target instanceof HTMLDivElement && h(n.target.textContent ?? ""); }; return O({ /** * Focus the codemirror element * * @param cursorAtEnd boolean place the cursor at the end of the input */ focus: (t) => { if (!o.value || (o.value.focus(), !Z(t))) return; const n = t === "start" ? 0 : t === "end" ? o.value.state.doc.length : t; o.value.dispatch({ selection: { anchor: n }, scrollIntoView: !0 }); }, isFocused: y, handleChange: E, handleSubmit: h, handleBlur: S, booleanOptions: C, codeMirror: o, modelValue: e.modelValue, cursorPosition: () => o.value?.state.selection.main.head, serializeValue: v }), (t, n) => (l(), i(Q, null, [ e.disabled ? (l(), i("div", { key: 0, class: G(["text-c-2 flex cursor-default items-center justify-center", { "font-code pr-2 pl-1 text-base": e.layout === "modal", "px-2": e.layout !== "modal", "line-through": e.linethrough }]), "data-testid": "code-input-disabled" }, [ V("span", re, X(e.modelValue), 1) ], 2)) : e.enum?.length ? (l(), m(p, { key: 1, default: e.default, modelValue: e.modelValue, type: R.value, value: e.enum, "onUpdate:modelValue": g }, null, 8, ["default", "modelValue", "type", "value"])) : M.value ? (l(), m(p, { key: 2, default: e.default, modelValue: e.modelValue, value: C.value, "onUpdate:modelValue": g }, null, 8, ["default", "modelValue", "value"])) : e.examples?.length ? (l(), m(p, { key: 3, default: e.default, modelValue: e.modelValue, value: e.examples, "onUpdate:modelValue": g }, null, 8, ["default", "modelValue", "value"])) : (l(), i("div", Y({ key: 4, id: T(I) }, t.$attrs, { ref_key: "codeMirrorRef", ref: P, 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": e.lineWrapping, "flow-code-input--error": e.error, "line-through": e.linethrough }], onKeydown: [ n[0] || (n[0] = b(A((a) => c("down", a), ["stop"]), ["down"])), n[1] || (n[1] = b((a) => c("enter", a), ["enter"])), n[2] || (n[2] = b((a) => c("escape", a), ["escape"])), n[3] || (n[3] = b(A((a) => c("up", a), ["stop"]), ["up"])) ] }), [ e.disableTabIndent ? f("", !0) : (l(), i("div", ue, [...n[5] || (n[5] = [ B(" Press ", -1), V("kbd", { class: "-mx-0.25 rounded border px-0.5 font-mono" }, "Esc", -1), B(" then ", -1), V("kbd", { class: "-mx-0.25 rounded border px-0.5 font-mono" }, "Tab", -1), B(" to exit ", -1) ])])) ], 16, ie)), t.$slots.warning ? (l(), i("div", de, [ N(t.$slots, "warning", {}, void 0, !0) ])) : f("", !0), t.$slots.icon ? (l(), i("div", se, [ N(t.$slots, "icon", {}, void 0, !0) ])) : f("", !0), e.required ? (l(), i("div", fe, " Required ")) : f("", !0), L.value && e.environment ? (l(), m(le, { key: 8, ref_key: "dropdownRef", ref: x, dropdownPosition: F.value, environment: e.environment, query: D.value, onRedirect: n[4] || (n[4] = (a) => s("redirectToEnvironment")), onSelect: T(K) }, null, 8, ["dropdownPosition", "environment", "query", "onSelect"])) : f("", !0) ], 64)); } }); export { xe as default };