@scalar/api-client 3.10.3 → 3.11.0

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.
Files changed (128) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/style.css +200 -103
  3. package/dist/v2/blocks/operation-block/OperationBlock.vue.d.ts.map +1 -1
  4. package/dist/v2/blocks/operation-block/OperationBlock.vue.js.map +1 -1
  5. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js +9 -0
  6. package/dist/v2/blocks/operation-block/OperationBlock.vue.script.js.map +1 -1
  7. package/dist/v2/blocks/operation-block/helpers/send-request.d.ts +7 -1
  8. package/dist/v2/blocks/operation-block/helpers/send-request.d.ts.map +1 -1
  9. package/dist/v2/blocks/operation-block/helpers/send-request.js +2 -2
  10. package/dist/v2/blocks/operation-block/helpers/send-request.js.map +1 -1
  11. package/dist/v2/blocks/request-block/RequestBlock.vue.d.ts.map +1 -1
  12. package/dist/v2/blocks/request-block/RequestBlock.vue.js +1 -1
  13. package/dist/v2/blocks/request-block/RequestBlock.vue.js.map +1 -1
  14. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js +46 -9
  15. package/dist/v2/blocks/request-block/RequestBlock.vue.script.js.map +1 -1
  16. package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts +4 -0
  17. package/dist/v2/blocks/request-block/components/RequestParams.vue.d.ts.map +1 -1
  18. package/dist/v2/blocks/request-block/components/RequestParams.vue.js.map +1 -1
  19. package/dist/v2/blocks/request-block/components/RequestParams.vue.script.js.map +1 -1
  20. package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts +3 -11
  21. package/dist/v2/blocks/request-block/components/RequestTable.vue.d.ts.map +1 -1
  22. package/dist/v2/blocks/request-block/components/RequestTable.vue.js +1 -1
  23. package/dist/v2/blocks/request-block/components/RequestTable.vue.js.map +1 -1
  24. package/dist/v2/blocks/request-block/components/RequestTable.vue.script.js.map +1 -1
  25. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts +8 -10
  26. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.d.ts.map +1 -1
  27. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.js.map +1 -1
  28. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js +24 -23
  29. package/dist/v2/blocks/request-block/components/RequestTableRow.vue.script.js.map +1 -1
  30. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.d.ts +9 -6
  31. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.d.ts.map +1 -1
  32. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.js +31 -4
  33. package/dist/v2/blocks/request-block/helpers/create-parameter-handlers.js.map +1 -1
  34. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.d.ts +4 -0
  35. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.d.ts.map +1 -1
  36. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js +78 -5
  37. package/dist/v2/blocks/request-block/helpers/create-parameter-rows.js.map +1 -1
  38. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.d.ts.map +1 -1
  39. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.js +1 -1
  40. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.js.map +1 -1
  41. package/dist/v2/blocks/scalar-address-bar-block/components/AddressBar.vue.script.js.map +1 -1
  42. package/dist/v2/blocks/scalar-auth-selector-block/components/AuthSelector.vue.script.js.map +1 -1
  43. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.d.ts +4 -1
  44. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.d.ts.map +1 -1
  45. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.js.map +1 -1
  46. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js +2 -2
  47. package/dist/v2/blocks/scalar-auth-selector-block/components/OAuth2.vue.script.js.map +1 -1
  48. package/dist/v2/blocks/scalar-auth-selector-block/components/OpenIDConnect.vue.d.ts +3 -0
  49. package/dist/v2/blocks/scalar-auth-selector-block/components/OpenIDConnect.vue.d.ts.map +1 -1
  50. package/dist/v2/blocks/scalar-auth-selector-block/components/OpenIDConnect.vue.js.map +1 -1
  51. package/dist/v2/blocks/scalar-auth-selector-block/components/OpenIDConnect.vue.script.js +3 -2
  52. package/dist/v2/blocks/scalar-auth-selector-block/components/OpenIDConnect.vue.script.js.map +1 -1
  53. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.d.ts.map +1 -1
  54. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.js.map +1 -1
  55. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.script.js +0 -1
  56. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthDataTableInput.vue.script.js.map +1 -1
  57. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.d.ts.map +1 -1
  58. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.js.map +1 -1
  59. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js +2 -0
  60. package/dist/v2/blocks/scalar-auth-selector-block/components/RequestAuthTab.vue.script.js.map +1 -1
  61. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-openid-connect-discovery.d.ts +4 -1
  62. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-openid-connect-discovery.d.ts.map +1 -1
  63. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-openid-connect-discovery.js +4 -3
  64. package/dist/v2/blocks/scalar-auth-selector-block/helpers/fetch-openid-connect-discovery.js.map +1 -1
  65. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.d.ts +7 -2
  66. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.d.ts.map +1 -1
  67. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js +11 -9
  68. package/dist/v2/blocks/scalar-auth-selector-block/helpers/oauth.js.map +1 -1
  69. package/dist/v2/components/code-input/CodeInput.vue.d.ts.map +1 -1
  70. package/dist/v2/components/code-input/CodeInput.vue.js +1 -1
  71. package/dist/v2/components/code-input/CodeInput.vue.js.map +1 -1
  72. package/dist/v2/components/code-input/CodeInput.vue.script.js +3 -2
  73. package/dist/v2/components/code-input/CodeInput.vue.script.js.map +1 -1
  74. package/dist/v2/components/code-input/CodeInputLite.vue.d.ts +124 -0
  75. package/dist/v2/components/code-input/CodeInputLite.vue.d.ts.map +1 -0
  76. package/dist/v2/components/code-input/CodeInputLite.vue.js +10 -0
  77. package/dist/v2/components/code-input/CodeInputLite.vue.js.map +1 -0
  78. package/dist/v2/components/code-input/CodeInputLite.vue.script.js +631 -0
  79. package/dist/v2/components/code-input/CodeInputLite.vue.script.js.map +1 -0
  80. package/dist/v2/components/code-input/PillTooltipHost.vue.d.ts +3 -0
  81. package/dist/v2/components/code-input/PillTooltipHost.vue.d.ts.map +1 -1
  82. package/dist/v2/components/code-input/PillTooltipHost.vue.js.map +1 -1
  83. package/dist/v2/components/code-input/PillTooltipHost.vue.script.js +23 -11
  84. package/dist/v2/components/code-input/PillTooltipHost.vue.script.js.map +1 -1
  85. package/dist/v2/components/code-input/code-variable-widget.d.ts.map +1 -1
  86. package/dist/v2/components/code-input/code-variable-widget.js +5 -2
  87. package/dist/v2/components/code-input/code-variable-widget.js.map +1 -1
  88. package/dist/v2/components/code-input/helpers/build-pill-context.d.ts +11 -0
  89. package/dist/v2/components/code-input/helpers/build-pill-context.d.ts.map +1 -0
  90. package/dist/v2/components/code-input/helpers/build-pill-context.js +28 -0
  91. package/dist/v2/components/code-input/helpers/build-pill-context.js.map +1 -0
  92. package/dist/v2/components/code-input/helpers/lookup-variable-value.d.ts +11 -0
  93. package/dist/v2/components/code-input/helpers/lookup-variable-value.d.ts.map +1 -0
  94. package/dist/v2/components/code-input/helpers/lookup-variable-value.js +18 -0
  95. package/dist/v2/components/code-input/helpers/lookup-variable-value.js.map +1 -0
  96. package/dist/v2/components/code-input/helpers/pill-signature.d.ts +13 -0
  97. package/dist/v2/components/code-input/helpers/pill-signature.d.ts.map +1 -0
  98. package/dist/v2/components/code-input/helpers/pill-signature.js +25 -0
  99. package/dist/v2/components/code-input/helpers/pill-signature.js.map +1 -0
  100. package/dist/v2/components/code-input/helpers/serialize-value.d.ts +10 -0
  101. package/dist/v2/components/code-input/helpers/serialize-value.d.ts.map +1 -0
  102. package/dist/v2/components/code-input/helpers/serialize-value.js +17 -0
  103. package/dist/v2/components/code-input/helpers/serialize-value.js.map +1 -0
  104. package/dist/v2/components/code-input/index.d.ts +1 -0
  105. package/dist/v2/components/code-input/index.d.ts.map +1 -1
  106. package/dist/v2/components/code-input/index.js +2 -1
  107. package/dist/v2/components/data-table/DataTableInput.vue.d.ts +0 -4
  108. package/dist/v2/components/data-table/DataTableInput.vue.d.ts.map +1 -1
  109. package/dist/v2/components/data-table/DataTableInput.vue.js +1 -1
  110. package/dist/v2/components/data-table/DataTableInput.vue.js.map +1 -1
  111. package/dist/v2/components/data-table/DataTableInput.vue.script.js +2 -19
  112. package/dist/v2/components/data-table/DataTableInput.vue.script.js.map +1 -1
  113. package/dist/v2/constants.js +1 -1
  114. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.d.ts +9 -0
  115. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.d.ts.map +1 -1
  116. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.js.map +1 -1
  117. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.script.js +59 -28
  118. package/dist/v2/features/environments/components/EnvironmentVariablesDropdown.vue.script.js.map +1 -1
  119. package/dist/v2/features/environments/components/EnvironmentVariablesTable.vue.d.ts.map +1 -1
  120. package/dist/v2/features/environments/components/EnvironmentVariablesTable.vue.js +1 -1
  121. package/dist/v2/features/environments/components/EnvironmentVariablesTable.vue.js.map +1 -1
  122. package/dist/v2/features/environments/components/EnvironmentVariablesTable.vue.script.js +3 -8
  123. package/dist/v2/features/environments/components/EnvironmentVariablesTable.vue.script.js.map +1 -1
  124. package/dist/v2/features/modal/Modal.vue.js.map +1 -1
  125. package/dist/v2/features/modal/Modal.vue.script.js +1 -1
  126. package/dist/v2/features/modal/Modal.vue.script.js.map +1 -1
  127. package/dist/vue-styles.css +147 -95
  128. package/package.json +11 -11
@@ -1,5 +1,5 @@
1
1
  import DataTableInputSelect_default from "./DataTableInputSelect.vue.js";
2
- import CodeInput_default from "../code-input/CodeInput.vue.js";
2
+ import CodeInputLite_default from "../code-input/CodeInputLite.vue.js";
3
3
  import DataTableCell_default from "./DataTableCell.vue.js";
4
4
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, mergeProps, normalizeClass, openBlock, ref, renderSlot, unref, useTemplateRef, withCtx } from "vue";
5
5
  import { ScalarIconEye, ScalarIconEyeSlash, ScalarIconX } from "@scalar/icons";
@@ -37,14 +37,8 @@ var DataTableInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
37
37
  default: false
38
38
  },
39
39
  enum: {},
40
- min: {},
41
- max: {},
42
40
  environment: {},
43
41
  description: {},
