@aleph-alpha/chat-kit 6.4.2 → 6.4.3

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 (27) hide show
  1. package/dist/{CkHistory.vue_vue_type_script_setup_true_lang-wu1Zrvgc.js → CkHistory.vue_vue_type_script_setup_true_lang-Bv3FuKT4.js} +78 -33
  2. package/dist/chat-kit.css +41 -10
  3. package/dist/components/base/CkCodeEditor/CkCodeEditor.vue.d.ts.map +1 -1
  4. package/dist/components/base/CkCodeEditor/createCodeMirror.d.ts +5 -1
  5. package/dist/components/base/CkCodeEditor/createCodeMirror.d.ts.map +1 -1
  6. package/dist/components/base/CkCodeEditor/index.d.ts +1 -0
  7. package/dist/components/base/CkCodeEditor/index.d.ts.map +1 -1
  8. package/dist/components/base/CkCodeEditor/loadCodeMirror.d.ts +17 -0
  9. package/dist/components/base/CkCodeEditor/loadCodeMirror.d.ts.map +1 -0
  10. package/dist/components/base/index.d.ts +1 -1
  11. package/dist/components/base/index.d.ts.map +1 -1
  12. package/dist/components/index.d.ts +1 -1
  13. package/dist/components/index.d.ts.map +1 -1
  14. package/dist/components/index.js +3 -2
  15. package/dist/{createCodeMirror-BO-TWTzn.js → createCodeMirror-CN8xL8qU.js} +20 -10
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +3 -2
  19. package/package.json +2 -2
  20. package/src/components/base/CkCodeEditor/CkCodeEditor.spec.ts +71 -0
  21. package/src/components/base/CkCodeEditor/CkCodeEditor.vue +89 -20
  22. package/src/components/base/CkCodeEditor/createCodeMirror.ts +34 -13
  23. package/src/components/base/CkCodeEditor/index.ts +1 -0
  24. package/src/components/base/CkCodeEditor/loadCodeMirror.ts +28 -0
  25. package/src/components/base/index.ts +1 -1
  26. package/src/components/index.ts +1 -0
  27. package/src/index.ts +1 -0
@@ -223,7 +223,7 @@ function useIsTruncated(elementRef, watchSource) {
223
223
  const _hoisted_1$f = { class: "ck-citation-card flex w-[22.5rem] max-w-[90vw] flex-col gap-2 rounded-md bg-background-surface-floating px-6 pb-6 pt-4 shadow-md" };
224
224
  const _hoisted_2$9 = { class: "flex min-w-0 items-center gap-3 py-0.5" };
225
225
  const _hoisted_3$8 = { class: "line-clamp-6 break-words text-sm leading-5 text-content-on-surface-secondary" };
226
- const _hoisted_4$7 = {
226
+ const _hoisted_4$8 = {
227
227
  key: 0,
228
228
  class: "flex items-center gap-1.5 text-sm leading-5 text-content-on-surface-muted"
229
229
  };
@@ -309,7 +309,7 @@ const _sfc_main$r = /* @__PURE__ */ defineComponent({
309
309
  }, 8, ["aria-label"])) : createCommentVNode("", true)
310
310
  ]),
311
311
  createElementVNode("p", _hoisted_3$8, toDisplayString(__props.snippet), 1),
