@antdv-next/x 1.1.3-beta.1 → 1.1.3-beta.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.
@@ -1,3 +1,4 @@
1
1
  import { default as CodeHighlighter } from './CodeHighlighter';
2
+ export { setupCodeHighlighter } from './shiki';
2
3
  export type { CodeHighlighterHeaderSlotScope, CodeHighlighterProps, CodeHighlighterRef, CodeHighlighterSemanticType, CodeHighlighterSlots, } from './interface';
3
4
  export default CodeHighlighter;
@@ -1,5 +1,6 @@
1
+ import { setupCodeHighlighter } from "./shiki.js";
1
2
  import { XCodeHighlighter } from "./CodeHighlighter.js";
2
3
  //#region components/code-highlighter/index.tsx
3
4
  var code_highlighter_default = XCodeHighlighter;
4
5
  //#endregion
5
- export { code_highlighter_default as default };
6
+ export { code_highlighter_default as default, setupCodeHighlighter };
@@ -1,4 +1,29 @@
1
+ type LanguageLoader = (lang: string) => Promise<any>;
2
+ /**
3
+ * 注入自定义语言加载器,覆盖默认内置白名单。
4
+ * 建议按需 `import` 语言模块,避免引入全量语言包。
5
+ *
6
+ * @example 按需加载额外语言
7
+ * ```ts
8
+ * import { setupCodeHighlighter } from "@antdv-next/x";
9
+ *
10
+ * setupCodeHighlighter({
11
+ * loadLanguage: async (lang) => {
12
+ * const loaders: Record<string, () => Promise<{ default: any }>> = {
13
+ * go: () => import("shiki/dist/langs/go.mjs"),
14
+ * rust: () => import("shiki/dist/langs/rust.mjs"),
15
+ * };
16
+ * const loader = loaders[lang];
17
+ * return loader ? (await loader()).default : null;
18
+ * },
19
+ * });
20
+ * ```
21
+ */
22
+ export declare function setupCodeHighlighter(options: {
23
+ loadLanguage?: LanguageLoader;
24
+ }): void;
1
25
  export declare function codeToHtml(code: string, options?: {
2
26
  lang?: string;
3
27
  theme?: string;
4
28
  }): Promise<string>;
29
+ export {};
@@ -3,40 +3,65 @@ import darkTheme from "shiki/dist/themes/vitesse-dark.mjs";
3
3
  import lightTheme from "shiki/dist/themes/vitesse-light.mjs";
4
4
  import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
5
5
  //#region components/code-highlighter/shiki.ts