44
- lineWrapping: {
45
- type: Boolean,
46
- default: false
47
- },
48
42
  withFakeData: {
49
43
  type: Boolean,
50
44
  default: true
@@ -98,7 +92,7 @@ var DataTableInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
98
92
  type: inputType.value,
99
93
  value: __props.modelValue,
100
94
  onInput: _cache[1] || (_cache[1] = ($event) => emit("update:modelValue", $event.target.value ?? ""))
101
- }), null, 16, _hoisted_3)) : (openBlock(), createBlock(unref(CodeInput_default), mergeProps({ key: 1 }, _ctx.$attrs, {
95
+ }), null, 16, _hoisted_3)) : (openBlock(), createBlock(unref(CodeInputLite_default), mergeProps({ key: 1 }, _ctx.$attrs, {
102
96
  id: __props.id,
103
97
  ref_key: "codeInput",
104
98
  ref: codeInput,
@@ -107,17 +101,10 @@ var DataTableInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
107
101
  __props.description && "pr-8",
108
102
  __props.type === "password" && "scalar-password-input"
109
103
  ]],
110
- description: __props.description,
111
- disableCloseBrackets: "",
112
- disableTabIndent: "",
113
104
  environment: __props.environment,
114
- lineWrapping: Boolean(__props.lineWrapping),
115
- max: __props.max,
116
- min: __props.min,
117
105
  modelValue: __props.modelValue ?? "",
118
106
  readOnly: __props.readOnly,
119
107
  required: Boolean(__props.required),
120
- spellcheck: "false",
121
108
  type: inputType.value,
122
109
  withFakeData: __props.withFakeData,
123
110
  onBlur: handleBlur,
@@ -126,11 +113,7 @@ var DataTableInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
126
113
  }), null, 16, [
127
114
  "id",
128
115
  "class",
129
- "description",
130
116
  "environment",
131
- "lineWrapping",
132
- "max",
133
- "min",
134
117
  "modelValue",
135
118
  "readOnly",
136
119
  "required",
@@ -1 +1 @@
1
- {"version":3,"file":"DataTableInput.vue.script.js","names":["$slots","$attrs"],"sources":["../../../../src/v2/components/data-table/DataTableInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarIconEye, ScalarIconEyeSlash, ScalarIconX } from '@scalar/icons'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed, ref, useTemplateRef } from 'vue'\n\nimport type { VueClassProp } from '@/types/vue'\nimport { CodeInput } from '@/v2/components/code-input'\n\nimport DataTableCell from './DataTableCell.vue'\nimport DataTableInputSelect from './DataTableInputSelect.vue'\n\nconst props = withDefaults(\n defineProps<{\n id?: string\n type?: string | undefined\n /** Class for the wrapping cell because attrs is bound to the input */\n containerClass?: VueClassProp | undefined\n required?: boolean\n modelValue: string\n /** Allows adding a custom value to the enum dropdown, defaults to true */\n canAddCustomEnumValue?: boolean\n readOnly?: boolean\n enum?: string[]\n min?: number\n max?: number\n environment: XScalarEnvironment\n description?: string | undefined\n lineWrapping?: boolean\n /** Whether to show context function suggestions like $guid, $timestamp. Defaults to true */\n withFakeData?: boolean\n }>(),\n {\n canAddCustomEnumValue: true,\n required: false,\n readOnly: false,\n lineWrapping: false,\n withFakeData: true,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', v: string | number): void\n (e: 'inputFocus'): void\n (e: 'inputBlur'): void\n (e: 'selectVariable', value: string): void\n}>()\n\ndefineOptions({ inheritAttrs: false })\n\nconst mask = ref(true)\nconst interactingWithDropdown = ref(false)\nconst codeInput = useTemplateRef('codeInput')\n\nconst handleBlur = () => !interactingWithDropdown.value && emit('inputBlur')\n\nconst inputType = computed(() =>\n props.type === 'password' ? 'text' : (props.type ?? 'text'),\n)\n\n// If not an enum nor read only, focus the code input\nconst handleLabelClick = () => {\n if (!props.enum?.length && !props.readOnly) {\n codeInput.value?.focus()\n }\n}\n</script>\n<template>\n <DataTableCell\n class=\"relative flex\"\n :class=\"containerClass\">\n <div\n v-if=\"$slots.default\"\n class=\"text-c-1 flex items-center pr-0 pl-3\"\n :for=\"id ?? ''\"\n @click=\"handleLabelClick\">\n <slot />:\n </div>\n <div class=\"relative flex min-w-0 flex-1\">\n <template v-if=\"props.enum && props.enum.length\">\n <DataTableInputSelect\n :canAddCustomValue=\"props.canAddCustomEnumValue\"\n :modelValue=\"props.modelValue\"\n :value=\"props.enum\"\n @update:modelValue=\"emit('update:modelValue', $event)\" />\n </template>\n <template v-else>\n <input\n v-if=\"mask && type === 'password'\"\n v-bind=\"id ? { ...$attrs, id: id } : $attrs\"\n autocomplete=\"off\"\n class=\"text-c-1 disabled:text-c-2 peer w-full min-w-0 border-none px-2 py-1.25 -outline-offset-1\"\n :class=\"{ 'scalar-password-input': type === 'password' }\"\n data-1p-ignore\n :readOnly=\"readOnly\"\n spellcheck=\"false\"\n :type=\"inputType\"\n :value=\"modelValue\"\n @input=\"\n emit(\n 'update:modelValue',\n ($event.target as HTMLInputElement).value ?? '',\n )\n \" />\n <CodeInput\n v-else\n v-bind=\"$attrs\"\n :id=\"id\"\n ref=\"codeInput\"\n class=\"text-c-1 disabled:text-c-2 peer w-full min-w-0 border-none -outline-offset-1\"\n :class=\"[\n type === 'password' && description && 'pr-12',\n description && 'pr-8',\n type === 'password' && 'scalar-password-input',\n ]\"\n :description=\"description\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"environment\"\n :lineWrapping=\"Boolean(lineWrapping)\"\n :max=\"max\"\n :min=\"min\"\n :modelValue=\"modelValue ?? ''\"\n :readOnly=\"readOnly\"\n :required=\"Boolean(required)\"\n spellcheck=\"false\"\n :type=\"inputType\"\n :withFakeData=\"withFakeData\"\n @blur=\"handleBlur\"\n @focus=\"emit('inputFocus')\"\n @update:modelValue=\"(value) => emit('update:modelValue', value)\" />\n </template>\n </div>\n <div\n v-if=\"$slots.warning\"\n class=\"centered-y text-orange absolute right-7 text-xs\">\n <slot name=\"warning\" />\n </div>\n <slot name=\"icon\" />\n <!-- Clear -->\n <ScalarIconButton\n v-if=\"modelValue\"\n class=\"-ml-.25 h-6 w-6 self-center p-1.25\"\n :icon=\"ScalarIconX\"\n label=\"Clear Value\"\n @click=\"emit('update:modelValue', '')\" />\n <!-- Toggle Visibility -->\n <ScalarIconButton\n v-if=\"type === 'password'\"\n class=\"-ml-.5 mr-1.25 h-6 w-6 self-center p-1.25\"\n data-testid=\"data-table-password-toggle\"\n :icon=\"mask ? ScalarIconEye : ScalarIconEyeSlash\"\n :label=\"mask ? 'Show Password' : 'Hide Password'\"\n @click=\"mask = !mask\" />\n </DataTableCell>\n</template>\n\n<style scoped>\n:deep(.cm-editor) {\n padding: 0;\n}\n:deep(.cm-content) {\n align-items: center;\n background-color: transparent;\n display: flex;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n width: 100%;\n}\n:deep(.cm-content):has(.cm-pill) {\n padding: 5px 8px;\n}\n:deep(.cm-content .cm-pill:not(:last-of-type)) {\n margin-right: 0.5px;\n}\n:deep(.cm-content .cm-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n:deep(.cm-line) {\n overflow: hidden;\n padding: 0;\n text-overflow: ellipsis;\n word-break: break-word;\n}\n.required::after {\n content: 'Required';\n}\n/* Tailwind placeholder is busted */\ninput::placeholder {\n color: var(--scalar-color-3);\n}\n/* we want our inputs to look like a password input but not be one */\n.scalar-password-input {\n text-security: disc;\n -webkit-text-security: disc;\n -moz-text-security: disc;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYA,MAAM,QAAQ;EA6Bd,MAAM,OAAO;EASb,MAAM,OAAO,IAAI,KAAI;EACrB,MAAM,0BAA0B,IAAI,MAAK;EACzC,MAAM,YAAY,eAAe,YAAW;EAE5C,MAAM,mBAAmB,CAAC,wBAAwB,SAAS,KAAK,YAAW;EAE3E,MAAM,YAAY,eAChB,MAAM,SAAS,aAAa,SAAU,MAAM,QAAQ,OACtD;EAGA,MAAM,yBAAyB;AAC7B,OAAI,CAAC,MAAM,MAAM,UAAU,CAAC,MAAM,SAChC,WAAU,OAAO,OAAM;;;uBAKzB,YAsFgB,uBAAA,EArFd,OAAK,eAAA,CAAC,iBACE,QAAA,eAAc,CAAA,EAAA,EAAA;2BAOhB;KALEA,KAAAA,OAAO,WAAA,WAAA,EADf,mBAMM,OAAA;;MAJJ,OAAM;MACL,KAAK,QAAA,MAAE;MACP,SAAO;SACR,WAAQ,KAAA,QAAA,WAAA,EAAA,EAAA,KAAA,GAAA,KAAA,EAAA,OAAA,OAAA,OAAA,KAAA,gBAAA,MACV,GAAA,EAAA,EAAA,GAAA,WAAA,IAAA,mBAAA,IAAA,KAAA;KACA,mBAsDM,OAtDN,YAsDM,CArDY,MAAM,QAAQ,MAAM,KAAK,UAAA,WAAA,EACvC,YAI2D,8BAAA;;MAHxD,mBAAmB,MAAM;MACzB,YAAY,MAAM;MAClB,OAAO,MAAM;MACb,uBAAiB,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,qBAAsB,OAAM;;;;;yBAExD,mBA6CW,UAAA,EAAA,KAAA,GAAA,EAAA,CA3CD,KAAA,SAAQ,QAAA,SAAI,cAAA,WAAA,EADpB,mBAgBM,SAhBN,WAgBM,EAAA,KAAA,GAAA,EAdI,QAAA,KAAE;MAAA,GAAQC,KAAAA;MAAM,IAAM,QAAA;MAAE,GAAKA,KAAAA,QAAM;MAC3C,cAAa;MACb,OAAK,CAAC,6FAA2F,EAAA,yBAC9D,QAAA,SAAI,YAAA,CAAA;MACvC,kBAAA;MACC,UAAU,QAAA;MACX,YAAW;MACV,MAAM,UAAA;MACN,OAAO,QAAA;MACP,SAAK,OAAA,OAAA,OAAA,MAAA,WAAe,KAAA,qBAAwD,OAAO,OAA4B,SAAK,GAAA;gDAMvH,YA0BqE,MAAA,kBAAA,EA1BrE,WA0BqE,EAAA,KAAA,GAAA,EAxB3DA,KAAAA,QAAM;MACb,IAAI,QAAA;eACD;MAAJ,KAAI;MACJ,OAAK,CAAC,gFAA8E;OAC9D,QAAA,SAAI,cAAmB,QAAA,eAAW;OAAyB,QAAA,eAAW;OAAwB,QAAA,SAAI,cAAA;;MAKvH,aAAa,QAAA;MACd,sBAAA;MACA,kBAAA;MACC,aAAa,QAAA;MACb,cAAc,QAAQ,QAAA,aAAY;MAClC,KAAK,QAAA;MACL,KAAK,QAAA;MACL,YAAY,QAAA,cAAU;MACtB,UAAU,QAAA;MACV,UAAU,QAAQ,QAAA,SAAQ;MAC3B,YAAW;MACV,MAAM,UAAA;MACN,cAAc,QAAA;MACd,QAAM;MACN,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,aAAA;MACX,uBAAiB,OAAA,OAAA,OAAA,MAAG,UAAU,KAAI,qBAAsB,MAAK;;;;;;;;;;;;;;;KAI5DD,KAAAA,OAAO,WAAA,WAAA,EADf,mBAIM,OAJN,YAIM,CADJ,WAAuB,KAAA,QAAA,WAAA,EAAA,EAAA,KAAA,GAAA,KAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA;KAEzB,WAAoB,KAAA,QAAA,QAAA,EAAA,EAAA,KAAA,GAAA,KAAA;KAGZ,QAAA,cAAA,WAAA,EADR,YAK2C,MAAA,iBAAA,EAAA;;MAHzC,OAAM;MACL,MAAM,MAAA,YAAW;MAClB,OAAM;MACL,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,qBAAA,GAAA;;KAGN,QAAA,SAAI,cAAA,WAAA,EADZ,YAM0B,MAAA,iBAAA,EAAA;;MAJxB,OAAM;MACN,eAAY;MACX,MAAM,KAAA,QAAO,MAAA,cAAa,GAAG,MAAA,mBAAkB;MAC/C,OAAO,KAAA,QAAI,kBAAA;MACX,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAA,QAAI,CAAI,KAAA"}
1
+ {"version":3,"file":"DataTableInput.vue.script.js","names":["$slots","$attrs"],"sources":["../../../../src/v2/components/data-table/DataTableInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarIconButton } from '@scalar/components/icon-button'\nimport { ScalarIconEye, ScalarIconEyeSlash, ScalarIconX } from '@scalar/icons'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed, ref, useTemplateRef } from 'vue'\n\nimport type { VueClassProp } from '@/types/vue'\nimport { CodeInputLite } from '@/v2/components/code-input'\n\nimport DataTableCell from './DataTableCell.vue'\nimport DataTableInputSelect from './DataTableInputSelect.vue'\n\nconst props = withDefaults(\n defineProps<{\n id?: string\n type?: string | undefined\n /** Class for the wrapping cell because attrs is bound to the input */\n containerClass?: VueClassProp | undefined\n required?: boolean\n modelValue: string\n /** Allows adding a custom value to the enum dropdown, defaults to true */\n canAddCustomEnumValue?: boolean\n readOnly?: boolean\n enum?: string[]\n environment: XScalarEnvironment\n description?: string | undefined\n /** Whether to show context function suggestions like $guid, $timestamp. Defaults to true */\n withFakeData?: boolean\n }>(),\n {\n canAddCustomEnumValue: true,\n required: false,\n readOnly: false,\n withFakeData: true,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', v: string | number): void\n (e: 'inputFocus'): void\n (e: 'inputBlur'): void\n (e: 'selectVariable', value: string): void\n}>()\n\ndefineOptions({ inheritAttrs: false })\n\nconst mask = ref(true)\nconst interactingWithDropdown = ref(false)\nconst codeInput = useTemplateRef('codeInput')\n\nconst handleBlur = () => !interactingWithDropdown.value && emit('inputBlur')\n\nconst inputType = computed(() =>\n props.type === 'password' ? 'text' : (props.type ?? 'text'),\n)\n\n// If not an enum nor read only, focus the code input\nconst handleLabelClick = () => {\n if (!props.enum?.length && !props.readOnly) {\n codeInput.value?.focus()\n }\n}\n</script>\n<template>\n <DataTableCell\n class=\"relative flex\"\n :class=\"containerClass\">\n <div\n v-if=\"$slots.default\"\n class=\"text-c-1 flex items-center pr-0 pl-3\"\n :for=\"id ?? ''\"\n @click=\"handleLabelClick\">\n <slot />:\n </div>\n <div class=\"relative flex min-w-0 flex-1\">\n <template v-if=\"props.enum && props.enum.length\">\n <DataTableInputSelect\n :canAddCustomValue=\"props.canAddCustomEnumValue\"\n :modelValue=\"props.modelValue\"\n :value=\"props.enum\"\n @update:modelValue=\"emit('update:modelValue', $event)\" />\n </template>\n <template v-else>\n <input\n v-if=\"mask && type === 'password'\"\n v-bind=\"id ? { ...$attrs, id: id } : $attrs\"\n autocomplete=\"off\"\n class=\"text-c-1 disabled:text-c-2 peer w-full min-w-0 border-none px-2 py-1.25 -outline-offset-1\"\n :class=\"{ 'scalar-password-input': type === 'password' }\"\n data-1p-ignore\n :readOnly=\"readOnly\"\n spellcheck=\"false\"\n :type=\"inputType\"\n :value=\"modelValue\"\n @input=\"\n emit(\n 'update:modelValue',\n ($event.target as HTMLInputElement).value ?? '',\n )\n \" />\n <CodeInputLite\n v-else\n v-bind=\"$attrs\"\n :id=\"id\"\n ref=\"codeInput\"\n class=\"text-c-1 disabled:text-c-2 peer w-full min-w-0 border-none -outline-offset-1\"\n :class=\"[\n type === 'password' && description && 'pr-12',\n description && 'pr-8',\n type === 'password' && 'scalar-password-input',\n ]\"\n :environment=\"environment\"\n :modelValue=\"modelValue ?? ''\"\n :readOnly=\"readOnly\"\n :required=\"Boolean(required)\"\n :type=\"inputType\"\n :withFakeData=\"withFakeData\"\n @blur=\"handleBlur\"\n @focus=\"emit('inputFocus')\"\n @update:modelValue=\"(value) => emit('update:modelValue', value)\" />\n </template>\n </div>\n <div\n v-if=\"$slots.warning\"\n class=\"centered-y text-orange absolute right-7 text-xs\">\n <slot name=\"warning\" />\n </div>\n <slot name=\"icon\" />\n <!-- Clear -->\n <ScalarIconButton\n v-if=\"modelValue\"\n class=\"-ml-.25 h-6 w-6 self-center p-1.25\"\n :icon=\"ScalarIconX\"\n label=\"Clear Value\"\n @click=\"emit('update:modelValue', '')\" />\n <!-- Toggle Visibility -->\n <ScalarIconButton\n v-if=\"type === 'password'\"\n class=\"-ml-.5 mr-1.25 h-6 w-6 self-center p-1.25\"\n data-testid=\"data-table-password-toggle\"\n :icon=\"mask ? ScalarIconEye : ScalarIconEyeSlash\"\n :label=\"mask ? 'Show Password' : 'Hide Password'\"\n @click=\"mask = !mask\" />\n </DataTableCell>\n</template>\n\n<style scoped>\n:deep(.code-input-lite__editor) {\n background-color: transparent;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n}\n:deep(.scalar-pill:not(:last-of-type)) {\n margin-right: 0.15em;\n}\n:deep(.scalar-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n.required::after {\n content: 'Required';\n}\n/* Tailwind placeholder is busted */\ninput::placeholder {\n color: var(--scalar-color-3);\n}\n/* we want our inputs to look like a password input but not be one */\n.scalar-password-input {\n text-security: disc;\n -webkit-text-security: disc;\n -moz-text-security: disc;\n}\n</style>\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  //#region src/v2/constants.ts
2
2
  /** The version number taken from the package.json. Consumers can override at build time via define (e.g. OVERRIDE_PACKAGE_VERSION: JSON.stringify('1.2.3')). */
3
- var APP_VERSION = typeof OVERRIDE_PACKAGE_VERSION !== "undefined" ? OVERRIDE_PACKAGE_VERSION : "3.10.3";
3
+ var APP_VERSION = typeof OVERRIDE_PACKAGE_VERSION !== "undefined" ? OVERRIDE_PACKAGE_VERSION : "3.11.0";
4
4
  //#endregion
5
5
  export { APP_VERSION };
6
6
 
@@ -11,15 +11,24 @@ type __VLS_Props = {
11
11
  key: string;
12
12
  description: string;
13
13
  }[];
14
+ /**
15
+ * Id for the `role="listbox"` element. When set, each option also receives a
16
+ * stable id so the owning combobox input can reference the active option via
17
+ * `aria-activedescendant` (W3C combobox pattern).
18
+ */
19
+ listboxId?: string;
14
20
  };
15
21
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
16
22
  handleArrowKey: (direction: "up" | "down") => void;
17
23
  handleSelect: () => void;
24
+ activeOptionId: import("vue").ComputedRef<string | undefined>;
18
25
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
19
26
  select: (variable: string) => any;
27
+ close: () => any;
20
28
  redirect: () => any;
21
29
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
22
30
  onSelect?: ((variable: string) => any) | undefined;
31
+ onClose?: (() => any) | undefined;
23
32
  onRedirect?: (() => any) | undefined;
24
33
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
34
  declare const _default: typeof __VLS_export;
@@ -1 +1 @@
1
- {"version":3,"file":"EnvironmentVariablesDropdown.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"names":[],"mappings":"AA+PA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AASnH,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,gBAAgB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD,iFAAiF;IACjF,oBAAoB,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAC9D,CAAC;AAqYF,QAAA,MAAM,YAAY;gCAnQiB,IAAI,GAAG,MAAM;;;;;;;;kFAuQ9C,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"EnvironmentVariablesDropdown.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"names":[],"mappings":"AAmTA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AASnH,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,gBAAgB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD,iFAAiF;IACjF,oBAAoB,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC7D;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAC;AA8aF,QAAA,MAAM,YAAY;gCA1QiB,IAAI,GAAG,MAAM;;;;;;;;;;;kFA8Q9C,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1 +1 @@
1
- {"version":3,"file":"EnvironmentVariablesDropdown.vue.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarTeleport } from '@scalar/components/teleport'\nimport { ScalarIconPlus } from '@scalar/icons'\nimport { POPULAR_CONTEXT_FUNCTION_KEYS } from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { onClickOutside } from '@vueuse/core'\nimport Fuse from 'fuse.js'\nimport { computed, onMounted, ref, type CSSProperties } from 'vue'\n\ntype DropdownRow =\n | { kind: 'env'; key: string; secondary: string }\n | { kind: 'context'; key: string; secondary: string }\n\nconst {\n query,\n environment,\n dropdownPosition,\n contextFunctionItems = [],\n} = defineProps<{\n query: string\n environment?: XScalarEnvironment\n dropdownPosition?: { left: number; top: number }\n /** Runtime placeholders such as `{{$guid}}`, shown with environment variables */\n contextFunctionItems?: { key: string; description: string }[]\n}>()\n\nconst emit = defineEmits<{\n (e: 'select', variable: string): void\n (e: 'redirect'): void\n}>()\n\nconst isOpen = ref(true)\nconst dropdownRef = ref<HTMLElement | null>(null)\nconst selectedVariableIndex = ref(0)\n\nconst redirectToEnvironment = () => {\n emit('redirect')\n isOpen.value = false\n}\n\n/** Normalize the variables to have a name and value */\nconst normalizedVariables = computed(() =>\n (environment?.variables ?? []).map((v) => ({\n key: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n })),\n)\n\nconst contextRows = computed((): DropdownRow[] =>\n contextFunctionItems.map((item) => ({\n kind: 'context',\n key: item.key,\n secondary: item.description,\n })),\n)\n\nconst envRows = computed((): DropdownRow[] =>\n normalizedVariables.value\n .filter(({ key, value }) => key !== '' || value !== '')\n .map(({ key, value }) => ({\n kind: 'env' as const,\n key,\n secondary: value,\n })),\n)\n\ntype FuseRow = DropdownRow & { fuseText: string }\n\nconst envFuseSource = computed((): FuseRow[] =>\n envRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst contextFuseSource = computed((): FuseRow[] =>\n contextRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst fuseEnv = computed(\n () =>\n new Fuse(envFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst fuseContext = computed(\n () =>\n new Fuse(contextFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst popularContextRows = computed((): DropdownRow[] => {\n const byKey = new Map(contextFunctionItems.map((c) => [c.key, c]))\n return POPULAR_CONTEXT_FUNCTION_KEYS.flatMap((key) => {\n const item = byKey.get(key)\n return item\n ? [\n {\n kind: 'context' as const,\n key: item.key,\n secondary: item.description,\n },\n ]\n : []\n })\n})\n\nconst DROPDOWN_LIMIT = 12\n\nconst filteredVariables = computed((): DropdownRow[] => {\n if (!query.trim()) {\n const envSlice = envRows.value.slice(-4)\n return [...envSlice, ...popularContextRows.value]\n }\n\n const q = query.trim()\n const envMatches = fuseEnv.value\n .search(q, { limit: DROPDOWN_LIMIT })\n .map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n\n const remaining = DROPDOWN_LIMIT - envMatches.length\n const contextMatches =\n remaining > 0\n ? fuseContext.value.search(q, { limit: remaining }).map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n : []\n\n return [...envMatches, ...contextMatches]\n})\n\nconst selectVariable = (variableKey: string): void => {\n emit('select', variableKey)\n}\n\nconst handleArrowKey = (direction: 'up' | 'down') => {\n const offset = direction === 'up' ? -1 : 1\n const length = filteredVariables.value.length\n\n if (length === 0) {\n return\n }\n\n selectedVariableIndex.value =\n (selectedVariableIndex.value + offset + length) % length\n}\n\nconst handleSelect = () => {\n if (selectedVariableIndex.value >= 0) {\n const selectedVariable =\n filteredVariables.value[selectedVariableIndex.value]\n if (selectedVariable) {\n selectVariable(selectedVariable.key)\n }\n }\n}\n\ndefineExpose({\n handleArrowKey,\n handleSelect,\n})\n\nonMounted(() => {\n // Reset selected index to the first item when dropdown opens\n selectedVariableIndex.value = 0\n})\n\nconst dropdownStyle = computed<CSSProperties>(() => {\n return {\n left: (dropdownPosition?.left ?? 0) + 'px',\n // Add a 5px offset from the editor\n top: (dropdownPosition?.top ?? 0) + 5 + 'px',\n }\n})\n\nonClickOutside(\n dropdownRef,\n () => {\n isOpen.value = false\n },\n { ignore: [dropdownRef] },\n)\n</script>\n<template>\n <ScalarTeleport\n v-if=\"isOpen\"\n class=\"scalar-client\">\n <div\n ref=\"dropdownRef\"\n class=\"custom-scroll z-context fixed top-0 left-0 flex max-h-[60svh] w-56 flex-col rounded border p-0.75\"\n :style=\"dropdownStyle\">\n <ul\n v-if=\"filteredVariables.length\"\n class=\"gap-1/2 flex flex-col\">\n <template\n v-for=\"(item, index) in filteredVariables\"\n :key=\"`${item.kind}-${item.key}`\">\n <li\n class=\"font-code text-xxs hover:bg-b-2 flex h-8 cursor-pointer items-center justify-between gap-1.5 rounded p-1.5 transition-colors duration-150\"\n :class=\"{ 'bg-b-2': index === selectedVariableIndex }\"\n @click=\"selectVariable(item.key)\">\n <div class=\"flex items-center gap-2 whitespace-nowrap\">\n <span\n v-if=\"item.kind === 'env'\"\n class=\"h-2.25 w-2.25 min-w-2.25 rounded-full\"\n :style=\"{\n backgroundColor: environment?.color,\n }\" />\n <span\n v-else\n class=\"text-c-3 bg-b-3 flex h-4.5 min-w-4.5 items-center justify-center rounded px-0.5 font-sans text-[9px] font-semibold\">\n fn\n </span>\n {{ item.key }}\n </div>\n <span\n class=\"max-w-[9rem] overflow-hidden text-right text-ellipsis whitespace-nowrap\">\n {{ item.secondary }}\n </span>\n </li>\n </template>\n </ul>\n <ScalarButton\n v-else\n class=\"font-code text-xxs bg-b-inherit hover:bg-b-2 flex h-8 w-full justify-start gap-2 px-1.5 transition-colors duration-150\"\n variant=\"outlined\"\n @click=\"redirectToEnvironment\">\n <ScalarIconPlus class=\"size-3\" />\n Add Variable\n </ScalarButton>\n <!-- Backdrop for the dropdown -->\n <div\n class=\"bg-b-1 brightness-lifted absolute inset-0 -z-1 rounded shadow-lg\" />\n </div>\n </ScalarTeleport>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"EnvironmentVariablesDropdown.vue.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarTeleport } from '@scalar/components/teleport'\nimport { ScalarIconPlus } from '@scalar/icons'\nimport { POPULAR_CONTEXT_FUNCTION_KEYS } from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { onClickOutside } from '@vueuse/core'\nimport Fuse from 'fuse.js'\nimport { computed, onMounted, ref, watch, type CSSProperties } from 'vue'\n\ntype DropdownRow =\n | { kind: 'env'; key: string; secondary: string }\n | { kind: 'context'; key: string; secondary: string }\n\nconst {\n query,\n environment,\n dropdownPosition,\n contextFunctionItems = [],\n listboxId,\n} = defineProps<{\n query: string\n environment?: XScalarEnvironment\n dropdownPosition?: { left: number; top: number }\n /** Runtime placeholders such as `{{$guid}}`, shown with environment variables */\n contextFunctionItems?: { key: string; description: string }[]\n /**\n * Id for the `role=\"listbox\"` element. When set, each option also receives a\n * stable id so the owning combobox input can reference the active option via\n * `aria-activedescendant` (W3C combobox pattern).\n */\n listboxId?: string\n}>()\n\nconst emit = defineEmits<{\n (e: 'select', variable: string): void\n (e: 'redirect'): void\n /**\n * Fired when the user dismisses the panel by clicking outside. The owning\n * combobox needs this to clear its `aria-expanded`/`aria-controls` state,\n * which would otherwise keep pointing at a listbox that is no longer mounted.\n */\n (e: 'close'): void\n}>()\n\nconst isOpen = ref(true)\nconst dropdownRef = ref<HTMLElement | null>(null)\nconst selectedVariableIndex = ref(0)\n\nconst redirectToEnvironment = () => {\n emit('redirect')\n isOpen.value = false\n // The panel is gone, so tell the combobox to drop its aria-expanded /\n // aria-controls — otherwise they keep pointing at a dismissed listbox.\n emit('close')\n}\n\n/** Normalize the variables to have a name and value */\nconst normalizedVariables = computed(() =>\n (environment?.variables ?? []).map((v) => ({\n key: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n })),\n)\n\nconst contextRows = computed((): DropdownRow[] =>\n contextFunctionItems.map((item) => ({\n kind: 'context',\n key: item.key,\n secondary: item.description,\n })),\n)\n\nconst envRows = computed((): DropdownRow[] =>\n normalizedVariables.value\n .filter(({ key, value }) => key !== '' || value !== '')\n .map(({ key, value }) => ({\n kind: 'env' as const,\n key,\n secondary: value,\n })),\n)\n\ntype FuseRow = DropdownRow & { fuseText: string }\n\nconst envFuseSource = computed((): FuseRow[] =>\n envRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst contextFuseSource = computed((): FuseRow[] =>\n contextRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst fuseEnv = computed(\n () =>\n new Fuse(envFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst fuseContext = computed(\n () =>\n new Fuse(contextFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst popularContextRows = computed((): DropdownRow[] => {\n const byKey = new Map(contextFunctionItems.map((c) => [c.key, c]))\n return POPULAR_CONTEXT_FUNCTION_KEYS.flatMap((key) => {\n const item = byKey.get(key)\n return item\n ? [\n {\n kind: 'context' as const,\n key: item.key,\n secondary: item.description,\n },\n ]\n : []\n })\n})\n\nconst DROPDOWN_LIMIT = 12\n\nconst filteredVariables = computed((): DropdownRow[] => {\n if (!query.trim()) {\n const envSlice = envRows.value.slice(-4)\n return [...envSlice, ...popularContextRows.value]\n }\n\n const q = query.trim()\n const envMatches = fuseEnv.value\n .search(q, { limit: DROPDOWN_LIMIT })\n .map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n\n const remaining = DROPDOWN_LIMIT - envMatches.length\n const contextMatches =\n remaining > 0\n ? fuseContext.value.search(q, { limit: remaining }).map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n : []\n\n return [...envMatches, ...contextMatches]\n})\n\nconst optionId = (index: number): string | undefined =>\n listboxId ? `${listboxId}-option-${index}` : undefined\n\n/**\n * Id of the currently highlighted option, for the combobox's\n * `aria-activedescendant`. Undefined when there is no list to point at.\n */\nconst activeOptionId = computed((): string | undefined =>\n filteredVariables.value.length\n ? optionId(selectedVariableIndex.value)\n : undefined,\n)\n\nconst selectVariable = (variableKey: string): void => {\n emit('select', variableKey)\n}\n\n// Narrowing the query shrinks the list; keep the highlight in range so both the\n// visible selection and `aria-activedescendant` never reference a dropped option.\nwatch(\n () => filteredVariables.value.length,\n (length) => {\n if (selectedVariableIndex.value > length - 1) {\n selectedVariableIndex.value = Math.max(0, length - 1)\n }\n },\n)\n\nconst handleArrowKey = (direction: 'up' | 'down') => {\n const offset = direction === 'up' ? -1 : 1\n const length = filteredVariables.value.length\n\n if (length === 0) {\n return\n }\n\n selectedVariableIndex.value =\n (selectedVariableIndex.value + offset + length) % length\n}\n\nconst handleSelect = () => {\n if (selectedVariableIndex.value >= 0) {\n const selectedVariable =\n filteredVariables.value[selectedVariableIndex.value]\n if (selectedVariable) {\n selectVariable(selectedVariable.key)\n }\n }\n}\n\ndefineExpose({\n handleArrowKey,\n handleSelect,\n activeOptionId,\n})\n\nonMounted(() => {\n // Reset selected index to the first item when dropdown opens\n selectedVariableIndex.value = 0\n})\n\nconst dropdownStyle = computed<CSSProperties>(() => {\n return {\n left: (dropdownPosition?.left ?? 0) + 'px',\n // Add a 5px offset from the editor\n top: (dropdownPosition?.top ?? 0) + 5 + 'px',\n }\n})\n\nonClickOutside(\n dropdownRef,\n () => {\n isOpen.value = false\n emit('close')\n },\n { ignore: [dropdownRef] },\n)\n</script>\n<template>\n <ScalarTeleport\n v-if=\"isOpen\"\n class=\"scalar-client\">\n <div\n ref=\"dropdownRef\"\n class=\"custom-scroll z-context fixed top-0 left-0 flex max-h-[60svh] w-56 flex-col rounded border p-0.75\"\n :style=\"dropdownStyle\"\n @mousedown.prevent>\n <!--\n Always rendered (even with no matches) so the combobox's `aria-controls`\n always resolves to a real listbox; an empty list simply has no options.\n -->\n <ul\n :id=\"listboxId\"\n aria-label=\"Variable suggestions\"\n class=\"gap-1/2 flex flex-col\"\n role=\"listbox\">\n <template\n v-for=\"(item, index) in filteredVariables\"\n :key=\"`${item.kind}-${item.key}`\">\n <li\n :id=\"optionId(index)\"\n :aria-selected=\"index === selectedVariableIndex\"\n class=\"font-code text-xxs hover:bg-b-3 flex h-8 cursor-pointer items-center justify-between gap-1.5 rounded p-1.5 transition-colors duration-150\"\n :class=\"{ 'bg-b-3': index === selectedVariableIndex }\"\n role=\"option\"\n @click=\"selectVariable(item.key)\">\n <div class=\"flex items-center gap-2 whitespace-nowrap\">\n <span\n v-if=\"item.kind === 'env'\"\n class=\"h-2.25 w-2.25 min-w-2.25 rounded-full\"\n :style=\"{\n backgroundColor: environment?.color,\n }\" />\n <span\n v-else\n class=\"text-c-3 bg-b-3 flex h-4.5 min-w-4.5 items-center justify-center rounded px-0.5 font-sans text-[9px] font-semibold\">\n fn\n </span>\n {{ item.key }}\n </div>\n <span\n class=\"max-w-[9rem] overflow-hidden text-right text-ellipsis whitespace-nowrap\">\n {{ item.secondary }}\n </span>\n </li>\n </template>\n </ul>\n <ScalarButton\n v-if=\"!filteredVariables.length\"\n class=\"font-code text-xxs bg-b-inherit hover:bg-b-3 flex h-8 w-full justify-start gap-2 px-1.5 transition-colors duration-150\"\n variant=\"outlined\"\n @click=\"redirectToEnvironment\">\n <ScalarIconPlus class=\"size-3\" />\n Add Variable\n </ScalarButton>\n <!-- Backdrop for the dropdown -->\n <div\n class=\"bg-b-1 brightness-lifted absolute inset-0 -z-1 rounded shadow-lg\" />\n </div>\n </ScalarTeleport>\n</template>\n"],"mappings":""}
@@ -1,4 +1,4 @@
1
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, onMounted, openBlock, ref, renderList, toDisplayString, unref, withCtx } from "vue";
1
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, onMounted, openBlock, ref, renderList, toDisplayString, unref, watch, withCtx, withModifiers } from "vue";
2
2
  import { ScalarButton } from "@scalar/components/button";
3
3
  import { ScalarIconPlus } from "@scalar/icons";
4
4
  import { POPULAR_CONTEXT_FUNCTION_KEYS } from "@scalar/workspace-store/request-example";
@@ -6,11 +6,12 @@ import { ScalarTeleport } from "@scalar/components/teleport";
6
6
  import { onClickOutside } from "@vueuse/core";
7
7
  import Fuse from "fuse.js";
8
8
  //#region src/v2/features/environments/components/EnvironmentVariablesDropdown.vue?vue&type=script&setup=true&lang.ts
9
- var _hoisted_1 = {
10
- key: 0,
11
- class: "gap-1/2 flex flex-col"
12
- };
13
- var _hoisted_2 = ["onClick"];
9
+ var _hoisted_1 = ["id"];
10
+ var _hoisted_2 = [
11
+ "id",
12
+ "aria-selected",
13
+ "onClick"
14
+ ];
14
15
  var _hoisted_3 = { class: "flex items-center gap-2 whitespace-nowrap" };
15
16
  var _hoisted_4 = {
16
17
  key: 1,
@@ -24,9 +25,14 @@ var EnvironmentVariablesDropdown_vue_vue_type_script_setup_true_lang_default = /
24
25
  query: {},
25
26
  environment: {},
26
27
  dropdownPosition: {},
27
- contextFunctionItems: { default: () => [] }
28
+ contextFunctionItems: { default: () => [] },
29
+ listboxId: {}
28
30
  },
29
- emits: ["select", "redirect"],
31
+ emits: [
32
+ "select",
33
+ "redirect",
34
+ "close"
35
+ ],
30
36
  setup(__props, { expose: __expose, emit: __emit }) {
31
37
  const emit = __emit;
32
38
  const isOpen = ref(true);
@@ -35,6 +41,7 @@ var EnvironmentVariablesDropdown_vue_vue_type_script_setup_true_lang_default = /
35
41
  const redirectToEnvironment = () => {
36
42
  emit("redirect");
37
43
  isOpen.value = false;
44
+ emit("close");
38
45
  };
39
46
  /** Normalize the variables to have a name and value */
40
47
  const normalizedVariables = computed(() => (__props.environment?.variables ?? []).map((v) => ({
@@ -100,9 +107,18 @@ var EnvironmentVariablesDropdown_vue_vue_type_script_setup_true_lang_default = /
100
107
  }) : [];
101
108
  return [...envMatches, ...contextMatches];
102
109
  });
110
+ const optionId = (index) => __props.listboxId ? `${__props.listboxId}-option-${index}` : void 0;
111
+ /**
112
+ * Id of the currently highlighted option, for the combobox's
113
+ * `aria-activedescendant`. Undefined when there is no list to point at.
114
+ */
115
+ const activeOptionId = computed(() => filteredVariables.value.length ? optionId(selectedVariableIndex.value) : void 0);
103
116
  const selectVariable = (variableKey) => {
104
117
  emit("select", variableKey);
105
118
  };
119
+ watch(() => filteredVariables.value.length, (length) => {
120
+ if (selectedVariableIndex.value > length - 1) selectedVariableIndex.value = Math.max(0, length - 1);
121
+ });
106
122
  const handleArrowKey = (direction) => {
107
123
  const offset = direction === "up" ? -1 : 1;
108
124
  const length = filteredVariables.value.length;
@@ -117,7 +133,8 @@ var EnvironmentVariablesDropdown_vue_vue_type_script_setup_true_lang_default = /
117
133
  };
118
134
  __expose({
119
135
  handleArrowKey,
120
- handleSelect
136
+ handleSelect,
137
+ activeOptionId
121
138
  });
122
139
  onMounted(() => {
123
140
  selectedVariableIndex.value = 0;
@@ -130,6 +147,7 @@ var EnvironmentVariablesDropdown_vue_vue_type_script_setup_true_lang_default = /
130
147
  });
131
148
  onClickOutside(dropdownRef, () => {
132
149
  isOpen.value = false;
150
+ emit("close");
133
151
  }, { ignore: [dropdownRef] });
134
152
  return (_ctx, _cache) => {
135
153
  return isOpen.value ? (openBlock(), createBlock(unref(ScalarTeleport), {
@@ -140,26 +158,39 @@ var EnvironmentVariablesDropdown_vue_vue_type_script_setup_true_lang_default = /
140
158
  ref_key: "dropdownRef",
141
159
  ref: dropdownRef,
142
160
  class: "custom-scroll z-context fixed top-0 left-0 flex max-h-[60svh] w-56 flex-col rounded border p-0.75",
143
- style: normalizeStyle(dropdownStyle.value)
144
- }, [filteredVariables.value.length ? (openBlock(), createElementBlock("ul", _hoisted_1, [(openBlock(true), createElementBlock(Fragment, null, renderList(filteredVariables.value, (item, index) => {
145
- return openBlock(), createElementBlock("li", {
146
- key: `${item.kind}-${item.key}`,
147
- class: normalizeClass(["font-code text-xxs hover:bg-b-2 flex h-8 cursor-pointer items-center justify-between gap-1.5 rounded p-1.5 transition-colors duration-150", { "bg-b-2": index === selectedVariableIndex.value }]),
148
- onClick: ($event) => selectVariable(item.key)
149
- }, [createElementVNode("div", _hoisted_3, [item.kind === "env" ? (openBlock(), createElementBlock("span", {
161
+ style: normalizeStyle(dropdownStyle.value),
162
+ onMousedown: _cache[0] || (_cache[0] = withModifiers(() => {}, ["prevent"]))
163
+ }, [
164
+ createElementVNode("ul", {
165
+ id: __props.listboxId,
166
+ "aria-label": "Variable suggestions",
167
+ class: "gap-1/2 flex flex-col",
168
+ role: "listbox"
169
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(filteredVariables.value, (item, index) => {
170
+ return openBlock(), createElementBlock("li", {
171
+ key: `${item.kind}-${item.key}`,
172
+ id: optionId(index),
173
+ "aria-selected": index === selectedVariableIndex.value,
174
+ class: normalizeClass(["font-code text-xxs hover:bg-b-3 flex h-8 cursor-pointer items-center justify-between gap-1.5 rounded p-1.5 transition-colors duration-150", { "bg-b-3": index === selectedVariableIndex.value }]),
175
+ role: "option",
176
+ onClick: ($event) => selectVariable(item.key)
177
+ }, [createElementVNode("div", _hoisted_3, [item.kind === "env" ? (openBlock(), createElementBlock("span", {
178
+ key: 0,
179
+ class: "h-2.25 w-2.25 min-w-2.25 rounded-full",
180
+ style: normalizeStyle({ backgroundColor: __props.environment?.color })
181
+ }, null, 4)) : (openBlock(), createElementBlock("span", _hoisted_4, " fn ")), createTextVNode(" " + toDisplayString(item.key), 1)]), createElementVNode("span", _hoisted_5, toDisplayString(item.secondary), 1)], 10, _hoisted_2);
182
+ }), 128))], 8, _hoisted_1),
183
+ !filteredVariables.value.length ? (openBlock(), createBlock(unref(ScalarButton), {
150
184
  key: 0,
151
- class: "h-2.25 w-2.25 min-w-2.25 rounded-full",
152
- style: normalizeStyle({ backgroundColor: __props.environment?.color })
153
- }, null, 4)) : (openBlock(), createElementBlock("span", _hoisted_4, " fn ")), createTextVNode(" " + toDisplayString(item.key), 1)]), createElementVNode("span", _hoisted_5, toDisplayString(item.secondary), 1)], 10, _hoisted_2);
154
- }), 128))])) : (openBlock(), createBlock(unref(ScalarButton), {
155
- key: 1,
156
- class: "font-code text-xxs bg-b-inherit hover:bg-b-2 flex h-8 w-full justify-start gap-2 px-1.5 transition-colors duration-150",
157
- variant: "outlined",
158
- onClick: redirectToEnvironment
159
- }, {
160
- default: withCtx(() => [createVNode(unref(ScalarIconPlus), { class: "size-3" }), _cache[0] || (_cache[0] = createTextVNode(" Add Variable ", -1))]),
161
- _: 1
162
- })), _cache[1] || (_cache[1] = createElementVNode("div", { class: "bg-b-1 brightness-lifted absolute inset-0 -z-1 rounded shadow-lg" }, null, -1))], 4)]),
185
+ class: "font-code text-xxs bg-b-inherit hover:bg-b-3 flex h-8 w-full justify-start gap-2 px-1.5 transition-colors duration-150",
186
+ variant: "outlined",
187
+ onClick: redirectToEnvironment
188
+ }, {
189
+ default: withCtx(() => [createVNode(unref(ScalarIconPlus), { class: "size-3" }), _cache[1] || (_cache[1] = createTextVNode(" Add Variable ", -1))]),
190
+ _: 1
191
+ })) : createCommentVNode("", true),
192
+ _cache[2] || (_cache[2] = createElementVNode("div", { class: "bg-b-1 brightness-lifted absolute inset-0 -z-1 rounded shadow-lg" }, null, -1))
193
+ ], 36)]),
163
194
  _: 1