312
- __props.collectionName || __props.locationLabel ? (openBlock(), createElementBlock("p", _hoisted_4$7, [
312
+ __props.collectionName || __props.locationLabel ? (openBlock(), createElementBlock("p", _hoisted_4$8, [
313
313
  __props.collectionName ? (openBlock(), createBlock(unref(UiTooltip), {
314
314
  key: 0,
315
315
  content: __props.collectionName,
@@ -502,7 +502,7 @@ const _hoisted_3$7 = {
502
502
  key: 0,
503
503
  class: "flex min-w-0 justify-end"
504
504
  };
505
- const _hoisted_4$6 = {
505
+ const _hoisted_4$7 = {
506
506
  key: 1,
507
507
  class: "flex min-w-0 justify-start"
508
508
  };
@@ -684,7 +684,7 @@ const _sfc_main$o = /* @__PURE__ */ defineComponent({
684
684
  }, [
685
685
  message.role === "user" ? (openBlock(), createElementBlock("div", _hoisted_3$7, [
686
686
  renderSlot(_ctx.$slots, "user-message", { message })
687
- ])) : (openBlock(), createElementBlock("div", _hoisted_4$6, [
687
+ ])) : (openBlock(), createElementBlock("div", _hoisted_4$7, [
688
688
  renderSlot(_ctx.$slots, "agent-message", { message })
689
689
  ]))
690
690
  ], 10, _hoisted_2$8);
@@ -853,7 +853,7 @@ const _sfc_main$l = /* @__PURE__ */ defineComponent({
853
853
  const _hoisted_1$b = ["aria-label"];
854
854
  const _hoisted_2$7 = { class: "pointer-events-none flex h-full w-full flex-col items-center justify-center gap-4 text-content-on-surface-primary" };
855
855
  const _hoisted_3$6 = { class: "flex flex-col items-center gap-1 text-center" };
856
- const _hoisted_4$5 = { class: "body-16-bold" };
856
+ const _hoisted_4$6 = { class: "body-16-bold" };
857
857
  const _hoisted_5$3 = {
858
858
  key: 0,
859
859
  class: "body-16-regular"
@@ -1029,7 +1029,7 @@ const _sfc_main$k = /* @__PURE__ */ defineComponent({
1029
1029
  renderSlot(_ctx.$slots, "default", {}, () => [
1030
1030
  createVNode(_sfc_main$l, { class: "h-36 w-52" }),
1031
1031
  createElementVNode("div", _hoisted_3$6, [
1032
- createElementVNode("p", _hoisted_4$5, toDisplayString(resolvedHeading.value), 1),
1032
+ createElementVNode("p", _hoisted_4$6, toDisplayString(resolvedHeading.value), 1),
1033
1033
  __props.hint ? (openBlock(), createElementBlock("p", _hoisted_5$3, toDisplayString(__props.hint), 1)) : createCommentVNode("", true)
1034
1034
  ])
1035
1035
  ], true)
@@ -1318,7 +1318,7 @@ const _hoisted_1$9 = {
1318
1318
  };
1319
1319
  const _hoisted_2$6 = { class: "ck-feedback-dialog__response min-h-0 flex-1 overflow-y-auto rounded-md border border-input bg-background-input-default px-3 py-2 shadow-xs" };
1320
1320
  const _hoisted_3$5 = { class: "flex min-h-0 flex-col gap-4" };
1321
- const _hoisted_4$4 = {
1321
+ const _hoisted_4$5 = {
1322
1322
  class: "self-end text-sm text-content-on-surface-muted tabular-nums",
1323
1323
  "aria-live": "polite"
1324
1324
  };
@@ -1549,7 +1549,7 @@ const _sfc_main$h = /* @__PURE__ */ defineComponent({
1549
1549
  maxlength: __props.maxFreeTextLength,
1550
1550
  rows: "3"
1551
1551
  }, null, 8, ["id", "modelValue", "placeholder", "disabled", "maxlength"]),
1552
- createElementVNode("div", _hoisted_4$4, toDisplayString(characterCount.value) + "/" + toDisplayString(__props.maxFreeTextLength), 1)
1552
+ createElementVNode("div", _hoisted_4$5, toDisplayString(characterCount.value) + "/" + toDisplayString(__props.maxFreeTextLength), 1)
1553
1553
  ]),
1554
1554
  _: 1
1555
1555
  })
@@ -1611,7 +1611,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1611
1611
  const _hoisted_1$8 = ["aria-label"];
1612
1612
  const _hoisted_2$5 = ["onClick"];
1613
1613
  const _hoisted_3$4 = ["disabled", "aria-label"];
1614
- const _hoisted_4$3 = {
1614
+ const _hoisted_4$4 = {
1615
1615
  key: 3,
1616
1616
  class: "flex min-w-0 flex-1 flex-col items-start gap-0.5"
1617
1617
  };
@@ -1789,7 +1789,7 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
1789
1789
  !__props.showStatus ? (openBlock(), createElementBlock("span", {
1790
1790
  key: 2,
1791
1791
  class: normalizeClass(["min-w-0 flex-1 truncate text-content-on-surface-primary", __props.size === "small" ? "label-12-medium" : "body-14-medium"])
1792
- }, toDisplayString(resolvedTriggerLabel.value), 3)) : (openBlock(), createElementBlock("div", _hoisted_4$3, [
1792
+ }, toDisplayString(resolvedTriggerLabel.value), 3)) : (openBlock(), createElementBlock("div", _hoisted_4$4, [
1793
1793
  createElementVNode("span", {
1794
1794
  class: normalizeClass(["w-full truncate text-content-on-surface-primary", __props.size === "small" ? "label-12-medium" : "body-14-medium"])
1795
1795
  }, toDisplayString(resolvedTriggerLabel.value), 3),
@@ -1858,7 +1858,7 @@ const CHAT_HISTORY_ACTIVE_INDICATOR_CLASS = "ui-active-indicator";
1858
1858
  const _hoisted_1$7 = ["data-active"];
1859
1859
  const _hoisted_2$4 = { class: "min-w-0 flex-1" };
1860
1860
  const _hoisted_3$3 = { class: "truncate body-14-regular text-content-on-surface-primary" };
1861
- const _hoisted_4$2 = {
1861
+ const _hoisted_4$3 = {
1862
1862
  key: 0,
1863
1863
  class: "mt-0.5 flex min-w-0 items-center gap-1 label-12-medium text-content-on-surface-muted"
1864
1864
  };
@@ -2006,7 +2006,7 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
2006
2006
  default: withCtx(() => [
2007
2007
  createElementVNode("div", _hoisted_2$4, [
2008
2008
  createElementVNode("div", _hoisted_3$3, toDisplayString(props.title), 1),
2009
- props.metaStart || props.metaEnd || _ctx.$slots.meta ? (openBlock(), createElementBlock("div", _hoisted_4$2, [
2009
+ props.metaStart || props.metaEnd || _ctx.$slots.meta ? (openBlock(), createElementBlock("div", _hoisted_4$3, [
2010
2010
  renderSlot(_ctx.$slots, "meta", {}, () => [
2011
2011
  props.metaStart ? (openBlock(), createElementBlock("span", _hoisted_5$1, toDisplayString(props.metaStart), 1)) : createCommentVNode("", true),
2012
2012
  props.metaStart && props.metaEnd ? (openBlock(), createElementBlock("span", _hoisted_6$1, "|")) : createCommentVNode("", true),
@@ -2150,7 +2150,7 @@ const _sfc_main$d = /* @__PURE__ */ defineComponent({
2150
2150
  const _hoisted_1$6 = ["disabled", "aria-expanded", "aria-label"];
2151
2151
  const _hoisted_2$3 = { class: "min-w-0 max-w-[10rem] truncate" };
2152
2152
  const _hoisted_3$2 = ["aria-label"];
2153
- const _hoisted_4$1 = ["aria-selected", "onClick"];
2153
+ const _hoisted_4$2 = ["aria-selected", "onClick"];
2154
2154
  const _hoisted_5 = { class: "flex min-w-0 flex-1 flex-col" };
2155
2155
  const _hoisted_6 = { class: "min-w-0 truncate" };
2156
2156
  const _hoisted_7 = {
@@ -2255,7 +2255,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
2255
2255
  class: "absolute right-2 text-content-on-surface-primary",
2256
2256
  "aria-hidden": "true"
2257
2257
  })) : createCommentVNode("", true)
2258
- ], 8, _hoisted_4$1)
2258
+ ], 8, _hoisted_4$2)
2259
2259
  ]);
2260
2260
  }), 128))
2261
2261
  ], 8, _hoisted_3$2)
@@ -2356,7 +2356,7 @@ const _hoisted_2$2 = {
2356
2356
  style: { "grid-area": "top" }
2357
2357
  };
2358
2358
  const _hoisted_3$1 = ["for"];
2359
- const _hoisted_4 = ["id", "value", "placeholder", "disabled"];
2359
+ const _hoisted_4$1 = ["id", "value", "placeholder", "disabled"];
2360
2360
  const MAX_LINES = 6;
2361
2361
  const _sfc_main$8 = /* @__PURE__ */ defineComponent({
2362
2362
  ...{ name: "CkPromptInput" },
@@ -2492,7 +2492,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
2492
2492
  onPointerdown: onPointerDown,
2493
2493
  onFocus,
2494
2494
  onBlur
2495
- }, null, 42, _hoisted_4),
2495
+ }, null, 42, _hoisted_4$1),
2496
2496
  createElementVNode("div", {
2497
2497
  class: normalizeClass([!isMultiLine.value && "pl-4"]),
2498
2498
  style: { "grid-area": "right" }
@@ -2820,12 +2820,24 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
2820
2820
  }
2821
2821
  });
2822
2822
  const CkMilkdownEditor = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-d1a2a9cf"]]);
2823
+ let pending;
2824
+ function loadCodeMirror() {
2825
+ pending ??= import("./createCodeMirror-CN8xL8qU.js").catch((error) => {
2826
+ pending = void 0;
2827
+ throw error;
2828
+ });
2829
+ return pending;
2830
+ }
2831
+ function preloadCkCodeEditor() {
2832
+ loadCodeMirror().catch(() => void 0);
2833
+ }
2823
2834
  const _hoisted_1$1 = ["aria-disabled"];
2824
2835
  const _hoisted_2 = {
2825
2836
  key: 0,
2826
2837
  class: "bg-background-surface-muted-subtle flex h-9 items-center justify-between px-3"
2827
2838
  };
2828
2839
  const _hoisted_3 = { class: "text-content-on-surface-secondary label-12-regular" };
2840
+ const _hoisted_4 = ["value", "placeholder", "aria-label", "readonly", "disabled", "wrap"];
2829
2841
  const FADE_HEIGHT = "53px";
2830
2842
  const _sfc_main$2 = /* @__PURE__ */ defineComponent({
2831
2843
  ...{ name: "CkCodeEditor" },
@@ -2857,8 +2869,10 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
2857
2869
  const labels = useChatKitLabels();
2858
2870
  const rootRef = useTemplateRef("rootRef");
2859
2871
  const hostRef = useTemplateRef("hostRef");
2872
+ const fallbackRef = useTemplateRef("fallbackRef");
2860
2873
  const isLocked = computed(() => props.readonly || props.disabled);
2861
2874
  const isReady = ref(false);
2875
+ const isFallback = ref(false);
2862
2876
  const isCopied = ref(false);
2863
2877
  const headerLabel = computed(() => {
2864
2878
  const label = props.filename || props.language;
@@ -2913,16 +2927,13 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
2913
2927
  lastKnownCode = value;
2914
2928
  emit("update:modelValue", value);
2915
2929
  }
2916
- onMounted(async () => {
2917
- const parent = hostRef.value;
2918
- if (!parent) return;
2919
- const { createCodeMirror } = await import("./createCodeMirror-BO-TWTzn.js");
2930
+ async function mountEditor(parent) {
2931
+ const { createCodeMirror } = await loadCodeMirror();
2920
2932
  if (destroyed) return;
2921
- const initialCode = props.modelValue;
2922
- lastKnownCode = initialCode;
2923
- const handle = await createCodeMirror({
2933
+ lastKnownCode = props.modelValue;
2934
+ const handle = createCodeMirror({
2924
2935
  parent,
2925
- doc: initialCode,
2936
+ doc: props.modelValue,
2926
2937
  language: props.language,
2927
2938
  placeholder: props.placeholder,
2928
2939
  ariaLabel: props.ariaLabel,
@@ -2933,16 +2944,31 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
2933
2944
  onChange: handleChange,
2934
2945
  onFocus: () => emit("focus")
2935
2946
  });
2936
- if (destroyed) {
2937
- handle.destroy();
2938
- return;
2939
- }
2940
2947
  editor = handle;
2941
- if (props.modelValue !== initialCode) handle.setCode(props.modelValue);
2942
2948
  watchScrolling(handle.view.scrollDOM, handle.view.contentDOM);
2943
2949
  isReady.value = true;
2944
2950
  if (props.autofocus) handle.focus();
2951
+ }
2952
+ onMounted(async () => {
2953
+ const parent = hostRef.value;
2954
+ if (!parent) return;
2955
+ try {
2956
+ await mountEditor(parent);
2957
+ } catch (error) {
2958
+ console.error("[CkCodeEditor] Falling back to a plain textarea:", error);
2959
+ if (destroyed) return;
2960
+ editor?.destroy();
2961
+ editor = void 0;
2962
+ isFallback.value = true;
2963
+ if (props.autofocus) {
2964
+ await nextTick();
2965
+ fallbackRef.value?.focus();
2966
+ }
2967
+ }
2945
2968
  });
2969
+ function onFallbackInput(event) {
2970
+ handleChange(event.target.value);
2971
+ }
2946
2972
  watch(
2947
2973
  () => props.modelValue,
2948
2974
  (next) => {
@@ -3001,7 +3027,8 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3001
3027
  if (!isInsideRoot(event.relatedTarget)) emit("blur");
3002
3028
  }
3003
3029
  function focus() {
3004
- editor?.focus();
3030
+ if (editor) editor.focus();
3031
+ else fallbackRef.value?.focus();
3005
3032
  }
3006
3033
  function getCode() {
3007
3034
  return editor?.getCode() ?? props.modelValue;
@@ -3014,6 +3041,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3014
3041
  class: normalizeClass([
3015
3042
  "ck-code-editor ck-code-surface border-border-surface-default bg-background-input-default min-w-0 overflow-hidden rounded-xl border",
3016
3043
  isReady.value && "ck-code-editor--ready",
3044
+ isFallback.value && "ck-code-editor--fallback",
3017
3045
  isLocked.value && "ck-code-editor--readonly",
3018
3046
  __props.disabled && "ck-code-editor--disabled"
3019
3047
  ]),
@@ -3045,7 +3073,23 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3045
3073
  ref: hostRef,
3046
3074
  class: "ck-code-editor__host",
3047
3075
  style: normalizeStyle(__props.maxHeight ? { "--ck-code-max-height": __props.maxHeight } : void 0)
3048
- }, null, 4)
3076
+ }, [
3077
+ isFallback.value ? (openBlock(), createElementBlock("textarea", {
3078
+ key: 0,
3079
+ ref_key: "fallbackRef",
3080
+ ref: fallbackRef,
3081
+ class: "ck-code-editor__fallback",
3082
+ value: __props.modelValue,
3083
+ placeholder: __props.placeholder,
3084
+ "aria-label": __props.ariaLabel,
3085
+ readonly: __props.readonly,
3086
+ disabled: __props.disabled,
3087
+ wrap: __props.lineWrapping ? "soft" : "off",
3088
+ spellcheck: "false",
3089
+ onInput: onFallbackInput,
3090
+ onFocus: _cache[0] || (_cache[0] = ($event) => emit("focus"))
3091
+ }, null, 40, _hoisted_4)) : createCommentVNode("", true)
3092
+ ], 4)
3049
3093
  ]),
3050
3094
  _: 1
3051
3095
  }, 16))
@@ -3053,7 +3097,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3053
3097
  };
3054
3098
  }
3055
3099
  });
3056
- const CkCodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-6dfa80b5"]]);
3100
+ const CkCodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-c589384b"]]);
3057
3101
  const _hoisted_1 = {
3058
3102
  key: 1,
3059
3103
  class: "flex size-8 shrink-0 items-center justify-center rounded-2xl bg-background-surface-muted-subtle"
@@ -3391,7 +3435,8 @@ export {
3391
3435
  _sfc_main$v as B,
3392
3436
  CkCitationLabel as C,
3393
3437
  CkUserMessage as D,
3394
- formatRelativeTime as E,
3438
+ preloadCkCodeEditor as E,
3439
+ formatRelativeTime as F,
3395
3440
  _sfc_main$u as _,
3396
3441
  _sfc_main$t as a,
3397
3442
  _sfc_main$p as b,
package/dist/chat-kit.css CHANGED
@@ -176,7 +176,7 @@
176
176
  * `helpers/codemirror/code-palette.css`). The overrides live here, not in
177
177
  * `theme.ts`, because `CkMilkdownEditor`'s code blocks use that theme too and
178
178
  * must keep matching the rendered block. */
179
- .ck-code-editor[data-v-6dfa80b5] {
179
+ .ck-code-editor[data-v-c589384b] {
180
180
  /* `theme.ts` paints the editor from these; transparent lets the root's
181
181
  * input surface show through. */
182
182
  --ck-cm-bg: transparent;
@@ -186,7 +186,7 @@
186
186
 
187
187
  /* `:deep` is needed below because CodeMirror builds its own DOM, which scoped
188
188
  * styles do not reach. Same declarations as the `body-14-regular` typography utility. */
189
- .ck-code-editor__host[data-v-6dfa80b5] .cm-scroller {
189
+ .ck-code-editor__host[data-v-c589384b] .cm-scroller {
190
190
  max-height: var(--ck-code-max-height, none);
191
191
  font-family: Saans, sans-serif;
192
192
  font-size: 0.875rem;
@@ -196,20 +196,20 @@
196
196
 
197
197
  /* 12px below the header, 16px above the bottom edge, and a 20px right inset,
198
198
  * as in the design. */
199
- .ck-code-editor__host[data-v-6dfa80b5] .cm-content {
199
+ .ck-code-editor__host[data-v-c589384b] .cm-content {
200
200
  padding: 0.75rem 1.25rem 1rem 1rem;
201
201
  }
202
202
 
203
203
  /* The number column already carries the 1rem left inset, so the code must not
204
204
  * pay for it a second time. The sibling selector only matches while the gutter
205
205
  * is mounted, which is exactly when `showLineNumbers` is on. */
206
- .ck-code-editor__host[data-v-6dfa80b5] .cm-gutters ~ .cm-content {
206
+ .ck-code-editor__host[data-v-c589384b] .cm-gutters ~ .cm-content {
207
207
  padding-left: 0;
208
208
  }
209
209
 
210
210
  /* Numbers stay monospaced so the column does not jitter as digits change; the
211
211
  * 12px right padding is the gap before the code. */
212
- .ck-code-editor__host[data-v-6dfa80b5] .cm-lineNumbers .cm-gutterElement {
212
+ .ck-code-editor__host[data-v-c589384b] .cm-lineNumbers .cm-gutterElement {
213
213
  min-width: 0;
214
214
  padding: 0 0.75rem 0 1rem;
215
215
  /* `CODE_FONT_FAMILY` from `theme.ts`, repeated because importing it here
@@ -219,7 +219,38 @@
219
219
  monospace;
220
220
  font-weight: 500;
221
221
  }
222
- .ck-code-editor__host[data-v-6dfa80b5] .cm-placeholder {
222
+
223
+ /* A column so the stand-in below grows into a host a consumer has stretched
224
+ * (as a fixed-height dialog does), rather than sitting at its minimum height
225
+ * at the top of an empty panel. */
226
+ .ck-code-editor--fallback .ck-code-editor__host[data-v-c589384b] {
227
+ display: flex;
228
+ flex-direction: column;
229
+ }
230
+
231
+ /* Stand-in for when CodeMirror fails to load: same text metrics and insets as
232
+ * the editor without a gutter, so the field reads as the same surface. Where
233
+ * supported, it grows with its content the way the editor does. */
234
+ .ck-code-editor__fallback[data-v-c589384b] {
235
+ display: block;
236
+ flex: 1 1 auto;
237
+ width: 100%;
238
+ min-height: 5rem;
239
+ field-sizing: content;
240
+ max-height: var(--ck-code-max-height, none);
241
+ resize: none;
242
+ border: 0;
243
+ outline: none;
244
+ padding: 0.75rem 1.25rem 1rem 1rem;
245
+ background: var(--ck-cm-bg);
246
+ color: var(--ck-cm-foreground);
247
+ font-family: Saans, sans-serif;
248
+ font-size: 0.875rem;
249
+ font-weight: 400;
250
+ line-height: 1.25rem;
251
+ }
252
+ .ck-code-editor__fallback[data-v-c589384b]::placeholder,
253
+ .ck-code-editor__host[data-v-c589384b] .cm-placeholder {
223
254
  color: oklch(var(--content-on-surface-muted));
224
255
  }
225
256
 
@@ -228,24 +259,24 @@
228
259
  * both and only knows `primary` and `secondary`. The gradient, edges and band
229
260
  * height stay the mask's own. `[data-background]` outranks the mask's
230
261
  * per-surface rule regardless of stylesheet order. */
231
- .ck-code-editor__body[data-v-6dfa80b5]
262
+ .ck-code-editor__body[data-v-c589384b]
232
263
  .ui-fade-mask__band[data-background][data-position='top'] {
233
264
  --ui-fade-mask-surface: var(--ck-code-fade-top);
234
265
  /* The mask turns its top band opaque halfway down on desktop, which left a
235
266
  * solid strip under the header; mirror the bottom band's stops instead. */
236
267
  --ui-fade-mask-stop: 20%;
237
268
  }
238
- .ck-code-editor__body[data-v-6dfa80b5]
269
+ .ck-code-editor__body[data-v-c589384b]
239
270
  .ui-fade-mask__band[data-background][data-position='bottom'] {
240
271
  --ui-fade-mask-surface: var(--ck-code-fade-bottom);
241
272
  }
242
273
  @media (min-width: 768px) {
243
- .ck-code-editor__body[data-v-6dfa80b5]
274
+ .ck-code-editor__body[data-v-c589384b]
244
275
  .ui-fade-mask__band[data-background][data-position='top'] {
245
276
  --ui-fade-mask-stop: 100%;
246
277
  }
247
278
  }
248
- .ck-code-editor--disabled[data-v-6dfa80b5] {
279
+ .ck-code-editor--disabled[data-v-c589384b] {
249
280
  opacity: 0.6;
250
281
  cursor: not-allowed;
251
282
  pointer-events: none;
@@ -1 +1 @@
1
- {"version":3,"file":"CkCodeEditor.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkCodeEditor/CkCodeEditor.vue"],"names":[],"mappings":"AA4YA,OAAO,KAAK,EAAqB,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAqOpE,iBAAS,KAAK,IAAI,IAAI,CAErB;AAED,iBAAS,OAAO,IAAI,MAAM,CAEzB;AAmLD,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6EAKhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"CkCodeEditor.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkCodeEditor/CkCodeEditor.vue"],"names":[],"mappings":"AAkdA,OAAO,KAAK,EAAqB,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAyPpE,iBAAS,KAAK,IAAI,IAAI,CAGrB;AAED,iBAAS,OAAO,IAAI,MAAM,CAEzB;AAiND,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6EAKhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -57,6 +57,10 @@ export declare function detectLineSeparator(doc: string): string;
57
57
  /**
58
58
  * Build a CodeMirror view themed like `UiCodeBlock`. Loaded lazily by
59
59
  * `CkCodeEditor` so CodeMirror stays out of the package's main chunk.
60
+ *
61
+ * The view is built at once, as plain text, and the grammar is applied when it
62
+ * arrives: the placeholder, gutter and content must not wait on a network
63
+ * request that may be slow or never finish. Only the syntax colours do.
60
64
  */
61
- export declare function createCodeMirror(options: CreateCodeMirrorOptions): Promise<CodeMirrorHandle>;
65
+ export declare function createCodeMirror(options: CreateCodeMirrorOptions): CodeMirrorHandle;
62
66
  //# sourceMappingURL=createCodeMirror.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createCodeMirror.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkCodeEditor/createCodeMirror.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,UAAU,EAOX,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,8CAA8C,CAAC;AAEtD,MAAM,WAAW,uBAAuB;IACtC,wCAAwC;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,0DAA0D;IAC1D,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;OAIG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,0EAA0E;IAC1E,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,kBAAkB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,QAAQ,EAAE,CAAC,IAAI,EAAE,qBAAqB,GAAG,SAAS,KAAK,IAAI,CAAC;IAC5D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAKD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAkBjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKvD;AAyCD;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CA6E3B"}
1
+ {"version":3,"file":"createCodeMirror.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkCodeEditor/createCodeMirror.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,UAAU,EAOX,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,8CAA8C,CAAC;AAEtD,MAAM,WAAW,uBAAuB;IACtC,wCAAwC;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,0DAA0D;IAC1D,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;OAIG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,0EAA0E;IAC1E,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,kBAAkB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,QAAQ,EAAE,CAAC,IAAI,EAAE,qBAAqB,GAAG,SAAS,KAAK,IAAI,CAAC;IAC5D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAKD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAkBjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKvD;AAyCD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,uBAAuB,GAC/B,gBAAgB,CA8FlB"}
@@ -1,3 +1,4 @@
1
1
  export { default as CkCodeEditor } from './CkCodeEditor.vue';
2
+ export { preloadCkCodeEditor } from './loadCodeMirror';
2
3
  export type * from './types';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkCodeEditor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,mBAAmB,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkCodeEditor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,mBAAmB,SAAS,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type * as CodeMirrorModule from './createCodeMirror';
2
+ /**
3
+ * Import the CodeMirror chunk once and share the result.
4
+ *
5
+ * A failed import is forgotten rather than cached, so the next editor to mount
6
+ * (or the next `preloadCkCodeEditor` call) tries again instead of inheriting the
7
+ * failure.
8
+ */
9
+ export declare function loadCodeMirror(): Promise<typeof CodeMirrorModule>;
10
+ /**
11
+ * Start fetching `CkCodeEditor`'s CodeMirror chunk ahead of time, for example
12
+ * when a view that will open an editor is shown. The editor then appears
13
+ * without waiting on the network. Safe to call repeatedly; failures are
14
+ * swallowed here and surface, if still failing, when an editor mounts.
15
+ */
16
+ export declare function preloadCkCodeEditor(): void;
17
+ //# sourceMappingURL=loadCodeMirror.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadCodeMirror.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkCodeEditor/loadCodeMirror.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,gBAAgB,MAAM,oBAAoB,CAAC;AAI5D;;;;;;GAMG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAAC,OAAO,gBAAgB,CAAC,CAMjE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -43,6 +43,6 @@ export { CkEditableUserMessage } from './CkEditableUserMessage';
43
43
  export type { CkEditableUserMessageEmits, CkEditableUserMessageProps, } from './CkEditableUserMessage';
44
44
  export { CkMilkdownEditor } from './CkMilkdownEditor';
45
45
  export type { CkMilkdownEditorEmits, CkMilkdownEditorExposed, CkMilkdownEditorProps, } from './CkMilkdownEditor';
46
- export { CkCodeEditor } from './CkCodeEditor';
46
+ export { CkCodeEditor, preloadCkCodeEditor } from './CkCodeEditor';
47
47
  export type { CkCodeEditorEmits, CkCodeEditorExposed, CkCodeEditorFadeSurface, CkCodeEditorProps, } from './CkCodeEditor';
48
48
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/base/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/base/index.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export { CkAgentMessage, CkAgentMessageHeader, CkHeaderActivityButton, CkCitation, CkCitationLabel, CkCitationCard, CkConversationLayout, CkCopyMessageButton, CkDropZoneOverlay, CkFeedbackButton, CkFeedbackDialog, CkFileItemsList, CkHistoryItem, CkHistoryWrapper, CkMarkdownRenderer, CkMessageButton, CkModelSelector, CkPromptSendButton, CkPromptMenuButton, CkPromptStopButton, CkPromptInput, CkPromptInputDisclaimer, CkRegenerateMessageButton, CkSendIcon, CkStopIcon, CkUserMessage, CkEditableUserMessage, CkMilkdownEditor, CkCodeEditor, } from './base';
1
+ export { CkAgentMessage, CkAgentMessageHeader, CkHeaderActivityButton, CkCitation, CkCitationLabel, CkCitationCard, CkConversationLayout, CkCopyMessageButton, CkDropZoneOverlay, CkFeedbackButton, CkFeedbackDialog, CkFileItemsList, CkHistoryItem, CkHistoryWrapper, CkMarkdownRenderer, CkMessageButton, CkModelSelector, CkPromptSendButton, CkPromptMenuButton, CkPromptStopButton, CkPromptInput, CkPromptInputDisclaimer, CkRegenerateMessageButton, CkSendIcon, CkStopIcon, CkUserMessage, CkEditableUserMessage, CkMilkdownEditor, CkCodeEditor, preloadCkCodeEditor, } from './base';
2
2
  export type { CkAgentMessageHeaderProps, CkHeaderActivityButtonProps, CkHeaderActivityButtonEmits, CkCitationProps, CkCitationEmits, CkCitationSource, CkCitationLabelProps, CkCitationCardProps, CkCitationCardEmits, CkConversationLayoutProps, CkDropZoneOverlayProps, CkDropZoneOverlayEmits, CkDropZoneRejection, CkDropZoneRejectionReason, CkFeedbackButtonProps, CkFeedbackDialogEmits, CkFeedbackDialogProps, CkFeedbackDialogSubmitPayload, CkFeedbackReason, CkFeedbackSentiment, CkFeedbackValue, CkFileEntry, CkFileItemsListEmits, CkFileItemsListProps, CkHistoryItemEmits, CkHistoryItemProps, CkHistoryWrapperProps, CkMarkdownElementClasses, CkMarkdownRendererProps, CkMarkdownRendererEmits, CkModelOption, CkModelSelectorProps, CkModelSelectorEmits, CkPromptMenuButtonProps, CkUserMessageProps, CkEditableUserMessageProps, CkEditableUserMessageEmits, CkMilkdownEditorEmits, CkMilkdownEditorExposed, CkMilkdownEditorProps, CkCodeEditorEmits, CkCodeEditorExposed, CkCodeEditorFadeSurface, CkCodeEditorProps, } from './base';
3
3
  export { CkConversation, CkHistory } from './composed';
4
4
  export type { CkConversationProps, CkHistoryEmits, CkHistoryProps, } from './composed';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,yBAAyB,EACzB,UAAU,EACV,UAAU,EACV,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,GACb,MAAM,QAAQ,CAAC;AAChB,YAAY,EACV,yBAAyB,EACzB,2BAA2B,EAC3B,2BAA2B,EAC3B,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,6BAA6B,EAC7B,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,0BAA0B,EAC1B,0BAA0B,EAC1B,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvD,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,yBAAyB,EACzB,UAAU,EACV,UAAU,EACV,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,GACpB,MAAM,QAAQ,CAAC;AAChB,YAAY,EACV,yBAAyB,EACzB,2BAA2B,EAC3B,2BAA2B,EAC3B,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,6BAA6B,EAC7B,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,0BAA0B,EAC1B,0BAA0B,EAC1B,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvD,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAC"}
@@ -1,4 +1,4 @@
1
- import { _, a, b, c, C, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, D } from "../CkHistory.vue_vue_type_script_setup_true_lang-wu1Zrvgc.js";
1
+ import { _, a, b, c, C, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, D, E } from "../CkHistory.vue_vue_type_script_setup_true_lang-Bv3FuKT4.js";
2
2
  export {
3
3
  _ as CkAgentMessage,
4
4
  a as CkAgentMessageHeader,
@@ -30,5 +30,6 @@ export {
30
30
  z as CkRegenerateMessageButton,
31
31
  A as CkSendIcon,
32
32
  B as CkStopIcon,
33
- D as CkUserMessage
33
+ D as CkUserMessage,
34
+ E as preloadCkCodeEditor
34
35
  };
@@ -114,22 +114,22 @@ function baseExtensions(options) {
114
114
  ...options.placeholder ? [placeholder(options.placeholder)] : []
115
115
  ];
116
116
  }
117
- async function createCodeMirror(options) {
117
+ function createCodeMirror(options) {
118
118
  const languageSlot = new Compartment();
119
119
  const readonlySlot = new Compartment();
120
120
  const lineNumbersSlot = new Compartment();
121
121
  const wrappingSlot = new Compartment();
122
122
  const badgeSlot = new Compartment();
123
123
  const lineSeparatorSlot = new Compartment();
124
- const support = await resolveLanguage(options.language);
125
124
  let languageRequestId = 0;
125
+ let destroyed = false;
126
126
  const view = new EditorView({
127
127
  parent: options.parent,
128
128
  state: EditorState.create({
129
129
  doc: options.doc,
130
130
  extensions: [
131
131
  ...baseExtensions(options),
132
- languageSlot.of(support ? [support] : []),
132
+ languageSlot.of([]),
133
133
  readonlySlot.of(readonlyState(options.readonly)),
134
134
  lineNumbersSlot.of(options.showLineNumbers ? lineNumbers() : []),
135
135
  wrappingSlot.of(options.lineWrapping ? EditorView.lineWrapping : []),
@@ -141,8 +141,20 @@ async function createCodeMirror(options) {
141
141
  })
142
142
  });
143
143
  function reconfigure(slot, extension) {
144
+ if (destroyed) return;
144
145
  view.dispatch({ effects: slot.reconfigure(extension) });
145
146
  }
147
+ async function setLanguage(language) {
148
+ const request = ++languageRequestId;
149
+ const next = await resolveLanguage(language);
150
+ if (request !== languageRequestId) return;
151
+ try {
152
+ reconfigure(languageSlot, next ? [next] : []);
153
+ } catch (error) {
154
+ console.warn(`[CkCodeEditor] Could not apply "${language}":`, error);
155
+ }
156
+ }
157
+ setLanguage(options.language).catch(() => void 0);
146
158
  return {
147
159
  view,
148
160
  getCode: () => readDoc(view.state),
@@ -158,12 +170,7 @@ async function createCodeMirror(options) {
158
170
  selection: { anchor: cursor }
159
171
  });
160
172
  },
161
- setLanguage: async (language) => {
162
- const request = ++languageRequestId;
163
- const next = await resolveLanguage(language);
164
- if (request !== languageRequestId) return;
165
- reconfigure(languageSlot, next ? [next] : []);
166
- },
173
+ setLanguage,
167
174
  setReadonly: (readonly) => {
168
175
  reconfigure(readonlySlot, readonlyState(readonly));
169
176
  },
@@ -177,7 +184,10 @@ async function createCodeMirror(options) {
177
184
  reconfigure(badgeSlot, rule ? badgeExtension(rule) : []);
178
185
  },
179
186
  focus: () => view.focus(),
180
- destroy: () => view.destroy()
187
+ destroy: () => {
188
+ destroyed = true;
189
+ view.destroy();
190
+ }
181
191
  };
182
192
  }
183
193
  export {
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export { useChat, useConversationSessions, useConversations, } from './composabl
6
6
  export type { ChatActions, ChatState, ConversationSession, CreateConversationInput, MessageHandler, MutationOptions, UseChatReturn, UseConversationSessionsReturn, UseConversationsOptions, UseConversationsReturn, } from './composables';
7
7
  export { SdkError, createDocumentUploadProvider, defaultDocumentUploadConfig, defaultEndpoints, useDocumentUploadWithDefaultConfig, } from './composables/fileUpload';
8
8
  export type { DocumentUploadConfig, DocumentUploadProvider, FileEntry, FileStatus, } from './composables/fileUpload';
9
- export { CkAgentMessage, CkAgentMessageHeader, CkHeaderActivityButton, CkCitation, CkCitationLabel, CkCitationCard, CkConversation, CkConversationLayout, CkCopyMessageButton, CkDropZoneOverlay, CkFeedbackButton, CkFeedbackDialog, CkFileItemsList, CkHistory, CkHistoryItem, CkHistoryWrapper, CkMarkdownRenderer, CkMessageButton, CkModelSelector, CkPromptSendButton, CkPromptMenuButton, CkPromptStopButton, CkPromptInput, CkPromptInputDisclaimer, CkRegenerateMessageButton, CkSendIcon, CkStopIcon, CkUserMessage, CkEditableUserMessage, CkMilkdownEditor, CkCodeEditor, } from './components';
9
+ export { CkAgentMessage, CkAgentMessageHeader, CkHeaderActivityButton, CkCitation, CkCitationLabel, CkCitationCard, CkConversation, CkConversationLayout, CkCopyMessageButton, CkDropZoneOverlay, CkFeedbackButton, CkFeedbackDialog, CkFileItemsList, CkHistory, CkHistoryItem, CkHistoryWrapper, CkMarkdownRenderer, CkMessageButton, CkModelSelector, CkPromptSendButton, CkPromptMenuButton, CkPromptStopButton, CkPromptInput, CkPromptInputDisclaimer, CkRegenerateMessageButton, CkSendIcon, CkStopIcon, CkUserMessage, CkEditableUserMessage, CkMilkdownEditor, CkCodeEditor, preloadCkCodeEditor, } from './components';
10
10
  export type { CkAgentMessageHeaderProps, CkHeaderActivityButtonProps, CkHeaderActivityButtonEmits, CkCitationProps, CkCitationEmits, CkCitationSource, CkCitationLabelProps, CkCitationCardProps, CkCitationCardEmits, CkConversationLayoutProps, CkConversationProps, CkDropZoneOverlayProps, CkDropZoneOverlayEmits, CkDropZoneRejection, CkDropZoneRejectionReason, CkFeedbackButtonProps, CkFeedbackDialogEmits, CkFeedbackDialogProps, CkFeedbackDialogSubmitPayload, CkFeedbackReason, CkFeedbackSentiment, CkFeedbackValue, CkFileEntry, CkFileItemsListEmits, CkFileItemsListProps, CkHistoryEmits, CkHistoryItemEmits, CkHistoryItemProps, CkHistoryProps, CkHistoryWrapperProps, CkMarkdownElementClasses, CkMarkdownRendererProps, CkMarkdownRendererEmits, CkModelOption, CkModelSelectorProps, CkModelSelectorEmits, CkPromptMenuButtonProps, CkUserMessageProps, CkEditableUserMessageProps, CkEditableUserMessageEmits, CkMilkdownEditorEmits, CkMilkdownEditorExposed, CkMilkdownEditorProps, CkCodeEditorEmits, CkCodeEditorExposed, CkCodeEditorFadeSurface, CkCodeEditorProps, } from './components';
11
11
  export { formatRelativeTime, markdownToPlainText } from './helpers';
12
12
  export type { ActiveComparison, BaseMessage, ComparisonLane, Conversation, ConversationTree, MessageContent, MessageContentStatus, MessageMetadata, MessageReasoningContent, MessageRole, MessageStatus, MessageTextContent, MessageToolContent, TreeMessage, } from './types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,iBAAiB,CAAC;AAGzB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AASpB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EACL,OAAO,EACP,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,aAAa,EACb,6BAA6B,EAC7B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,QAAQ,EACR,4BAA4B,EAC5B,2BAA2B,EAC3B,gBAAgB,EAChB,kCAAkC,GACnC,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,UAAU,GACX,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,yBAAyB,EACzB,UAAU,EACV,UAAU,EACV,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,GACb,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,yBAAyB,EACzB,2BAA2B,EAC3B,2BAA2B,EAC3B,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,6BAA6B,EAC7B,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,0BAA0B,EAC1B,0BAA0B,EAC1B,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGpE,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,GACZ,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,iBAAiB,CAAC;AAGzB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AASpB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EACL,OAAO,EACP,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,aAAa,EACb,6BAA6B,EAC7B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,QAAQ,EACR,4BAA4B,EAC5B,2BAA2B,EAC3B,gBAAgB,EAChB,kCAAkC,GACnC,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,UAAU,GACX,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,yBAAyB,EACzB,UAAU,EACV,UAAU,EACV,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,yBAAyB,EACzB,2BAA2B,EAC3B,2BAA2B,EAC3B,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,6BAA6B,EAC7B,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,0BAA0B,EAC1B,0BAA0B,EAC1B,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGpE,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,GACZ,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { u } from "./useMessageHandler-Bkzrdgfj.js";
2
2
  import { C, d, p, u as u2, b } from "./useChatKitLabels-DxW0N5U-.js";
3
3
  import { S, c, d as d2, f, u as u3, a, b as b2, e } from "./index-D0DQjdsq.js";
4
- import { _, a as a2, b as b3, c as c2, C as C2, d as d3, e as e2, f as f2, g, h, i, j, k, l, m, n, o, p as p2, q, r, s, t, u as u4, v, w, x, y, z, A, B, D, E } from "./CkHistory.vue_vue_type_script_setup_true_lang-wu1Zrvgc.js";
4
+ import { _, a as a2, b as b3, c as c2, C as C2, d as d3, e as e2, f as f2, g, h, i, j, k, l, m, n, o, p as p2, q, r, s, t, u as u4, v, w, x, y, z, A, B, D, F, E } from "./CkHistory.vue_vue_type_script_setup_true_lang-Bv3FuKT4.js";
5
5
  import { m as m2 } from "./markdownToPlainText-DN_G-I6g.js";
6
6
  export {
7
7
  C as CHAT_KIT_LABELS,
@@ -41,8 +41,9 @@ export {
41
41
  d as defaultChatKitLabels,
42
42
  d2 as defaultDocumentUploadConfig,
43
43
  f as defaultEndpoints,
44
- E as formatRelativeTime,
44
+ F as formatRelativeTime,
45
45
  m2 as markdownToPlainText,
46
+ E as preloadCkCodeEditor,
46
47
  p as provideChatKitLabels,
47
48
  u3 as useChat,
48
49
  u2 as useChatKitLabels,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aleph-alpha/chat-kit",
3
- "version": "6.4.2",
3
+ "version": "6.4.3",
4
4
  "description": "Chat kit package for building chat interfaces with Vue",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -115,8 +115,8 @@
115
115
  "vue": "^3.5.27",
116
116
  "vue-tsc": "^3.2.4",
117
117
  "wait-on": "9.0.3",
118
- "@aleph-alpha/eslint-config-frontend": "0.7.1",
119
118
  "@aleph-alpha/prettier-config-frontend": "2.1.1",
119
+ "@aleph-alpha/eslint-config-frontend": "0.7.1",
120
120
  "@aleph-alpha/tsconfig-frontend": "0.7.3"
121
121
  },
122
122
  "scripts": {
@@ -1,8 +1,17 @@
1
1
  import { render, screen, waitFor } from '@testing-library/vue';
2
2
  import userEvent from '@testing-library/user-event';
3
+ import type { MockInstance } from 'vitest';
3
4
  import CkCodeEditor from './CkCodeEditor.vue';
4
5
  import { detectLineSeparator, resolveLanguage } from './createCodeMirror';
5
6
  import { matchBadgeRanges } from './badgeDecoration';
7
+ import { loadCodeMirror } from './loadCodeMirror';
8
+
9
+ // Wrapped so a test can make the lazy chunk fail; every other test gets the
10
+ // real module.
11
+ vi.mock('./loadCodeMirror', async (importOriginal) => {
12
+ const actual = await importOriginal<typeof import('./loadCodeMirror')>();
13
+ return { ...actual, loadCodeMirror: vi.fn(actual.loadCodeMirror) };
14
+ });
6
15
 
7
16
  // CodeMirror measures its own layout on construction; jsdom has none of the
8
17
  // geometry APIs it calls. The stubs stay in this spec rather than the global
@@ -353,6 +362,68 @@ describe('CkCodeEditor', () => {
353
362
  const late = await renderEditor({ modelValue: 'y' });
354
363
  expect(() => late.unmount()).not.toThrow();
355
364
  });
365
+
366
+ describe('when CodeMirror fails to load', () => {
367
+ let logError: MockInstance;
368
+
369
+ beforeEach(() => {
370
+ vi.mocked(loadCodeMirror).mockRejectedValueOnce(
371
+ new Error('Failed to fetch dynamically imported module'),
372
+ );
373
+ logError = vi
374
+ .spyOn(globalThis.console, 'error')
375
+ .mockImplementation(() => undefined);
376
+ });
377
+
378
+ afterEach(() => {
379
+ logError.mockRestore();
380
+ });
381
+
382
+ async function renderFallback(
383
+ props: InstanceType<typeof CkCodeEditor>['$props'] = {},
384
+ ) {
385
+ const utils = render(CkCodeEditor, { props });
386
+ const textarea = await waitFor(() => {
387
+ const found = utils.container.querySelector(
388
+ '.ck-code-editor--fallback textarea',
389
+ );
390
+ expect(found).toBeInTheDocument();
391
+ return found as HTMLTextAreaElement;
392
+ });
393
+ return { ...utils, textarea };
394
+ }
395
+
396
+ it('falls back to a textarea with the value, placeholder and label', async () => {
397
+ const { textarea } = await renderFallback({
398
+ modelValue: 'body',
399
+ placeholder: 'Write the skill',
400
+ ariaLabel: 'Skill body',
401
+ });
402
+
403
+ expect(textarea.value).toBe('body');
404
+ expect(textarea.placeholder).toBe('Write the skill');
405
+ expect(textarea.getAttribute('aria-label')).toBe('Skill body');
406
+ expect(logError).toHaveBeenCalled();
407
+ });
408
+
409
+ it('keeps v-model working through the textarea', async () => {
410
+ const { textarea, emitted } = await renderFallback({ modelValue: '' });
411
+
412
+ await userEvent.type(textarea, 'hi');
413
+
414
+ const updates = emitted()['update:modelValue'] as string[][];
415
+ expect(updates.at(-1)?.[0]).toBe('hi');
416
+ });
417
+
418
+ it('locks the textarea when readonly', async () => {
419
+ const { textarea } = await renderFallback({
420
+ modelValue: 'x',
421
+ readonly: true,
422
+ });
423
+
424
+ expect(textarea.readOnly).toBe(true);
425
+ });
426
+ });
356
427
  });
357
428
 
358
429
  describe('resolveLanguage', () => {
@@ -11,6 +11,7 @@ import {
11
11
  import { UiButton, UiFadeMask, UiIcon } from '@aleph-alpha/ui-library';
12
12
  import { useChatKitLabels } from '../../../handlers/useChatKitLabels';
13
13
  import type { CodeMirrorHandle } from './createCodeMirror';
14
+ import { loadCodeMirror } from './loadCodeMirror';
14
15
  import type { CkCodeEditorEmits, CkCodeEditorProps } from './types';
15
16
 
16
17
  defineOptions({ name: 'CkCodeEditor' });
@@ -41,8 +42,12 @@ const emit = defineEmits<CkCodeEditorEmits>();
41
42
  const labels = useChatKitLabels();
42
43
  const rootRef = useTemplateRef<HTMLDivElement>('rootRef');
43
44
  const hostRef = useTemplateRef<HTMLDivElement>('hostRef');
45
+ const fallbackRef = useTemplateRef<HTMLTextAreaElement>('fallbackRef');
44
46
  const isLocked = computed(() => props.readonly || props.disabled);
45
47
  const isReady = ref(false);
48
+ // CodeMirror could not be loaded or built; a plain textarea stands in so the
49
+ // field can still be typed into.
50
+ const isFallback = ref(false);
46
51
  const isCopied = ref(false);
47
52
 
48
53
  // `UiCodeBlock` labels the block with the filename when there is one and hides
@@ -130,19 +135,16 @@ function handleChange(value: string): void {
130
135
  emit('update:modelValue', value);
131
136
  }
132
137
 
133
- onMounted(async () => {
134
- const parent = hostRef.value;
135
- if (!parent) return;
136
-
137
- // Lazy: CodeMirror and its grammars load only once an editor is shown.
138
- const { createCodeMirror } = await import('./createCodeMirror');
138
+ async function mountEditor(parent: HTMLElement): Promise<void> {
139
+ // Lazy: CodeMirror loads only once an editor is shown. The grammar follows in
140
+ // the background, so a slow one delays the colours, not the editor.
141
+ const { createCodeMirror } = await loadCodeMirror();
139
142
  if (destroyed) return;
140
143
 
141
- const initialCode = props.modelValue;
142
- lastKnownCode = initialCode;
143
- const handle = await createCodeMirror({
144
+ lastKnownCode = props.modelValue;
145
+ const handle = createCodeMirror({
144
146
  parent,
145
- doc: initialCode,
147
+ doc: props.modelValue,
146
148
  language: props.language,
147
149
  placeholder: props.placeholder,
148
150
  ariaLabel: props.ariaLabel,
@@ -154,20 +156,39 @@ onMounted(async () => {
154
156
  onFocus: () => emit('focus'),
155
157
  });
156
158
 
157
- // Unmounted while the grammar was loading.
158
- if (destroyed) {
159
- handle.destroy();
160
- return;
161
- }
162
-
163
159
  editor = handle;
164
- // Props may have moved on while the grammar loaded; catch up.
165
- if (props.modelValue !== initialCode) handle.setCode(props.modelValue);
166
160
  watchScrolling(handle.view.scrollDOM, handle.view.contentDOM);
167
161
  isReady.value = true;
168
162
  if (props.autofocus) handle.focus();
163
+ }
164
+
165
+ onMounted(async () => {
166
+ const parent = hostRef.value;
167
+ if (!parent) return;
168
+
169
+ try {
170
+ await mountEditor(parent);
171
+ } catch (error) {
172
+ // A stale or unreachable chunk, or a CodeMirror setup error such as
173
+ // duplicate `@codemirror/state` copies. Left alone, the header would sit
174
+ // over an empty body with no way to type.
175
+ // eslint-disable-next-line no-console
176
+ console.error('[CkCodeEditor] Falling back to a plain textarea:', error);
177
+ if (destroyed) return;
178
+ editor?.destroy();
179
+ editor = undefined;
180
+ isFallback.value = true;
181
+ if (props.autofocus) {
182
+ await nextTick();
183
+ fallbackRef.value?.focus();
184
+ }
185
+ }
169
186
  });
170
187
 
188
+ function onFallbackInput(event: Event): void {
189
+ handleChange((event.target as HTMLTextAreaElement).value);
190
+ }
191
+
171
192
  watch(
172
193
  () => props.modelValue,
173
194
  (next) => {
@@ -239,7 +260,8 @@ function onFocusOut(event: FocusEvent): void {
239
260
  }
240
261
 
241
262
  function focus(): void {
242
- editor?.focus();
263
+ if (editor) editor.focus();
264
+ else fallbackRef.value?.focus();
243
265
  }
244
266
 
245
267
  function getCode(): string {
@@ -255,6 +277,7 @@ defineExpose({ focus, getCode });
255
277
  :class="[
256
278
  'ck-code-editor ck-code-surface border-border-surface-default bg-background-input-default min-w-0 overflow-hidden rounded-xl border',
257
279
  isReady && 'ck-code-editor--ready',
280
+ isFallback && 'ck-code-editor--fallback',
258
281
  isLocked && 'ck-code-editor--readonly',
259
282
  disabled && 'ck-code-editor--disabled',
260
283
  ]"
@@ -288,7 +311,22 @@ defineExpose({ focus, getCode });
288
311
  ref="hostRef"
289
312
  class="ck-code-editor__host"
290
313
  :style="maxHeight ? { '--ck-code-max-height': maxHeight } : undefined"
291
- />
314
+ >
315
+ <textarea
316
+ v-if="isFallback"
317
+ ref="fallbackRef"
318
+ class="ck-code-editor__fallback"
319
+ :value="modelValue"
320
+ :placeholder="placeholder"
321
+ :aria-label="ariaLabel"
322
+ :readonly="readonly"
323
+ :disabled="disabled"
324
+ :wrap="lineWrapping ? 'soft' : 'off'"
325
+ spellcheck="false"
326
+ @input="onFallbackInput"
327
+ @focus="emit('focus')"
328
+ />
329
+ </div>
292
330
  </component>
293
331
  </div>
294
332
  </template>
@@ -344,6 +382,37 @@ defineExpose({ focus, getCode });
344
382
  font-weight: 500;
345
383
  }
346
384
 
385
+ /* A column so the stand-in below grows into a host a consumer has stretched
386
+ * (as a fixed-height dialog does), rather than sitting at its minimum height
387
+ * at the top of an empty panel. */
388
+ .ck-code-editor--fallback .ck-code-editor__host {
389
+ display: flex;
390
+ flex-direction: column;
391
+ }
392
+
393
+ /* Stand-in for when CodeMirror fails to load: same text metrics and insets as
394
+ * the editor without a gutter, so the field reads as the same surface. Where
395
+ * supported, it grows with its content the way the editor does. */
396
+ .ck-code-editor__fallback {
397
+ display: block;
398
+ flex: 1 1 auto;
399
+ width: 100%;
400
+ min-height: 5rem;
401
+ field-sizing: content;
402
+ max-height: var(--ck-code-max-height, none);
403
+ resize: none;
404
+ border: 0;
405
+ outline: none;
406
+ padding: 0.75rem 1.25rem 1rem 1rem;
407
+ background: var(--ck-cm-bg);
408
+ color: var(--ck-cm-foreground);
409
+ font-family: Saans, sans-serif;
410
+ font-size: 0.875rem;
411
+ font-weight: 400;
412
+ line-height: 1.25rem;
413
+ }
414
+
415
+ .ck-code-editor__fallback::placeholder,
347
416
  .ck-code-editor__host :deep(.cm-placeholder) {
348
417
  color: oklch(var(--content-on-surface-muted));
349
418
  }
@@ -151,10 +151,14 @@ function baseExtensions(options: CreateCodeMirrorOptions): Extension[] {
151
151
  /**
152
152
  * Build a CodeMirror view themed like `UiCodeBlock`. Loaded lazily by
153
153
  * `CkCodeEditor` so CodeMirror stays out of the package's main chunk.
154
+ *
155
+ * The view is built at once, as plain text, and the grammar is applied when it
156
+ * arrives: the placeholder, gutter and content must not wait on a network
157
+ * request that may be slow or never finish. Only the syntax colours do.
154
158
  */
155
- export async function createCodeMirror(
159
+ export function createCodeMirror(
156
160
  options: CreateCodeMirrorOptions,
157
- ): Promise<CodeMirrorHandle> {
161
+ ): CodeMirrorHandle {
158
162
  // One set per view: a compartment is the key a reconfigure targets, so
159
163
  // sharing them across editors would make the instances interfere.
160
164
  const languageSlot = new Compartment();
@@ -164,9 +168,10 @@ export async function createCodeMirror(
164
168
  const badgeSlot = new Compartment();
165
169
  const lineSeparatorSlot = new Compartment();
166
170
 
167
- const support = await resolveLanguage(options.language);
168
171
  // Guards against out-of-order grammar loads; see `setLanguage` below.
169
172
  let languageRequestId = 0;
173
+ // A grammar can land after the view is gone; it must not touch it then.
174
+ let destroyed = false;
170
175
 
171
176
  const view = new EditorView({
172
177
  parent: options.parent,
@@ -174,7 +179,7 @@ export async function createCodeMirror(
174
179
  doc: options.doc,
175
180
  extensions: [
176
181
  ...baseExtensions(options),
177
- languageSlot.of(support ? [support] : []),
182
+ languageSlot.of([]),
178
183
  readonlySlot.of(readonlyState(options.readonly)),
179
184
  lineNumbersSlot.of(options.showLineNumbers ? lineNumbers() : []),
180
185
  wrappingSlot.of(options.lineWrapping ? EditorView.lineWrapping : []),
@@ -187,9 +192,29 @@ export async function createCodeMirror(
187
192
  });
188
193
 
189
194
  function reconfigure(slot: Compartment, extension: Extension): void {
195
+ if (destroyed) return;
190
196
  view.dispatch({ effects: slot.reconfigure(extension) });
191
197
  }
192
198
 
199
+ async function setLanguage(language: string): Promise<void> {
200
+ // Grammars load over the network and out of order, so a slow one must not
201
+ // land on top of a language chosen after it.
202
+ const request = ++languageRequestId;
203
+ const next = await resolveLanguage(language);
204
+ if (request !== languageRequestId) return;
205
+ try {
206
+ reconfigure(languageSlot, next ? [next] : []);
207
+ } catch (error) {
208
+ // Typically a grammar built against another `@codemirror/state` copy.
209
+ // The editor keeps working as plain text; say why the colours are gone.
210
+ // eslint-disable-next-line no-console
211
+ console.warn(`[CkCodeEditor] Could not apply "${language}":`, error);
212
+ }
213
+ }
214
+
215
+ // Nothing waits on this; a failed grammar already resolves to plain text.
216
+ setLanguage(options.language).catch(() => undefined);
217
+
193
218
  return {
194
219
  view,
195
220
  getCode: () => readDoc(view.state),
@@ -208,14 +233,7 @@ export async function createCodeMirror(
208
233
  selection: { anchor: cursor },
209
234
  });
210
235
  },
211
- setLanguage: async (language) => {
212
- // Grammars load over the network and out of order, so a slow one must not
213
- // land on top of a language chosen after it.
214
- const request = ++languageRequestId;
215
- const next = await resolveLanguage(language);
216
- if (request !== languageRequestId) return;
217
- reconfigure(languageSlot, next ? [next] : []);
218
- },
236
+ setLanguage,
219
237
  setReadonly: (readonly) => {
220
238
  reconfigure(readonlySlot, readonlyState(readonly));
221
239
  },
@@ -229,6 +247,9 @@ export async function createCodeMirror(
229
247
  reconfigure(badgeSlot, rule ? badgeExtension(rule) : []);
230
248
  },
231
249
  focus: () => view.focus(),
232
- destroy: () => view.destroy(),
250
+ destroy: () => {
251
+ destroyed = true;
252
+ view.destroy();
253
+ },
233
254
  };
234
255
  }
@@ -1,2 +1,3 @@
1
1
  export { default as CkCodeEditor } from './CkCodeEditor.vue';
2
+ export { preloadCkCodeEditor } from './loadCodeMirror';
2
3
  export type * from './types';
@@ -0,0 +1,28 @@
1
+ import type * as CodeMirrorModule from './createCodeMirror';
2
+
3
+ let pending: Promise<typeof CodeMirrorModule> | undefined;
4
+
5
+ /**
6
+ * Import the CodeMirror chunk once and share the result.
7
+ *
8
+ * A failed import is forgotten rather than cached, so the next editor to mount
9
+ * (or the next `preloadCkCodeEditor` call) tries again instead of inheriting the
10
+ * failure.
11
+ */
12
+ export function loadCodeMirror(): Promise<typeof CodeMirrorModule> {
13
+ pending ??= import('./createCodeMirror').catch((error: unknown) => {
14
+ pending = undefined;
15
+ throw error;
16
+ });
17
+ return pending;
18
+ }
19
+
20
+ /**
21
+ * Start fetching `CkCodeEditor`'s CodeMirror chunk ahead of time, for example
22
+ * when a view that will open an editor is shown. The editor then appears
23
+ * without waiting on the network. Safe to call repeatedly; failures are
24
+ * swallowed here and surface, if still failing, when an editor mounts.
25
+ */
26
+ export function preloadCkCodeEditor(): void {
27
+ loadCodeMirror().catch(() => undefined);
28
+ }
@@ -86,7 +86,7 @@ export type {
86
86
  CkMilkdownEditorExposed,
87
87
  CkMilkdownEditorProps,
88
88
  } from './CkMilkdownEditor';
89
- export { CkCodeEditor } from './CkCodeEditor';
89
+ export { CkCodeEditor, preloadCkCodeEditor } from './CkCodeEditor';
90
90
  export type {
91
91
  CkCodeEditorEmits,
92
92
  CkCodeEditorExposed,
@@ -29,6 +29,7 @@ export {
29
29
  CkEditableUserMessage,
30
30
  CkMilkdownEditor,
31
31
  CkCodeEditor,
32
+ preloadCkCodeEditor,
32
33
  } from './base';
33
34
  export type {
34
35
  CkAgentMessageHeaderProps,
package/src/index.ts CHANGED
@@ -101,6 +101,7 @@ export {
101
101
  CkEditableUserMessage,
102
102
  CkMilkdownEditor,
103
103
  CkCodeEditor,
104
+ preloadCkCodeEditor,
104
105
  } from './components';
105
106
  export type {
106
107
  CkAgentMessageHeaderProps,