6
- var SUPPORTED_LANG_ALIASES = {
7
- ts: "typescript",
8
- js: "javascript",
9
- py: "python",
10
- md: "markdown",
11
- yml: "yaml",
12
- shell: "bash",
13
- zsh: "bash",
14
- sh: "bash",
15
- vue: "vue"
16
- };
17
- var LANG_LOADERS = {
18
- javascript: () => import("shiki/dist/langs/javascript.mjs"),
6
+ var PLAIN_TEXT_LANGUAGES = new Set([
7
+ "text",
8
+ "plaintext",
9
+ "txt",
10
+ "plain"
11
+ ]);
12
+ /**
13
+ * 内置热门语言白名单。
14
+ * 使用静态 import 路径,打包时仅生成这几个语言对应的 chunk。
15
+ */
16
+ var BUILTIN_LANGUAGES = {
19
17
  typescript: () => import("shiki/dist/langs/typescript.mjs"),
20
- jsx: () => import("shiki/dist/langs/jsx.mjs"),
21
- tsx: () => import("shiki/dist/langs/tsx.mjs"),
18
+ javascript: () => import("shiki/dist/langs/javascript.mjs"),
19
+ python: () => import("shiki/dist/langs/python.mjs"),
22
20
  json: () => import("shiki/dist/langs/json.mjs"),
23
- bash: () => import("shiki/dist/langs/bash.mjs"),
24
- markdown: () => import("shiki/dist/langs/markdown.mjs"),
25
21
  html: () => import("shiki/dist/langs/html.mjs"),
26
- css: () => import("shiki/dist/langs/css.mjs"),
27
- vue: () => import("shiki/dist/langs/vue.mjs"),
28
- "vue-html": () => import("shiki/dist/langs/vue-html.mjs"),
29
- python: () => import("shiki/dist/langs/python.mjs"),
30
- mermaid: () => import("shiki/dist/langs/mermaid.mjs"),
31
- yaml: () => import("shiki/dist/langs/yaml.mjs"),
32
- diff: () => import("shiki/dist/langs/diff.mjs")
22
+ css: () => import("shiki/dist/langs/css.mjs")
23
+ };
24
+ /** 常用别名 -> 基础语言 */
25
+ var BUILTIN_ALIASES = {
26
+ ts: "typescript",
27
+ js: "javascript",
28
+ py: "python"
29
+ };
30
+ var defaultLoader = async (lang) => {
31
+ const loader = BUILTIN_LANGUAGES[BUILTIN_ALIASES[lang] ?? lang];
32
+ return loader ? (await loader()).default : null;
33
33
  };
34
+ var activeLoader = defaultLoader;
35
+ /**
36
+ * 注入自定义语言加载器,覆盖默认内置白名单。
37
+ * 建议按需 `import` 语言模块,避免引入全量语言包。
38
+ *
39
+ * @example 按需加载额外语言
40
+ * ```ts
41
+ * import { setupCodeHighlighter } from "@antdv-next/x";
42
+ *
43
+ * setupCodeHighlighter({
44
+ * loadLanguage: async (lang) => {
45
+ * const loaders: Record<string, () => Promise<{ default: any }>> = {
46
+ * go: () => import("shiki/dist/langs/go.mjs"),
47
+ * rust: () => import("shiki/dist/langs/rust.mjs"),
48
+ * };
49
+ * const loader = loaders[lang];
50
+ * return loader ? (await loader()).default : null;
51
+ * },
52
+ * });
53
+ * ```
54
+ */
55
+ function setupCodeHighlighter(options) {
56
+ if (options?.loadLanguage) activeLoader = options.loadLanguage;
57
+ }
34
58
  var highlighter = null;
35
59
  var highlighterPromise = null;
36
60
  var loadedLangs = /* @__PURE__ */ new Set();
61
+ var failedLangs = /* @__PURE__ */ new Set();
62
+ var languageLoadPromises = /* @__PURE__ */ new Map();
37
63
  function normalizeLanguage(language) {
38
- const input = (language || "text").toLowerCase();
39
- return SUPPORTED_LANG_ALIASES[input] || input;
64
+ return (language || "text").toLowerCase();
40
65
  }
41
66
  function escapeHtml(str) {
42
67
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
@@ -52,14 +77,31 @@ async function getHighlighter() {
52
77
  return highlighter;
53
78
  }
54
79
  async function loadLang(lang) {
55
- const loader = LANG_LOADERS[lang];
56
- if (!loader) return false;
57
80
  if (loadedLangs.has(lang)) return true;
58
- const instance = await getHighlighter();
59
- const mod = await loader();
60
- await instance.loadLanguage(mod.default);
61
- loadedLangs.add(lang);
62
- return true;
81
+ if (failedLangs.has(lang) || PLAIN_TEXT_LANGUAGES.has(lang)) return false;
82
+ const pendingLoad = languageLoadPromises.get(lang);
83
+ if (pendingLoad) return pendingLoad;
84
+ const loadPromise = (async () => {
85
+ try {
86
+ const registration = await activeLoader(lang);
87
+ if (!registration) {
88
+ failedLangs.add(lang);
89
+ return false;
90
+ }
91
+ await (await getHighlighter()).loadLanguage(registration);
92
+ loadedLangs.add(lang);
93
+ return true;
94
+ } catch (error) {
95
+ const loadError = error instanceof Error ? error : new Error(String(error));
96
+ failedLangs.add(lang);
97
+ console.warn(`[CodeHighlighter] Failed to load language: ${lang}`, loadError);
98
+ return false;
99
+ } finally {
100
+ languageLoadPromises.delete(lang);
101
+ }
102
+ })();
103
+ languageLoadPromises.set(lang, loadPromise);
104
+ return loadPromise;
63
105
  }
64
106
  async function codeToHtml(code, options = {}) {
65
107
  const lang = normalizeLanguage(options.lang);
@@ -70,4 +112,4 @@ async function codeToHtml(code, options = {}) {
70
112
  });
71
113
  }
72
114
  //#endregion
73
- export { codeToHtml };
115
+ export { codeToHtml, setupCodeHighlighter };
package/dist/index.d.ts CHANGED
@@ -35,6 +35,7 @@ export type { ConversationItemType, ConversationsProps, ConversationsRef, Creati
35
35
  export type { SourcesProps } from './sources';
36
36
  export type { WelcomeProps, WelcomeRef } from './welcome';
37
37
  export type { CodeHighlighterProps, CodeHighlighterRef, CodeHighlighterSemanticType, } from './code-highlighter';
38
+ export { setupCodeHighlighter } from './code-highlighter';
38
39
  export type { SenderProps, SenderRef } from './sender';
39
40
  export type { RenderChildrenProps, SuggestionItem, SuggestionProps, } from './suggestion';
40
41
  export type { XProviderProps } from './x-provider';
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ import { XBubbleDivider } from "./bubble/Divider.js";
10
10
  import { XBubbleSystem } from "./bubble/System.js";
11
11
  import { XBubbleList } from "./bubble/BubbleList.js";
12
12
  import BubbleWithSub from "./bubble/index.js";
13
+ import { setupCodeHighlighter } from "./code-highlighter/shiki.js";
13
14
  import code_highlighter_default from "./code-highlighter/index.js";
14
15
  import Creation from "./conversations/Creation.js";
15
16
  import ConversationsWithSub from "./conversations/index.js";
@@ -69,4 +70,4 @@ var components_default = {
69
70
  version
70
71
  };
71
72
  //#endregion
72
- export { ActionsWithSub as Actions, XActionsAudio as ActionsAudio, XActionsCopy as ActionsCopy, XActionsFeedback as ActionsFeedback, XActionsItem as ActionsItem, XAttachments as Attachments, BubbleWithSub as Bubble, XBubbleDivider as BubbleDivider, XBubbleList as BubbleList, XBubbleSystem as BubbleSystem, code_highlighter_default as CodeHighlighter, ConversationsWithSub as Conversations, Creation as ConversationsCreation, FileCardWithSub as FileCard, XFileCardList as FileCardList, folder_default as Folder, mermaid_default as Mermaid, notification_default as Notification, prompts_default as Prompts, Sender, SenderHeader_default as SenderHeader, SenderSwitch_default as SenderSwitch, sources_default as Sources, suggestion_default as Suggestion, think_default as Think, ThoughtChainWithSub as ThoughtChain, XThoughtChainItem as ThoughtChainItem, XWelcome as Welcome, XNotification, XProvider, components_default as default, version };
73
+ export { ActionsWithSub as Actions, XActionsAudio as ActionsAudio, XActionsCopy as ActionsCopy, XActionsFeedback as ActionsFeedback, XActionsItem as ActionsItem, XAttachments as Attachments, BubbleWithSub as Bubble, XBubbleDivider as BubbleDivider, XBubbleList as BubbleList, XBubbleSystem as BubbleSystem, code_highlighter_default as CodeHighlighter, ConversationsWithSub as Conversations, Creation as ConversationsCreation, FileCardWithSub as FileCard, XFileCardList as FileCardList, folder_default as Folder, mermaid_default as Mermaid, notification_default as Notification, prompts_default as Prompts, Sender, SenderHeader_default as SenderHeader, SenderSwitch_default as SenderSwitch, sources_default as Sources, suggestion_default as Suggestion, think_default as Think, ThoughtChainWithSub as ThoughtChain, XThoughtChainItem as ThoughtChainItem, XWelcome as Welcome, XNotification, XProvider, components_default as default, setupCodeHighlighter, version };
package/dist/index.umd.js CHANGED
@@ -49,7 +49,7 @@
49
49
  shiki_dist_themes_vitesse_dark_mjs = __toESM(shiki_dist_themes_vitesse_dark_mjs);
50
50
  shiki_dist_themes_vitesse_light_mjs = __toESM(shiki_dist_themes_vitesse_light_mjs);
51
51
  //#region package.json
52
- var version = "1.1.3-beta.1";
52
+ var version = "1.1.3-beta.3";
53
53
  //#endregion
54
54
  //#region components/x-provider/context.ts
55
55
  var XProviderContextKey = Symbol("antdv-next-x-provider-context");
@@ -4755,40 +4755,65 @@
4755
4755
  BubbleWithSub.Divider = XBubbleDivider;
4756
4756
  //#endregion
4757
4757
  //#region components/code-highlighter/shiki.ts
4758
- var SUPPORTED_LANG_ALIASES = {
4759
- ts: "typescript",
4760
- js: "javascript",
4761
- py: "python",
4762
- md: "markdown",
4763
- yml: "yaml",
4764
- shell: "bash",
4765
- zsh: "bash",
4766
- sh: "bash",
4767
- vue: "vue"
4768
- };
4769
- var LANG_LOADERS = {
4770
- javascript: () => import("shiki/dist/langs/javascript.mjs"),
4758
+ var PLAIN_TEXT_LANGUAGES = new Set([
4759
+ "text",
4760
+ "plaintext",
4761
+ "txt",
4762
+ "plain"
4763
+ ]);
4764
+ /**
4765
+ * 内置热门语言白名单。
4766
+ * 使用静态 import 路径,打包时仅生成这几个语言对应的 chunk。
4767
+ */
4768
+ var BUILTIN_LANGUAGES = {
4771
4769
  typescript: () => import("shiki/dist/langs/typescript.mjs"),
4772
- jsx: () => import("shiki/dist/langs/jsx.mjs"),
4773
- tsx: () => import("shiki/dist/langs/tsx.mjs"),
4770
+ javascript: () => import("shiki/dist/langs/javascript.mjs"),
4771
+ python: () => import("shiki/dist/langs/python.mjs"),
4774
4772
  json: () => import("shiki/dist/langs/json.mjs"),
4775
- bash: () => import("shiki/dist/langs/bash.mjs"),
4776
- markdown: () => import("shiki/dist/langs/markdown.mjs"),
4777
4773
  html: () => import("shiki/dist/langs/html.mjs"),
4778
- css: () => import("shiki/dist/langs/css.mjs"),
4779
- vue: () => import("shiki/dist/langs/vue.mjs"),
4780
- "vue-html": () => import("shiki/dist/langs/vue-html.mjs"),
4781
- python: () => import("shiki/dist/langs/python.mjs"),
4782
- mermaid: () => import("shiki/dist/langs/mermaid.mjs"),
4783
- yaml: () => import("shiki/dist/langs/yaml.mjs"),
4784
- diff: () => import("shiki/dist/langs/diff.mjs")
4774
+ css: () => import("shiki/dist/langs/css.mjs")
4775
+ };
4776
+ /** 常用别名 -> 基础语言 */
4777
+ var BUILTIN_ALIASES = {
4778
+ ts: "typescript",
4779
+ js: "javascript",
4780
+ py: "python"
4781
+ };
4782
+ var defaultLoader = async (lang) => {
4783
+ const loader = BUILTIN_LANGUAGES[BUILTIN_ALIASES[lang] ?? lang];
4784
+ return loader ? (await loader()).default : null;
4785
4785
  };
4786
+ var activeLoader = defaultLoader;
4787
+ /**
4788
+ * 注入自定义语言加载器,覆盖默认内置白名单。
4789
+ * 建议按需 `import` 语言模块,避免引入全量语言包。
4790
+ *
4791
+ * @example 按需加载额外语言
4792
+ * ```ts
4793
+ * import { setupCodeHighlighter } from "@antdv-next/x";
4794
+ *
4795
+ * setupCodeHighlighter({
4796
+ * loadLanguage: async (lang) => {
4797
+ * const loaders: Record<string, () => Promise<{ default: any }>> = {
4798
+ * go: () => import("shiki/dist/langs/go.mjs"),
4799
+ * rust: () => import("shiki/dist/langs/rust.mjs"),
4800
+ * };
4801
+ * const loader = loaders[lang];
4802
+ * return loader ? (await loader()).default : null;
4803
+ * },
4804
+ * });
4805
+ * ```
4806
+ */
4807
+ function setupCodeHighlighter(options) {
4808
+ if (options?.loadLanguage) activeLoader = options.loadLanguage;
4809
+ }
4786
4810
  var highlighter = null;
4787
4811
  var highlighterPromise = null;
4788
4812
  var loadedLangs = /* @__PURE__ */ new Set();
4813
+ var failedLangs = /* @__PURE__ */ new Set();
4814
+ var languageLoadPromises = /* @__PURE__ */ new Map();
4789
4815
  function normalizeLanguage(language) {
4790
- const input = (language || "text").toLowerCase();
4791
- return SUPPORTED_LANG_ALIASES[input] || input;
4816
+ return (language || "text").toLowerCase();
4792
4817
  }
4793
4818
  function escapeHtml(str) {
4794
4819
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
@@ -4804,14 +4829,31 @@
4804
4829
  return highlighter;
4805
4830
  }
4806
4831
  async function loadLang(lang) {
4807
- const loader = LANG_LOADERS[lang];
4808
- if (!loader) return false;
4809
4832
  if (loadedLangs.has(lang)) return true;
4810
- const instance = await getHighlighter();
4811
- const mod = await loader();
4812
- await instance.loadLanguage(mod.default);
4813
- loadedLangs.add(lang);
4814
- return true;
4833
+ if (failedLangs.has(lang) || PLAIN_TEXT_LANGUAGES.has(lang)) return false;
4834
+ const pendingLoad = languageLoadPromises.get(lang);
4835
+ if (pendingLoad) return pendingLoad;
4836
+ const loadPromise = (async () => {
4837
+ try {
4838
+ const registration = await activeLoader(lang);
4839
+ if (!registration) {
4840
+ failedLangs.add(lang);
4841
+ return false;
4842
+ }
4843
+ await (await getHighlighter()).loadLanguage(registration);
4844
+ loadedLangs.add(lang);
4845
+ return true;
4846
+ } catch (error) {
4847
+ const loadError = error instanceof Error ? error : new Error(String(error));
4848
+ failedLangs.add(lang);
4849
+ console.warn(`[CodeHighlighter] Failed to load language: ${lang}`, loadError);
4850
+ return false;
4851
+ } finally {
4852
+ languageLoadPromises.delete(lang);
4853
+ }
4854
+ })();
4855
+ languageLoadPromises.set(lang, loadPromise);
4856
+ return loadPromise;
4815
4857
  }
4816
4858
  async function codeToHtml(code, options = {}) {
4817
4859
  const lang = normalizeLanguage(options.lang);
@@ -9269,6 +9311,7 @@
9269
9311
  const { componentCls, antCls, calc } = token;
9270
9312
  const slotCls = `${componentCls}-slot`;
9271
9313
  const antInputCls = `${antCls}-input`;
9314
+ const antInputBorderlessCls = `${antInputCls}-borderless`;
9272
9315
  const antDropdownCls = `${antCls}-dropdown-trigger`;
9273
9316
  const slotInputCls = `${componentCls}-slot-input`;
9274
9317
  const slotSelectCls = `${componentCls}-slot-select`;
@@ -9308,6 +9351,7 @@
9308
9351
  fontSize: "inherit",
9309
9352
  lineHeight: "inherit",
9310
9353
  position: "relative",
9354
+ [`&${antInputBorderlessCls}`]: { "&:focus-visible, &:has(input:focus-visible), &:has(textarea:focus-visible)": { outline: "none" } },
9311
9355
  [`&::placeholder`]: {
9312
9356
  color: token.colorTextSlotPlaceholder,
9313
9357
  fontSize: "inherit",
@@ -9513,7 +9557,8 @@
9513
9557
  flex: "auto",
9514
9558
  alignSelf: "center",
9515
9559
  caretColor: token.colorPrimary,
9516
- fontSize: token.fontSize
9560
+ fontSize: token.fontSize,
9561
+ [`&${antCls}-input-borderless`]: { "&:focus-visible, &:has(input:focus-visible), &:has(textarea:focus-visible)": { outline: "none" } }
9517
9562
  },
9518
9563
  [`${componentCls}-actions-list`]: {
9519
9564
  flex: "none",
@@ -12266,5 +12311,6 @@
12266
12311
  exports.XNotification = XNotification;
12267
12312
  exports.XProvider = XProvider;
12268
12313
  exports.default = components_default;
12314
+ exports.setupCodeHighlighter = setupCodeHighlighter;
12269
12315
  exports.version = version;
12270
12316
  });
package/dist/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "1.1.3-beta.1";
2
+ var version = "1.1.3-beta.3";
3
3
  //#endregion
4
4
  export { version };
@@ -43,7 +43,8 @@ var genSenderStyle = (token) => {
43
43
  flex: "auto",
44
44
  alignSelf: "center",
45
45
  caretColor: token.colorPrimary,
46
- fontSize: token.fontSize
46
+ fontSize: token.fontSize,
47
+ [`&${antCls}-input-borderless`]: { "&:focus-visible, &:has(input:focus-visible), &:has(textarea:focus-visible)": { outline: "none" } }
47
48
  },
48
49
  [`${componentCls}-actions-list`]: {
49
50
  flex: "none",
@@ -4,6 +4,7 @@ var genSlotTextAreaStyle = (token) => {
4
4
  const { componentCls, antCls, calc } = token;
5
5
  const slotCls = `${componentCls}-slot`;
6
6
  const antInputCls = `${antCls}-input`;
7
+ const antInputBorderlessCls = `${antInputCls}-borderless`;
7
8
  const antDropdownCls = `${antCls}-dropdown-trigger`;
8
9
  const slotInputCls = `${componentCls}-slot-input`;
9
10
  const slotSelectCls = `${componentCls}-slot-select`;
@@ -43,6 +44,7 @@ var genSlotTextAreaStyle = (token) => {
43
44
  fontSize: "inherit",
44
45
  lineHeight: "inherit",
45
46
  position: "relative",
47
+ [`&${antInputBorderlessCls}`]: { "&:focus-visible, &:has(input:focus-visible), &:has(textarea:focus-visible)": { outline: "none" } },
46
48
  [`&::placeholder`]: {
47
49
  color: token.colorTextSlotPlaceholder,
48
50
  fontSize: "inherit",