164
195
  })) : createCommentVNode("", true);
165
196
  };
@@ -1 +1 @@
1
- {"version":3,"file":"EnvironmentVariablesDropdown.vue.script.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarTeleport } from '@scalar/components/teleport'\nimport { ScalarIconPlus } from '@scalar/icons'\nimport { POPULAR_CONTEXT_FUNCTION_KEYS } from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { onClickOutside } from '@vueuse/core'\nimport Fuse from 'fuse.js'\nimport { computed, onMounted, ref, type CSSProperties } from 'vue'\n\ntype DropdownRow =\n | { kind: 'env'; key: string; secondary: string }\n | { kind: 'context'; key: string; secondary: string }\n\nconst {\n query,\n environment,\n dropdownPosition,\n contextFunctionItems = [],\n} = defineProps<{\n query: string\n environment?: XScalarEnvironment\n dropdownPosition?: { left: number; top: number }\n /** Runtime placeholders such as `{{$guid}}`, shown with environment variables */\n contextFunctionItems?: { key: string; description: string }[]\n}>()\n\nconst emit = defineEmits<{\n (e: 'select', variable: string): void\n (e: 'redirect'): void\n}>()\n\nconst isOpen = ref(true)\nconst dropdownRef = ref<HTMLElement | null>(null)\nconst selectedVariableIndex = ref(0)\n\nconst redirectToEnvironment = () => {\n emit('redirect')\n isOpen.value = false\n}\n\n/** Normalize the variables to have a name and value */\nconst normalizedVariables = computed(() =>\n (environment?.variables ?? []).map((v) => ({\n key: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n })),\n)\n\nconst contextRows = computed((): DropdownRow[] =>\n contextFunctionItems.map((item) => ({\n kind: 'context',\n key: item.key,\n secondary: item.description,\n })),\n)\n\nconst envRows = computed((): DropdownRow[] =>\n normalizedVariables.value\n .filter(({ key, value }) => key !== '' || value !== '')\n .map(({ key, value }) => ({\n kind: 'env' as const,\n key,\n secondary: value,\n })),\n)\n\ntype FuseRow = DropdownRow & { fuseText: string }\n\nconst envFuseSource = computed((): FuseRow[] =>\n envRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst contextFuseSource = computed((): FuseRow[] =>\n contextRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst fuseEnv = computed(\n () =>\n new Fuse(envFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst fuseContext = computed(\n () =>\n new Fuse(contextFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst popularContextRows = computed((): DropdownRow[] => {\n const byKey = new Map(contextFunctionItems.map((c) => [c.key, c]))\n return POPULAR_CONTEXT_FUNCTION_KEYS.flatMap((key) => {\n const item = byKey.get(key)\n return item\n ? [\n {\n kind: 'context' as const,\n key: item.key,\n secondary: item.description,\n },\n ]\n : []\n })\n})\n\nconst DROPDOWN_LIMIT = 12\n\nconst filteredVariables = computed((): DropdownRow[] => {\n if (!query.trim()) {\n const envSlice = envRows.value.slice(-4)\n return [...envSlice, ...popularContextRows.value]\n }\n\n const q = query.trim()\n const envMatches = fuseEnv.value\n .search(q, { limit: DROPDOWN_LIMIT })\n .map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n\n const remaining = DROPDOWN_LIMIT - envMatches.length\n const contextMatches =\n remaining > 0\n ? fuseContext.value.search(q, { limit: remaining }).map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n : []\n\n return [...envMatches, ...contextMatches]\n})\n\nconst selectVariable = (variableKey: string): void => {\n emit('select', variableKey)\n}\n\nconst handleArrowKey = (direction: 'up' | 'down') => {\n const offset = direction === 'up' ? -1 : 1\n const length = filteredVariables.value.length\n\n if (length === 0) {\n return\n }\n\n selectedVariableIndex.value =\n (selectedVariableIndex.value + offset + length) % length\n}\n\nconst handleSelect = () => {\n if (selectedVariableIndex.value >= 0) {\n const selectedVariable =\n filteredVariables.value[selectedVariableIndex.value]\n if (selectedVariable) {\n selectVariable(selectedVariable.key)\n }\n }\n}\n\ndefineExpose({\n handleArrowKey,\n handleSelect,\n})\n\nonMounted(() => {\n // Reset selected index to the first item when dropdown opens\n selectedVariableIndex.value = 0\n})\n\nconst dropdownStyle = computed<CSSProperties>(() => {\n return {\n left: (dropdownPosition?.left ?? 0) + 'px',\n // Add a 5px offset from the editor\n top: (dropdownPosition?.top ?? 0) + 5 + 'px',\n }\n})\n\nonClickOutside(\n dropdownRef,\n () => {\n isOpen.value = false\n },\n { ignore: [dropdownRef] },\n)\n</script>\n<template>\n <ScalarTeleport\n v-if=\"isOpen\"\n class=\"scalar-client\">\n <div\n ref=\"dropdownRef\"\n class=\"custom-scroll z-context fixed top-0 left-0 flex max-h-[60svh] w-56 flex-col rounded border p-0.75\"\n :style=\"dropdownStyle\">\n <ul\n v-if=\"filteredVariables.length\"\n class=\"gap-1/2 flex flex-col\">\n <template\n v-for=\"(item, index) in filteredVariables\"\n :key=\"`${item.kind}-${item.key}`\">\n <li\n class=\"font-code text-xxs hover:bg-b-2 flex h-8 cursor-pointer items-center justify-between gap-1.5 rounded p-1.5 transition-colors duration-150\"\n :class=\"{ 'bg-b-2': index === selectedVariableIndex }\"\n @click=\"selectVariable(item.key)\">\n <div class=\"flex items-center gap-2 whitespace-nowrap\">\n <span\n v-if=\"item.kind === 'env'\"\n class=\"h-2.25 w-2.25 min-w-2.25 rounded-full\"\n :style=\"{\n backgroundColor: environment?.color,\n }\" />\n <span\n v-else\n class=\"text-c-3 bg-b-3 flex h-4.5 min-w-4.5 items-center justify-center rounded px-0.5 font-sans text-[9px] font-semibold\">\n fn\n </span>\n {{ item.key }}\n </div>\n <span\n class=\"max-w-[9rem] overflow-hidden text-right text-ellipsis whitespace-nowrap\">\n {{ item.secondary }}\n </span>\n </li>\n </template>\n </ul>\n <ScalarButton\n v-else\n class=\"font-code text-xxs bg-b-inherit hover:bg-b-2 flex h-8 w-full justify-start gap-2 px-1.5 transition-colors duration-150\"\n variant=\"outlined\"\n @click=\"redirectToEnvironment\">\n <ScalarIconPlus class=\"size-3\" />\n Add Variable\n </ScalarButton>\n <!-- Backdrop for the dropdown -->\n <div\n class=\"bg-b-1 brightness-lifted absolute inset-0 -z-1 rounded shadow-lg\" />\n </div>\n </ScalarTeleport>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"EnvironmentVariablesDropdown.vue.script.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarTeleport } from '@scalar/components/teleport'\nimport { ScalarIconPlus } from '@scalar/icons'\nimport { POPULAR_CONTEXT_FUNCTION_KEYS } from '@scalar/workspace-store/request-example'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { onClickOutside } from '@vueuse/core'\nimport Fuse from 'fuse.js'\nimport { computed, onMounted, ref, watch, type CSSProperties } from 'vue'\n\ntype DropdownRow =\n | { kind: 'env'; key: string; secondary: string }\n | { kind: 'context'; key: string; secondary: string }\n\nconst {\n query,\n environment,\n dropdownPosition,\n contextFunctionItems = [],\n listboxId,\n} = defineProps<{\n query: string\n environment?: XScalarEnvironment\n dropdownPosition?: { left: number; top: number }\n /** Runtime placeholders such as `{{$guid}}`, shown with environment variables */\n contextFunctionItems?: { key: string; description: string }[]\n /**\n * Id for the `role=\"listbox\"` element. When set, each option also receives a\n * stable id so the owning combobox input can reference the active option via\n * `aria-activedescendant` (W3C combobox pattern).\n */\n listboxId?: string\n}>()\n\nconst emit = defineEmits<{\n (e: 'select', variable: string): void\n (e: 'redirect'): void\n /**\n * Fired when the user dismisses the panel by clicking outside. The owning\n * combobox needs this to clear its `aria-expanded`/`aria-controls` state,\n * which would otherwise keep pointing at a listbox that is no longer mounted.\n */\n (e: 'close'): void\n}>()\n\nconst isOpen = ref(true)\nconst dropdownRef = ref<HTMLElement | null>(null)\nconst selectedVariableIndex = ref(0)\n\nconst redirectToEnvironment = () => {\n emit('redirect')\n isOpen.value = false\n // The panel is gone, so tell the combobox to drop its aria-expanded /\n // aria-controls — otherwise they keep pointing at a dismissed listbox.\n emit('close')\n}\n\n/** Normalize the variables to have a name and value */\nconst normalizedVariables = computed(() =>\n (environment?.variables ?? []).map((v) => ({\n key: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n })),\n)\n\nconst contextRows = computed((): DropdownRow[] =>\n contextFunctionItems.map((item) => ({\n kind: 'context',\n key: item.key,\n secondary: item.description,\n })),\n)\n\nconst envRows = computed((): DropdownRow[] =>\n normalizedVariables.value\n .filter(({ key, value }) => key !== '' || value !== '')\n .map(({ key, value }) => ({\n kind: 'env' as const,\n key,\n secondary: value,\n })),\n)\n\ntype FuseRow = DropdownRow & { fuseText: string }\n\nconst envFuseSource = computed((): FuseRow[] =>\n envRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst contextFuseSource = computed((): FuseRow[] =>\n contextRows.value.map((row) => ({\n ...row,\n fuseText: `${row.key} ${row.secondary}`,\n })),\n)\n\nconst fuseEnv = computed(\n () =>\n new Fuse(envFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst fuseContext = computed(\n () =>\n new Fuse(contextFuseSource.value, {\n keys: ['fuseText'],\n threshold: 0.35,\n }),\n)\n\nconst popularContextRows = computed((): DropdownRow[] => {\n const byKey = new Map(contextFunctionItems.map((c) => [c.key, c]))\n return POPULAR_CONTEXT_FUNCTION_KEYS.flatMap((key) => {\n const item = byKey.get(key)\n return item\n ? [\n {\n kind: 'context' as const,\n key: item.key,\n secondary: item.description,\n },\n ]\n : []\n })\n})\n\nconst DROPDOWN_LIMIT = 12\n\nconst filteredVariables = computed((): DropdownRow[] => {\n if (!query.trim()) {\n const envSlice = envRows.value.slice(-4)\n return [...envSlice, ...popularContextRows.value]\n }\n\n const q = query.trim()\n const envMatches = fuseEnv.value\n .search(q, { limit: DROPDOWN_LIMIT })\n .map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n\n const remaining = DROPDOWN_LIMIT - envMatches.length\n const contextMatches =\n remaining > 0\n ? fuseContext.value.search(q, { limit: remaining }).map((res) => {\n const { kind, key, secondary } = res.item\n return { kind, key, secondary }\n })\n : []\n\n return [...envMatches, ...contextMatches]\n})\n\nconst optionId = (index: number): string | undefined =>\n listboxId ? `${listboxId}-option-${index}` : undefined\n\n/**\n * Id of the currently highlighted option, for the combobox's\n * `aria-activedescendant`. Undefined when there is no list to point at.\n */\nconst activeOptionId = computed((): string | undefined =>\n filteredVariables.value.length\n ? optionId(selectedVariableIndex.value)\n : undefined,\n)\n\nconst selectVariable = (variableKey: string): void => {\n emit('select', variableKey)\n}\n\n// Narrowing the query shrinks the list; keep the highlight in range so both the\n// visible selection and `aria-activedescendant` never reference a dropped option.\nwatch(\n () => filteredVariables.value.length,\n (length) => {\n if (selectedVariableIndex.value > length - 1) {\n selectedVariableIndex.value = Math.max(0, length - 1)\n }\n },\n)\n\nconst handleArrowKey = (direction: 'up' | 'down') => {\n const offset = direction === 'up' ? -1 : 1\n const length = filteredVariables.value.length\n\n if (length === 0) {\n return\n }\n\n selectedVariableIndex.value =\n (selectedVariableIndex.value + offset + length) % length\n}\n\nconst handleSelect = () => {\n if (selectedVariableIndex.value >= 0) {\n const selectedVariable =\n filteredVariables.value[selectedVariableIndex.value]\n if (selectedVariable) {\n selectVariable(selectedVariable.key)\n }\n }\n}\n\ndefineExpose({\n handleArrowKey,\n handleSelect,\n activeOptionId,\n})\n\nonMounted(() => {\n // Reset selected index to the first item when dropdown opens\n selectedVariableIndex.value = 0\n})\n\nconst dropdownStyle = computed<CSSProperties>(() => {\n return {\n left: (dropdownPosition?.left ?? 0) + 'px',\n // Add a 5px offset from the editor\n top: (dropdownPosition?.top ?? 0) + 5 + 'px',\n }\n})\n\nonClickOutside(\n dropdownRef,\n () => {\n isOpen.value = false\n emit('close')\n },\n { ignore: [dropdownRef] },\n)\n</script>\n<template>\n <ScalarTeleport\n v-if=\"isOpen\"\n class=\"scalar-client\">\n <div\n ref=\"dropdownRef\"\n class=\"custom-scroll z-context fixed top-0 left-0 flex max-h-[60svh] w-56 flex-col rounded border p-0.75\"\n :style=\"dropdownStyle\"\n @mousedown.prevent>\n <!--\n Always rendered (even with no matches) so the combobox's `aria-controls`\n always resolves to a real listbox; an empty list simply has no options.\n -->\n <ul\n :id=\"listboxId\"\n aria-label=\"Variable suggestions\"\n class=\"gap-1/2 flex flex-col\"\n role=\"listbox\">\n <template\n v-for=\"(item, index) in filteredVariables\"\n :key=\"`${item.kind}-${item.key}`\">\n <li\n :id=\"optionId(index)\"\n :aria-selected=\"index === selectedVariableIndex\"\n class=\"font-code text-xxs hover:bg-b-3 flex h-8 cursor-pointer items-center justify-between gap-1.5 rounded p-1.5 transition-colors duration-150\"\n :class=\"{ 'bg-b-3': index === selectedVariableIndex }\"\n role=\"option\"\n @click=\"selectVariable(item.key)\">\n <div class=\"flex items-center gap-2 whitespace-nowrap\">\n <span\n v-if=\"item.kind === 'env'\"\n class=\"h-2.25 w-2.25 min-w-2.25 rounded-full\"\n :style=\"{\n backgroundColor: environment?.color,\n }\" />\n <span\n v-else\n class=\"text-c-3 bg-b-3 flex h-4.5 min-w-4.5 items-center justify-center rounded px-0.5 font-sans text-[9px] font-semibold\">\n fn\n </span>\n {{ item.key }}\n </div>\n <span\n class=\"max-w-[9rem] overflow-hidden text-right text-ellipsis whitespace-nowrap\">\n {{ item.secondary }}\n </span>\n </li>\n </template>\n </ul>\n <ScalarButton\n v-if=\"!filteredVariables.length\"\n class=\"font-code text-xxs bg-b-inherit hover:bg-b-3 flex h-8 w-full justify-start gap-2 px-1.5 transition-colors duration-150\"\n variant=\"outlined\"\n @click=\"redirectToEnvironment\">\n <ScalarIconPlus class=\"size-3\" />\n Add Variable\n </ScalarButton>\n <!-- Backdrop for the dropdown -->\n <div\n class=\"bg-b-1 brightness-lifted absolute inset-0 -z-1 rounded shadow-lg\" />\n </div>\n </ScalarTeleport>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"EnvironmentVariablesTable.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesTable.vue"],"names":[],"mappings":"AA8LA,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAWnH,KAAK,WAAW,GAAG;IACf,WAAW,EAAE,kBAAkB,CAAA;IAC/B,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,iBAAiB,CAAA;CAC5B,GAAG,cAAc,CAAC;AAgXrB,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"EnvironmentVariablesTable.vue.d.ts","sourceRoot":"","sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesTable.vue"],"names":[],"mappings":"AA2KA,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EAClB,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2EAA2E,CAAA;AAWnH,KAAK,WAAW,GAAG;IACf,WAAW,EAAE,kBAAkB,CAAA;IAC/B,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,iBAAiB,CAAA;CAC5B,GAAG,cAAc,CAAC;AAgWrB,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -2,7 +2,7 @@ import _plugin_vue_export_helper_default from "../../../../_virtual/_plugin-vue_
2
2
  import EnvironmentVariablesTable_vue_vue_type_script_setup_true_lang_default from "./EnvironmentVariablesTable.vue.script.js";
3
3
  /* empty css */
4
4
  //#region src/v2/features/environments/components/EnvironmentVariablesTable.vue
5
- var EnvironmentVariablesTable_default = /* @__PURE__ */ _plugin_vue_export_helper_default(EnvironmentVariablesTable_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-69be2d6c"]]);
5
+ var EnvironmentVariablesTable_default = /* @__PURE__ */ _plugin_vue_export_helper_default(EnvironmentVariablesTable_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-5b336842"]]);
6
6
  //#endregion
7
7
  export { EnvironmentVariablesTable_default as default };
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"EnvironmentVariablesTable.vue.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarIconTrash } from '@scalar/icons'\nimport type {\n CollectionType,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed } from 'vue'\n\nimport { CodeInput } from '@/v2/components/code-input'\nimport {\n DataTable,\n DataTableCell,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\n\nconst { environment, environmentName, eventBus, collectionType } = defineProps<\n {\n environment: XScalarEnvironment\n environmentName: string\n eventBus: WorkspaceEventBus\n } & CollectionType\n>()\n\n/** Column widths: Name, Value, Actions (delete button) */\nconst COLUMNS = ['1fr', '1fr', '36px']\n\n/** Adds an empty row at the end for creating new variables */\nconst displayRows = computed<\n {\n name: string\n value: string\n }[]\n>(() => {\n /** Normalize the variables to have a name and value */\n const variableRows = environment.variables.map((v) => ({\n name: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n }))\n\n const lastRow = environment.variables.at(-1)\n const hasContentInLastRow =\n lastRow && (lastRow.name !== '' || lastRow.value !== '')\n\n // Add the extra row at the end\n if (!lastRow || hasContentInLastRow) {\n return [...variableRows, { name: '', value: '' }]\n }\n\n return variableRows\n})\n\n/** Updates an existing variable or creates a new one */\nconst handleVariableChange = (\n name: string,\n value: string,\n index: number,\n): void => {\n const isNewVariable = index >= environment.variables.length\n\n /**\n * Do not allow adding a new variable with an empty name on the last row,\n * we allow it on other rows as it will delete the row\n */\n if (!name && isNewVariable) {\n return\n }\n\n // Adding a new variable\n if (index >= environment.variables.length) {\n eventBus.emit('environment:upsert:environment-variable', {\n environmentName,\n variable: { name, value },\n collectionType,\n })\n return\n }\n\n // Updating\n eventBus.emit('environment:upsert:environment-variable', {\n environmentName,\n variable: { name, value },\n index,\n collectionType,\n })\n}\n\n/** Deletes a variable by index */\nconst handleVariableDelete = (index: number): void =>\n eventBus.emit('environment:delete:environment-variable', {\n environmentName,\n index,\n collectionType,\n })\n</script>\n<template>\n <!-- Environment variables table -->\n <DataTable\n class=\"group/table data-table h-min flex-1 rounded\"\n :columns=\"COLUMNS\">\n <!-- Accessibility header row -->\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>Name</DataTableHeader>\n <DataTableHeader>Value</DataTableHeader>\n <DataTableHeader>Actions</DataTableHeader>\n </DataTableRow>\n\n <!-- Variable rows -->\n <DataTableRow\n v-for=\"(row, index) in displayRows\"\n :key=\"index\"\n class=\"group/row\">\n <!-- Name -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Environment Variable Name\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.name\"\n placeholder=\"Name\"\n @update:modelValue=\"\n (name) => handleVariableChange(name, row.value, index)\n \" />\n </DataTableCell>\n\n <!-- Value -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Environment Variable Value\"\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.value\"\n placeholder=\"Value\"\n @update:modelValue=\"\n (value) => handleVariableChange(row.name, value, index)\n \" />\n </DataTableCell>\n\n <!-- Delete button -->\n <DataTableCell class=\"flex items-center justify-center\">\n <ScalarButton\n v-if=\"index < environment.variables.length\"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 hidden h-fit rounded p-1 group-focus-within:flex group-hover/row:flex\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleVariableDelete(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </DataTableCell>\n </DataTableRow>\n </DataTable>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n padding: 0;\n}\n:deep(.cm-content) {\n align-items: center;\n background-color: transparent;\n display: flex;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n width: 100%;\n}\n:deep(.cm-content):has(.cm-pill) {\n padding: 5px 8px;\n}\n:deep(.cm-content .cm-pill:not(:last-of-type)) {\n margin-right: 0.5px;\n}\n:deep(.cm-content .cm-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n:deep(.cm-line) {\n overflow: hidden;\n padding: 0;\n text-overflow: ellipsis;\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"EnvironmentVariablesTable.vue.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarIconTrash } from '@scalar/icons'\nimport type {\n CollectionType,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed } from 'vue'\n\nimport { CodeInputLite } from '@/v2/components/code-input'\nimport {\n DataTable,\n DataTableCell,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\n\nconst { environment, environmentName, eventBus, collectionType } = defineProps<\n {\n environment: XScalarEnvironment\n environmentName: string\n eventBus: WorkspaceEventBus\n } & CollectionType\n>()\n\n/** Column widths: Name, Value, Actions (delete button) */\nconst COLUMNS = ['1fr', '1fr', '36px']\n\n/** Adds an empty row at the end for creating new variables */\nconst displayRows = computed<\n {\n name: string\n value: string\n }[]\n>(() => {\n /** Normalize the variables to have a name and value */\n const variableRows = environment.variables.map((v) => ({\n name: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n }))\n\n const lastRow = environment.variables.at(-1)\n const hasContentInLastRow =\n lastRow && (lastRow.name !== '' || lastRow.value !== '')\n\n // Add the extra row at the end\n if (!lastRow || hasContentInLastRow) {\n return [...variableRows, { name: '', value: '' }]\n }\n\n return variableRows\n})\n\n/** Updates an existing variable or creates a new one */\nconst handleVariableChange = (\n name: string,\n value: string,\n index: number,\n): void => {\n const isNewVariable = index >= environment.variables.length\n\n /**\n * Do not allow adding a new variable with an empty name on the last row,\n * we allow it on other rows as it will delete the row\n */\n if (!name && isNewVariable) {\n return\n }\n\n // Adding a new variable\n if (index >= environment.variables.length) {\n eventBus.emit('environment:upsert:environment-variable', {\n environmentName,\n variable: { name, value },\n collectionType,\n })\n return\n }\n\n // Updating\n eventBus.emit('environment:upsert:environment-variable', {\n environmentName,\n variable: { name, value },\n index,\n collectionType,\n })\n}\n\n/** Deletes a variable by index */\nconst handleVariableDelete = (index: number): void =>\n eventBus.emit('environment:delete:environment-variable', {\n environmentName,\n index,\n collectionType,\n })\n</script>\n<template>\n <!-- Environment variables table -->\n <DataTable\n class=\"group/table data-table h-min flex-1 rounded\"\n :columns=\"COLUMNS\">\n <!-- Accessibility header row -->\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>Name</DataTableHeader>\n <DataTableHeader>Value</DataTableHeader>\n <DataTableHeader>Actions</DataTableHeader>\n </DataTableRow>\n\n <!-- Variable rows -->\n <DataTableRow\n v-for=\"(row, index) in displayRows\"\n :key=\"index\"\n class=\"group/row\">\n <!-- Name -->\n <DataTableCell>\n <CodeInputLite\n aria-label=\"Environment Variable Name\"\n :environment=\"undefined\"\n :modelValue=\"row.name\"\n placeholder=\"Name\"\n @update:modelValue=\"\n (name) => handleVariableChange(name, row.value, index)\n \" />\n </DataTableCell>\n\n <!-- Value -->\n <DataTableCell>\n <CodeInputLite\n aria-label=\"Environment Variable Value\"\n :environment=\"undefined\"\n :modelValue=\"row.value\"\n placeholder=\"Value\"\n @update:modelValue=\"\n (value) => handleVariableChange(row.name, value, index)\n \" />\n </DataTableCell>\n\n <!-- Delete button -->\n <DataTableCell class=\"flex items-center justify-center\">\n <ScalarButton\n v-if=\"index < environment.variables.length\"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 hidden h-fit rounded p-1 group-focus-within:flex group-hover/row:flex\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleVariableDelete(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </DataTableCell>\n </DataTableRow>\n </DataTable>\n</template>\n<style scoped>\n:deep(.code-input-lite__editor) {\n background-color: transparent;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n}\n:deep(.scalar-pill:not(:last-of-type)) {\n margin-right: 0.15em;\n}\n:deep(.scalar-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n</style>\n"],"mappings":""}
@@ -1,4 +1,4 @@
1
- import CodeInput_default from "../../../components/code-input/CodeInput.vue.js";
1
+ import CodeInputLite_default from "../../../components/code-input/CodeInputLite.vue.js";
2
2
  import DataTable_default from "../../../components/data-table/DataTable.vue.js";
3
3
  import DataTableCell_default from "../../../components/data-table/DataTableCell.vue.js";
4
4
  import DataTableHeader_default from "../../../components/data-table/DataTableHeader.vue.js";
@@ -100,12 +100,9 @@ var EnvironmentVariablesTable_vue_vue_type_script_setup_true_lang_default = /* @
100
100
  }, {
101
101
  default: withCtx(() => [
102
102
  createVNode(unref(DataTableCell_default), null, {
103
- default: withCtx(() => [createVNode(unref(CodeInput_default), {
103
+ default: withCtx(() => [createVNode(unref(CodeInputLite_default), {
104
104
  "aria-label": "Environment Variable Name",
105
- disableCloseBrackets: "",
106
- disableTabIndent: "",
107
105
  environment: void 0,
108
- lineWrapping: "",
109
106
  modelValue: row.name,
110
107
  placeholder: "Name",
111
108
  "onUpdate:modelValue": (name) => handleVariableChange(name, row.value, index)
@@ -113,11 +110,9 @@ var EnvironmentVariablesTable_vue_vue_type_script_setup_true_lang_default = /* @
113
110
  _: 2
114
111
  }, 1024),
115
112
  createVNode(unref(DataTableCell_default), null, {
116
- default: withCtx(() => [createVNode(unref(CodeInput_default), {
113
+ default: withCtx(() => [createVNode(unref(CodeInputLite_default), {
117
114
  "aria-label": "Environment Variable Value",
118
- disableTabIndent: "",
119
115
  environment: void 0,
120
- lineWrapping: "",
121
116
  modelValue: row.value,
122
117
  placeholder: "Value",
123
118
  "onUpdate:modelValue": (value) => handleVariableChange(row.name, value, index)
@@ -1 +1 @@
1
- {"version":3,"file":"EnvironmentVariablesTable.vue.script.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarIconTrash } from '@scalar/icons'\nimport type {\n CollectionType,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed } from 'vue'\n\nimport { CodeInput } from '@/v2/components/code-input'\nimport {\n DataTable,\n DataTableCell,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\n\nconst { environment, environmentName, eventBus, collectionType } = defineProps<\n {\n environment: XScalarEnvironment\n environmentName: string\n eventBus: WorkspaceEventBus\n } & CollectionType\n>()\n\n/** Column widths: Name, Value, Actions (delete button) */\nconst COLUMNS = ['1fr', '1fr', '36px']\n\n/** Adds an empty row at the end for creating new variables */\nconst displayRows = computed<\n {\n name: string\n value: string\n }[]\n>(() => {\n /** Normalize the variables to have a name and value */\n const variableRows = environment.variables.map((v) => ({\n name: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n }))\n\n const lastRow = environment.variables.at(-1)\n const hasContentInLastRow =\n lastRow && (lastRow.name !== '' || lastRow.value !== '')\n\n // Add the extra row at the end\n if (!lastRow || hasContentInLastRow) {\n return [...variableRows, { name: '', value: '' }]\n }\n\n return variableRows\n})\n\n/** Updates an existing variable or creates a new one */\nconst handleVariableChange = (\n name: string,\n value: string,\n index: number,\n): void => {\n const isNewVariable = index >= environment.variables.length\n\n /**\n * Do not allow adding a new variable with an empty name on the last row,\n * we allow it on other rows as it will delete the row\n */\n if (!name && isNewVariable) {\n return\n }\n\n // Adding a new variable\n if (index >= environment.variables.length) {\n eventBus.emit('environment:upsert:environment-variable', {\n environmentName,\n variable: { name, value },\n collectionType,\n })\n return\n }\n\n // Updating\n eventBus.emit('environment:upsert:environment-variable', {\n environmentName,\n variable: { name, value },\n index,\n collectionType,\n })\n}\n\n/** Deletes a variable by index */\nconst handleVariableDelete = (index: number): void =>\n eventBus.emit('environment:delete:environment-variable', {\n environmentName,\n index,\n collectionType,\n })\n</script>\n<template>\n <!-- Environment variables table -->\n <DataTable\n class=\"group/table data-table h-min flex-1 rounded\"\n :columns=\"COLUMNS\">\n <!-- Accessibility header row -->\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>Name</DataTableHeader>\n <DataTableHeader>Value</DataTableHeader>\n <DataTableHeader>Actions</DataTableHeader>\n </DataTableRow>\n\n <!-- Variable rows -->\n <DataTableRow\n v-for=\"(row, index) in displayRows\"\n :key=\"index\"\n class=\"group/row\">\n <!-- Name -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Environment Variable Name\"\n disableCloseBrackets\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.name\"\n placeholder=\"Name\"\n @update:modelValue=\"\n (name) => handleVariableChange(name, row.value, index)\n \" />\n </DataTableCell>\n\n <!-- Value -->\n <DataTableCell>\n <CodeInput\n aria-label=\"Environment Variable Value\"\n disableTabIndent\n :environment=\"undefined\"\n lineWrapping\n :modelValue=\"row.value\"\n placeholder=\"Value\"\n @update:modelValue=\"\n (value) => handleVariableChange(row.name, value, index)\n \" />\n </DataTableCell>\n\n <!-- Delete button -->\n <DataTableCell class=\"flex items-center justify-center\">\n <ScalarButton\n v-if=\"index < environment.variables.length\"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 hidden h-fit rounded p-1 group-focus-within:flex group-hover/row:flex\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleVariableDelete(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </DataTableCell>\n </DataTableRow>\n </DataTable>\n</template>\n<style scoped>\n:deep(.cm-editor) {\n padding: 0;\n}\n:deep(.cm-content) {\n align-items: center;\n background-color: transparent;\n display: flex;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n width: 100%;\n}\n:deep(.cm-content):has(.cm-pill) {\n padding: 5px 8px;\n}\n:deep(.cm-content .cm-pill:not(:last-of-type)) {\n margin-right: 0.5px;\n}\n:deep(.cm-content .cm-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n:deep(.cm-line) {\n overflow: hidden;\n padding: 0;\n text-overflow: ellipsis;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;EA2BA,MAAM,UAAU;GAAC;GAAO;GAAO;GAAM;;EAGrC,MAAM,cAAc,eAKZ;;GAEN,MAAM,eAAe,QAAA,YAAY,UAAU,KAAK,OAAO;IACrD,MAAM,EAAE;IACR,OAAO,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ,EAAE,MAAM;IACxD,EAAC;GAEF,MAAM,UAAU,QAAA,YAAY,UAAU,GAAG,GAAE;GAC3C,MAAM,sBACJ,YAAY,QAAQ,SAAS,MAAM,QAAQ,UAAU;AAGvD,OAAI,CAAC,WAAW,oBACd,QAAO,CAAC,GAAG,cAAc;IAAE,MAAM;IAAI,OAAO;IAAI,CAAA;AAGlD,UAAO;IACR;;EAGD,MAAM,wBACJ,MACA,OACA,UACS;GACT,MAAM,gBAAgB,SAAS,QAAA,YAAY,UAAU;;;;;AAMrD,OAAI,CAAC,QAAQ,cACX;AAIF,OAAI,SAAS,QAAA,YAAY,UAAU,QAAQ;AACzC,YAAA,SAAS,KAAK,2CAA2C;KACvD,iBAAc,QAAA;KACd,UAAU;MAAE;MAAM;MAAO;KACzB,gBAAa,QAAA;KACd,CAAA;AACD;;AAIF,WAAA,SAAS,KAAK,2CAA2C;IACvD,iBAAc,QAAA;IACd,UAAU;KAAE;KAAM;KAAO;IACzB;IACA,gBAAa,QAAA;IACd,CAAA;;;EAIH,MAAM,wBAAwB,UAC5B,QAAA,SAAS,KAAK,2CAA2C;GACvD,iBAAc,QAAA;GACd;GACA,gBAAa,QAAA;GACd,CAAA;;uBAID,YAwDY,MAAA,kBAAA,EAAA;IAvDV,OAAM;IACL,SAAS;;2BAMK,CAJf,YAIe,MAAA,qBAAA,EAAA,EAJD,OAAM,kBAAgB,EAAA;4BACK;MAAvC,YAAuC,MAAA,wBAAA,EAAA,MAAA;8BAAlB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAJ,QAAI,GAAA,CAAA,EAAA,CAAA;;;MACrB,YAAwC,MAAA,wBAAA,EAAA,MAAA;8BAAlB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAL,SAAK,GAAA,CAAA,EAAA,CAAA;;;MACtB,YAA0C,MAAA,wBAAA,EAAA,MAAA;8BAAlB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAP,WAAO,GAAA,CAAA,EAAA,CAAA;;;;;0BAI1B,mBA4Ce,UAAA,MAAA,WA3CU,YAAA,QAAf,KAAK,UAAK;yBADpB,YA4Ce,MAAA,qBAAA,EAAA;MA1CZ,KAAK;MACN,OAAM;;6BAcU;OAZhB,YAYgB,MAAA,sBAAA,EAAA,MAAA;+BADR,CAVN,YAUM,MAAA,kBAAA,EAAA;SATJ,cAAW;SACX,sBAAA;SACA,kBAAA;SACC,aAAa,KAAA;SACd,cAAA;SACC,YAAY,IAAI;SACjB,aAAY;SACX,wBAAiC,SAAS,qBAAqB,MAAM,IAAI,OAAO,MAAK;;;;OAM1F,YAWgB,MAAA,sBAAA,EAAA,MAAA;+BADR,CATN,YASM,MAAA,kBAAA,EAAA;SARJ,cAAW;SACX,kBAAA;SACC,aAAa,KAAA;SACd,cAAA;SACC,YAAY,IAAI;SACjB,aAAY;SACX,wBAAiC,UAAU,qBAAqB,IAAI,MAAM,OAAO,MAAK;;;;OAM3F,YASgB,MAAA,sBAAA,EAAA,EATD,OAAM,oCAAkC,EAAA;+BAQtC,CANP,QAAQ,QAAA,YAAY,UAAU,UAAA,WAAA,EADtC,YAOe,MAAA,aAAA,EAAA;;SALb,OAAM;SACN,MAAK;SACL,SAAQ;SACP,UAAK,WAAE,qBAAqB,MAAK;;gCACE,CAApC,YAAoC,MAAA,gBAAA,EAAA,EAAnB,OAAM,YAAU,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"EnvironmentVariablesTable.vue.script.js","names":[],"sources":["../../../../../src/v2/features/environments/components/EnvironmentVariablesTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ScalarButton } from '@scalar/components/button'\nimport { ScalarIconTrash } from '@scalar/icons'\nimport type {\n CollectionType,\n WorkspaceEventBus,\n} from '@scalar/workspace-store/events'\nimport type { XScalarEnvironment } from '@scalar/workspace-store/schemas/extensions/document/x-scalar-environments'\nimport { computed } from 'vue'\n\nimport { CodeInputLite } from '@/v2/components/code-input'\nimport {\n DataTable,\n DataTableCell,\n DataTableHeader,\n DataTableRow,\n} from '@/v2/components/data-table'\n\nconst { environment, environmentName, eventBus, collectionType } = defineProps<\n {\n environment: XScalarEnvironment\n environmentName: string\n eventBus: WorkspaceEventBus\n } & CollectionType\n>()\n\n/** Column widths: Name, Value, Actions (delete button) */\nconst COLUMNS = ['1fr', '1fr', '36px']\n\n/** Adds an empty row at the end for creating new variables */\nconst displayRows = computed<\n {\n name: string\n value: string\n }[]\n>(() => {\n /** Normalize the variables to have a name and value */\n const variableRows = environment.variables.map((v) => ({\n name: v.name,\n value: typeof v.value === 'string' ? v.value : v.value.default,\n }))\n\n const lastRow = environment.variables.at(-1)\n const hasContentInLastRow =\n lastRow && (lastRow.name !== '' || lastRow.value !== '')\n\n // Add the extra row at the end\n if (!lastRow || hasContentInLastRow) {\n return [...variableRows, { name: '', value: '' }]\n }\n\n return variableRows\n})\n\n/** Updates an existing variable or creates a new one */\nconst handleVariableChange = (\n name: string,\n value: string,\n index: number,\n): void => {\n const isNewVariable = index >= environment.variables.length\n\n /**\n * Do not allow adding a new variable with an empty name on the last row,\n * we allow it on other rows as it will delete the row\n */\n if (!name && isNewVariable) {\n return\n }\n\n // Adding a new variable\n if (index >= environment.variables.length) {\n eventBus.emit('environment:upsert:environment-variable', {\n environmentName,\n variable: { name, value },\n collectionType,\n })\n return\n }\n\n // Updating\n eventBus.emit('environment:upsert:environment-variable', {\n environmentName,\n variable: { name, value },\n index,\n collectionType,\n })\n}\n\n/** Deletes a variable by index */\nconst handleVariableDelete = (index: number): void =>\n eventBus.emit('environment:delete:environment-variable', {\n environmentName,\n index,\n collectionType,\n })\n</script>\n<template>\n <!-- Environment variables table -->\n <DataTable\n class=\"group/table data-table h-min flex-1 rounded\"\n :columns=\"COLUMNS\">\n <!-- Accessibility header row -->\n <DataTableRow class=\"sr-only !block\">\n <DataTableHeader>Name</DataTableHeader>\n <DataTableHeader>Value</DataTableHeader>\n <DataTableHeader>Actions</DataTableHeader>\n </DataTableRow>\n\n <!-- Variable rows -->\n <DataTableRow\n v-for=\"(row, index) in displayRows\"\n :key=\"index\"\n class=\"group/row\">\n <!-- Name -->\n <DataTableCell>\n <CodeInputLite\n aria-label=\"Environment Variable Name\"\n :environment=\"undefined\"\n :modelValue=\"row.name\"\n placeholder=\"Name\"\n @update:modelValue=\"\n (name) => handleVariableChange(name, row.value, index)\n \" />\n </DataTableCell>\n\n <!-- Value -->\n <DataTableCell>\n <CodeInputLite\n aria-label=\"Environment Variable Value\"\n :environment=\"undefined\"\n :modelValue=\"row.value\"\n placeholder=\"Value\"\n @update:modelValue=\"\n (value) => handleVariableChange(row.name, value, index)\n \" />\n </DataTableCell>\n\n <!-- Delete button -->\n <DataTableCell class=\"flex items-center justify-center\">\n <ScalarButton\n v-if=\"index < environment.variables.length\"\n class=\"text-c-2 hover:text-c-1 hover:bg-b-2 hidden h-fit rounded p-1 group-focus-within:flex group-hover/row:flex\"\n size=\"sm\"\n variant=\"ghost\"\n @click=\"handleVariableDelete(index)\">\n <ScalarIconTrash class=\"size-3.5\" />\n </ScalarButton>\n </DataTableCell>\n </DataTableRow>\n </DataTable>\n</template>\n<style scoped>\n:deep(.code-input-lite__editor) {\n background-color: transparent;\n font-family: var(--scalar-font);\n font-size: var(--scalar-small);\n padding: 5px 8px;\n}\n:deep(.scalar-pill:not(:last-of-type)) {\n margin-right: 0.15em;\n}\n:deep(.scalar-pill:not(:first-of-type)) {\n margin-left: 0.5px;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;EA2BA,MAAM,UAAU;GAAC;GAAO;GAAO;GAAM;;EAGrC,MAAM,cAAc,eAKZ;;GAEN,MAAM,eAAe,QAAA,YAAY,UAAU,KAAK,OAAO;IACrD,MAAM,EAAE;IACR,OAAO,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ,EAAE,MAAM;IACxD,EAAC;GAEF,MAAM,UAAU,QAAA,YAAY,UAAU,GAAG,GAAE;GAC3C,MAAM,sBACJ,YAAY,QAAQ,SAAS,MAAM,QAAQ,UAAU;AAGvD,OAAI,CAAC,WAAW,oBACd,QAAO,CAAC,GAAG,cAAc;IAAE,MAAM;IAAI,OAAO;IAAI,CAAA;AAGlD,UAAO;IACR;;EAGD,MAAM,wBACJ,MACA,OACA,UACS;GACT,MAAM,gBAAgB,SAAS,QAAA,YAAY,UAAU;;;;;AAMrD,OAAI,CAAC,QAAQ,cACX;AAIF,OAAI,SAAS,QAAA,YAAY,UAAU,QAAQ;AACzC,YAAA,SAAS,KAAK,2CAA2C;KACvD,iBAAc,QAAA;KACd,UAAU;MAAE;MAAM;MAAO;KACzB,gBAAa,QAAA;KACd,CAAA;AACD;;AAIF,WAAA,SAAS,KAAK,2CAA2C;IACvD,iBAAc,QAAA;IACd,UAAU;KAAE;KAAM;KAAO;IACzB;IACA,gBAAa,QAAA;IACd,CAAA;;;EAIH,MAAM,wBAAwB,UAC5B,QAAA,SAAS,KAAK,2CAA2C;GACvD,iBAAc,QAAA;GACd;GACA,gBAAa,QAAA;GACd,CAAA;;uBAID,YAmDY,MAAA,kBAAA,EAAA;IAlDV,OAAM;IACL,SAAS;;2BAMK,CAJf,YAIe,MAAA,qBAAA,EAAA,EAJD,OAAM,kBAAgB,EAAA;4BACK;MAAvC,YAAuC,MAAA,wBAAA,EAAA,MAAA;8BAAlB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAJ,QAAI,GAAA,CAAA,EAAA,CAAA;;;MACrB,YAAwC,MAAA,wBAAA,EAAA,MAAA;8BAAlB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAL,SAAK,GAAA,CAAA,EAAA,CAAA;;;MACtB,YAA0C,MAAA,wBAAA,EAAA,MAAA;8BAAlB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,gBAAP,WAAO,GAAA,CAAA,EAAA,CAAA;;;;;0BAI1B,mBAuCe,UAAA,MAAA,WAtCU,YAAA,QAAf,KAAK,UAAK;yBADpB,YAuCe,MAAA,qBAAA,EAAA;MArCZ,KAAK;MACN,OAAM;;6BAWU;OAThB,YASgB,MAAA,sBAAA,EAAA,MAAA;+BADR,CAPN,YAOM,MAAA,sBAAA,EAAA;SANJ,cAAW;SACV,aAAa,KAAA;SACb,YAAY,IAAI;SACjB,aAAY;SACX,wBAAiC,SAAS,qBAAqB,MAAM,IAAI,OAAO,MAAK;;;;OAM1F,YASgB,MAAA,sBAAA,EAAA,MAAA;+BADR,CAPN,YAOM,MAAA,sBAAA,EAAA;SANJ,cAAW;SACV,aAAa,KAAA;SACb,YAAY,IAAI;SACjB,aAAY;SACX,wBAAiC,UAAU,qBAAqB,IAAI,MAAM,OAAO,MAAK;;;;OAM3F,YASgB,MAAA,sBAAA,EAAA,EATD,OAAM,oCAAkC,EAAA;+BAQtC,CANP,QAAQ,QAAA,YAAY,UAAU,UAAA,WAAA,EADtC,YAOe,MAAA,aAAA,EAAA;;SALb,OAAM;SACN,MAAK;SACL,SAAQ;SACP,UAAK,WAAE,qBAAqB,MAAK;;gCACE,CAApC,YAAoC,MAAA,gBAAA,EAAA,EAAnB,OAAM,YAAU,CAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.vue.js","names":[],"sources":["../../../../src/v2/features/modal/Modal.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ModalProps = {\n /** The workspace store must be initialized and passed in */\n workspaceStore: WorkspaceStore\n /** The document must be initialized and passed in. OpenAPI-only — the modal has no AsyncAPI path. */\n document: ComputedRef<OpenApiDocument | null>\n /** The path must be initialized and passed in */\n path: ComputedRef<string | undefined>\n /** The event bus for handling all events */\n eventBus: WorkspaceEventBus\n /** The method must be initialized and passed in */\n method: ComputedRef<HttpMethod | undefined>\n /** The example name must be initialized and passed in */\n exampleName: ComputedRef<string | undefined>\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection: Ref<Record<string, number>>\n /** Controls the visibility of the modal */\n modalState: ModalState\n /** The sidebar state must be initialized and passed in */\n sidebarState: UseModalSidebarReturn\n /** Api client plugins to include in the modal */\n plugins: ClientPlugin[]\n /** Subset of the configuration options for the modal */\n options: MaybeRefOrGetter<ApiClientOptions>\n}\n\n/**\n * Scalar Api Client Modal\n *\n * This component is used to render the API Client Modal\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport type { ScalarListboxOption } from '@scalar/components/listbox'\nimport type { ModalState } from '@scalar/components/modal'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getActiveEnvironment } from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport {\n computed,\n onBeforeUnmount,\n ref,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\n\nimport ModalClientContainer from '@/v2/components/modals/ModalClientContainer.vue'\nimport { Sidebar, SidebarToggle } from '@/v2/components/sidebar'\nimport { type UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeModalEvents } from '@/v2/features/modal/modal-events'\nimport Operation from '@/v2/features/operation/Operation.vue'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport { useScrollLock } from '@/v2/hooks/use-scroll-lock'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\nconst {\n document,\n eventBus,\n modalState,\n options,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n} = defineProps<\n Omit<ModalProps, 'options'> & { options: ApiClientOptionsRef }\n>()\n\nconst activeWorkspace: ScalarListboxOption = {\n label: 'default',\n id: 'default',\n}\n\n/** Controls the visibility of the sidebar. */\nconst isSidebarOpen = ref(false)\n\n/** Initialize modal events */\ninitializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store: workspaceStore,\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(eventBus, 'modal', () => !modalState.open)\n\n/** Clean up on close */\nconst cleanUp = () => {\n eventBus.emit('operation:cancel:request')\n}\n\nconst isLocked = useScrollLock(() => {\n if (typeof window !== 'undefined') {\n return window.document.body\n }\n return null\n})\n\nwatch(\n () => modalState.open,\n (open) => {\n // Make sure scrolling is locked or unlocked when the modal is opened or closed\n isLocked.value = open\n\n if (!open) {\n cleanUp()\n }\n },\n)\n\n// Ensure we add our scalar wrapper class to the headless ui root\nonBeforeUnmount(() => cleanUp())\n\n/** Default sidebar width in pixels. */\nconst DEFAULT_SIDEBAR_WIDTH = 288\n\n/** Width of the sidebar, with fallback to default. */\nconst sidebarWidth = computed(\n () =>\n workspaceStore?.workspace?.['x-scalar-sidebar-width'] ??\n DEFAULT_SIDEBAR_WIDTH,\n)\n\n/** Handler for sidebar width changes. */\nconst handleSidebarWidthUpdate = (width: number) =>\n workspaceStore?.update('x-scalar-sidebar-width', width)\n\n/**\n * Merged environment variables from workspace and document levels.\n * Variables from both sources are combined, with document variables\n * taking precedence in case of naming conflicts.\n */\nconst environment = computed(\n () => getActiveEnvironment(workspaceStore, document.value).environment,\n)\n\ndefineExpose({\n sidebarWidth,\n environment,\n})\n</script>\n\n<template>\n <ModalClientContainer :modalState>\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- If we have a document, path and method, render the operation -->\n <main\n v-if=\"document.value && path?.value && method?.value\"\n class=\"relative flex h-full min-h-0 w-full flex-1\">\n <SidebarToggle\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-4 z-10 max-md:top-4\" />\n <Sidebar\n v-show=\"isSidebarOpen\"\n v-model:sidebarWidth=\"sidebarWidth\"\n :activeWorkspace=\"activeWorkspace\"\n class=\"h-full max-md:absolute! max-md:z-5 max-md:w-full!\"\n :documents=\"[document.value]\"\n :eventBus\n :isDroppable=\"() => false\"\n layout=\"modal\"\n :sidebarState=\"sidebarState.state\"\n :workspaces=\"[]\"\n @selectItem=\"sidebarState.handleSelectItem\"\n @update:sidebarWidth=\"handleSidebarWidthUpdate\" />\n <Operation\n :activeWorkspace=\"activeWorkspace\"\n class=\"flex-1\"\n :document=\"document.value\"\n :documentSlug=\"document.value['x-scalar-navigation']?.id ?? ''\"\n :environment\n :eventBus\n :exampleName=\"exampleName?.value\"\n layout=\"modal\"\n :method=\"method?.value\"\n :options\n :path=\"path?.value\"\n :plugins\n :requestBodyCompositionSelection=\"requestBodyCompositionSelection.value\"\n :workspaceStore />\n </main>\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">No document selected</span>\n </div>\n </ModalClientContainer>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Modal.vue.js","names":[],"sources":["../../../../src/v2/features/modal/Modal.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ModalProps = {\n /** The workspace store must be initialized and passed in */\n workspaceStore: WorkspaceStore\n /** The document must be initialized and passed in. OpenAPI-only — the modal has no AsyncAPI path. */\n document: ComputedRef<OpenApiDocument | null>\n /** The path must be initialized and passed in */\n path: ComputedRef<string | undefined>\n /** The event bus for handling all events */\n eventBus: WorkspaceEventBus\n /** The method must be initialized and passed in */\n method: ComputedRef<HttpMethod | undefined>\n /** The example name must be initialized and passed in */\n exampleName: ComputedRef<string | undefined>\n /** Selected anyOf/oneOf request-body variants keyed by schema path */\n requestBodyCompositionSelection: Ref<Record<string, number>>\n /** Controls the visibility of the modal */\n modalState: ModalState\n /** The sidebar state must be initialized and passed in */\n sidebarState: UseModalSidebarReturn\n /** Api client plugins to include in the modal */\n plugins: ClientPlugin[]\n /** Subset of the configuration options for the modal */\n options: MaybeRefOrGetter<ApiClientOptions>\n}\n\n/**\n * Scalar Api Client Modal\n *\n * This component is used to render the API Client Modal\n */\nexport default {}\n</script>\n\n<script setup lang=\"ts\">\nimport type { ScalarListboxOption } from '@scalar/components/listbox'\nimport type { ModalState } from '@scalar/components/modal'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport type { ClientPlugin } from '@scalar/oas-utils/helpers'\nimport { ScalarToasts } from '@scalar/use-toasts'\nimport type { WorkspaceStore } from '@scalar/workspace-store/client'\nimport { type WorkspaceEventBus } from '@scalar/workspace-store/events'\nimport { getActiveEnvironment } from '@scalar/workspace-store/request-example'\nimport type { OpenApiDocument } from '@scalar/workspace-store/schemas/v3.1/strict/openapi-document'\nimport {\n computed,\n onBeforeUnmount,\n ref,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from 'vue'\n\nimport ModalClientContainer from '@/v2/components/modals/ModalClientContainer.vue'\nimport { Sidebar, SidebarToggle } from '@/v2/components/sidebar'\nimport { type UseModalSidebarReturn } from '@/v2/features/modal/hooks/use-modal-sidebar'\nimport { initializeModalEvents } from '@/v2/features/modal/modal-events'\nimport Operation from '@/v2/features/operation/Operation.vue'\nimport { useGlobalHotKeys } from '@/v2/hooks/use-global-hot-keys'\nimport { useScrollLock } from '@/v2/hooks/use-scroll-lock'\nimport type { ApiClientOptions, ApiClientOptionsRef } from '@/v2/types/options'\n\nconst {\n document,\n eventBus,\n modalState,\n options,\n plugins,\n requestBodyCompositionSelection,\n sidebarState,\n workspaceStore,\n} = defineProps<\n Omit<ModalProps, 'options'> & { options: ApiClientOptionsRef }\n>()\n\nconst activeWorkspace: ScalarListboxOption = {\n label: 'default',\n id: 'default',\n}\n\n/** Controls the visibility of the sidebar. */\nconst isSidebarOpen = ref(false)\n\n/** Initialize modal events */\ninitializeModalEvents({\n eventBus,\n isSidebarOpen,\n requestBodyCompositionSelection,\n sidebarState,\n modalState,\n store: workspaceStore,\n})\n\n/** Register global hotkeys for the app, passing the workspace event bus and layout state */\nuseGlobalHotKeys(eventBus, 'modal', () => !modalState.open)\n\n/** Clean up on close */\nconst cleanUp = () => {\n eventBus.emit('operation:cancel:request')\n}\n\nconst isLocked = useScrollLock(() => {\n if (typeof window !== 'undefined') {\n return window.document.body\n }\n return null\n})\n\nwatch(\n () => modalState.open,\n (open) => {\n // Make sure scrolling is locked or unlocked when the modal is opened or closed\n isLocked.value = open\n\n if (!open) {\n cleanUp()\n }\n },\n)\n\n// Ensure we add our scalar wrapper class to the headless ui root\nonBeforeUnmount(() => cleanUp())\n\n/** Default sidebar width in pixels. */\nconst DEFAULT_SIDEBAR_WIDTH = 288\n\n/** Width of the sidebar, with fallback to default. */\nconst sidebarWidth = computed(\n () =>\n workspaceStore?.workspace?.['x-scalar-sidebar-width'] ??\n DEFAULT_SIDEBAR_WIDTH,\n)\n\n/** Handler for sidebar width changes. */\nconst handleSidebarWidthUpdate = (width: number) =>\n workspaceStore?.update('x-scalar-sidebar-width', width)\n\n/**\n * Merged environment variables from workspace and document levels.\n * Variables from both sources are combined, with document variables\n * taking precedence in case of naming conflicts.\n */\nconst environment = computed(\n () => getActiveEnvironment(workspaceStore, document.value).environment,\n)\n\ndefineExpose({\n sidebarWidth,\n environment,\n})\n</script>\n\n<template>\n <ModalClientContainer :modalState>\n <!-- Toasts -->\n <ScalarToasts />\n\n <!-- If we have a document, path and method, render the operation -->\n <main\n v-if=\"document.value && path?.value && method?.value\"\n class=\"relative flex h-full min-h-0 w-full flex-1\">\n <SidebarToggle\n v-model=\"isSidebarOpen\"\n class=\"absolute top-2 left-4 z-10 max-md:top-4\" />\n <Sidebar\n v-show=\"isSidebarOpen\"\n v-model:sidebarWidth=\"sidebarWidth\"\n :activeWorkspace=\"activeWorkspace\"\n class=\"h-full max-md:absolute! max-md:z-5 max-md:w-full!\"\n :documents=\"[document.value]\"\n :eventBus\n :isDroppable=\"() => false\"\n layout=\"modal\"\n :sidebarState=\"sidebarState.state\"\n :workspaces=\"[]\"\n @selectItem=\"sidebarState.handleSelectItem\"\n @update:sidebarWidth=\"handleSidebarWidthUpdate\" />\n <Operation\n :activeWorkspace=\"activeWorkspace\"\n class=\"flex-1\"\n :document=\"document.value\"\n :documentSlug=\"document.value['x-scalar-navigation']?.name ?? ''\"\n :environment\n :eventBus\n :exampleName=\"exampleName?.value\"\n layout=\"modal\"\n :method=\"method?.value\"\n :options\n :path=\"path?.value\"\n :plugins\n :requestBodyCompositionSelection=\"requestBodyCompositionSelection.value\"\n :workspaceStore />\n </main>\n <!-- Empty state -->\n <div\n v-else\n class=\"flex h-full w-full items-center justify-center\">\n <span class=\"text-c-3\">No document selected</span>\n </div>\n </ModalClientContainer>\n</template>\n"],"mappings":""}
@@ -110,7 +110,7 @@ var Modal_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
110
110
  activeWorkspace,
111
111
  class: "flex-1",
112
112
  document: __props.document.value,
113
- documentSlug: __props.document.value["x-scalar-navigation"]?.id ?? "",
113
+ documentSlug: __props.document.value["x-scalar-navigation"]?.name ?? "",
114
114
  environment: environment.value,
115
115
  eventBus: __props.eventBus,
116
116
  exampleName: __props.exampleName?.value,