@creekjs/web-components 1.0.9 → 1.0.11

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 (55) hide show
  1. package/.turbo/turbo-father$colon$build.log +27 -28
  2. package/dist/creek-config-provider/CreekConfigContext.d.ts +0 -4
  3. package/dist/creek-config-provider/CreekConfigContext.d.ts.map +1 -1
  4. package/dist/creek-config-provider/CreekConfigContext.js.map +2 -2
  5. package/dist/creek-config-provider/CreekI18nProvider.d.ts +5 -4
  6. package/dist/creek-config-provider/CreekI18nProvider.d.ts.map +1 -1
  7. package/dist/creek-config-provider/CreekI18nProvider.js +53 -30
  8. package/dist/creek-config-provider/CreekI18nProvider.js.map +2 -2
  9. package/dist/creek-config-provider/index.d.ts.map +1 -1
  10. package/dist/creek-config-provider/index.js +5 -1
  11. package/dist/creek-config-provider/index.js.map +3 -3
  12. package/dist/creek-keep-alive/index.js +2 -2
  13. package/dist/creek-keep-alive/index.js.map +3 -3
  14. package/dist/creek-layout/ActionRender/FullScreen.js +2 -2
  15. package/dist/creek-layout/ActionRender/FullScreen.js.map +2 -2
  16. package/dist/creek-layout/index.d.ts.map +1 -1
  17. package/dist/creek-layout/index.js +6 -4
  18. package/dist/creek-layout/index.js.map +3 -3
  19. package/dist/creek-locale-button/index.js +4 -4
  20. package/dist/creek-locale-button/index.js.map +1 -1
  21. package/dist/creek-table/components/DensityIcon.js +2 -2
  22. package/dist/creek-table/components/DensityIcon.js.map +2 -2
  23. package/dist/creek-table/components/EllipsisTooltip.js +2 -2
  24. package/dist/creek-table/components/EllipsisTooltip.js.map +3 -3
  25. package/dist/creek-table/hooks/useIndexColumn.js +2 -2
  26. package/dist/creek-table/hooks/useIndexColumn.js.map +3 -3
  27. package/dist/locales/en_US.d.ts.map +1 -0
  28. package/dist/locales/{en-US.js → en_US.js} +2 -2
  29. package/dist/locales/{en-US.js.map → en_US.js.map} +1 -1
  30. package/dist/locales/zh_CN.d.ts.map +1 -0
  31. package/dist/locales/{zh-CN.js → zh_CN.js} +2 -2
  32. package/dist/locales/{zh-CN.js.map → zh_CN.js.map} +1 -1
  33. package/i18n.config.ts +7 -4
  34. package/package.json +3 -3
  35. package/src/creek-config-provider/CreekConfigContext.tsx +0 -4
  36. package/src/creek-config-provider/CreekI18nProvider.tsx +65 -37
  37. package/src/creek-config-provider/index.tsx +8 -4
  38. package/src/creek-keep-alive/index.tsx +1 -1
  39. package/src/creek-layout/ActionRender/FullScreen.tsx +1 -1
  40. package/src/creek-layout/index.tsx +7 -2
  41. package/src/creek-locale-button/index.tsx +4 -4
  42. package/src/creek-table/components/DensityIcon.tsx +1 -1
  43. package/src/creek-table/components/EllipsisTooltip.tsx +1 -1
  44. package/src/creek-table/hooks/useIndexColumn.tsx +1 -1
  45. package/dist/locales/en-US.d.ts.map +0 -1
  46. package/dist/locales/zh-CN.d.ts.map +0 -1
  47. package/dist/utils/i18n.d.ts +0 -2
  48. package/dist/utils/i18n.d.ts.map +0 -1
  49. package/dist/utils/i18n.js +0 -34
  50. package/dist/utils/i18n.js.map +0 -7
  51. package/src/utils/i18n.ts +0 -4
  52. /package/dist/locales/{en-US.d.ts → en_US.d.ts} +0 -0
  53. /package/dist/locales/{zh-CN.d.ts → zh_CN.d.ts} +0 -0
  54. /package/src/locales/{en-US.ts → en_US.ts} +0 -0
  55. /package/src/locales/{zh-CN.ts → zh_CN.ts} +0 -0
@@ -24,10 +24,10 @@ __export(DensityIcon_exports, {
24
24
  module.exports = __toCommonJS(DensityIcon_exports);
25
25
  var import_icons = require("@ant-design/icons");
26
26
  var import_antd = require("antd");
27
- var import_i18n = require("../../utils/i18n");
27
+ var import_react = require("@creekjs/i18n/react");
28
28
  var import_jsx_runtime = require("react/jsx-runtime");
29
29
  var DensityIcon = ({ tableSize, setTableSize }) => {
30
- const t = (0, import_i18n.useT)();
30
+ const t = (0, import_react.useT)();
31
31
  const items = [
32
32
  {
33
33
  key: "large",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/creek-table/components/DensityIcon.tsx"],
4
- "sourcesContent": ["import { ColumnHeightOutlined } from '@ant-design/icons';\nimport { ProTableProps } from '@ant-design/pro-components';\nimport { Dropdown, MenuProps, Tooltip } from 'antd';\nimport React from 'react';\n\nimport { useT } from '@/utils/i18n';\n\nexport type SizeType = ProTableProps<any, any>['size'];\n\ninterface DensityIconProps {\n tableSize: SizeType;\n setTableSize: (size: SizeType) => void;\n}\n\nexport const DensityIcon: React.FC<DensityIconProps> = ({ tableSize, setTableSize }) => {\n const t = useT();\n\n const items: MenuProps['items'] = [\n {\n key: 'large',\n label: t('creek-table.components.DensityIcon.kuanSong', '宽松'),\n onClick: () => setTableSize('large'),\n },\n {\n key: 'middle',\n label: t('creek-table.components.DensityIcon.zhongDeng', '中等'),\n onClick: () => setTableSize('middle'),\n },\n {\n key: 'small',\n label: t('creek-table.components.DensityIcon.jinCou', '紧凑'),\n onClick: () => setTableSize('small'),\n },\n ];\n\n const getTitle = () => {\n switch (tableSize) {\n case 'large':\n return t('creek-table.components.DensityIcon.biaoGeMiDu(KuanSong)', '表格密度 (宽松)');\n case 'middle':\n return t('creek-table.components.DensityIcon.biaoGeMiDu(ZhongDeng)', '表格密度 (中等)');\n case 'small':\n return t('creek-table.components.DensityIcon.biaoGeMiDu(JinCou)', '表格密度 (紧凑)');\n default:\n return t('creek-table.components.DensityIcon.biaoGeMiDu', '表格密度');\n }\n };\n\n return (\n <Dropdown\n menu={{\n items,\n selectedKeys: [tableSize || 'large'],\n selectable: true,\n }}\n trigger={['click']}\n >\n <Tooltip title={getTitle()}>\n <ColumnHeightOutlined style={{ fontSize: 16, cursor: 'pointer' }} />\n </Tooltip>\n </Dropdown>\n );\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAqC;AAErC,kBAA6C;AAG7C,kBAAqB;AAqDb;AA5CD,IAAM,cAA0C,CAAC,EAAE,WAAW,aAAa,MAAM;AACtF,QAAM,QAAI,kBAAK;AAEf,QAAM,QAA4B;AAAA,IAChC;AAAA,MACE,KAAK;AAAA,MACL,OAAO,EAAE,+CAA+C,IAAI;AAAA,MAC5D,SAAS,MAAM,aAAa,OAAO;AAAA,IACrC;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO,EAAE,gDAAgD,IAAI;AAAA,MAC7D,SAAS,MAAM,aAAa,QAAQ;AAAA,IACtC;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO,EAAE,6CAA6C,IAAI;AAAA,MAC1D,SAAS,MAAM,aAAa,OAAO;AAAA,IACrC;AAAA,EACF;AAEA,QAAM,WAAW,MAAM;AACrB,YAAQ,WAAW;AAAA,MACjB,KAAK;AACH,eAAO,EAAE,2DAA2D,WAAW;AAAA,MACjF,KAAK;AACH,eAAO,EAAE,4DAA4D,WAAW;AAAA,MAClF,KAAK;AACH,eAAO,EAAE,yDAAyD,WAAW;AAAA,MAC/E;AACE,eAAO,EAAE,iDAAiD,MAAM;AAAA,IACpE;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,QACJ;AAAA,QACA,cAAc,CAAC,aAAa,OAAO;AAAA,QACnC,YAAY;AAAA,MACd;AAAA,MACA,SAAS,CAAC,OAAO;AAAA,MAEjB,sDAAC,uBAAQ,OAAO,SAAS,GACvB,sDAAC,qCAAqB,OAAO,EAAE,UAAU,IAAI,QAAQ,UAAU,GAAG,GACpE;AAAA;AAAA,EACF;AAEJ;",
4
+ "sourcesContent": ["import { ColumnHeightOutlined } from '@ant-design/icons';\nimport { ProTableProps } from '@ant-design/pro-components';\nimport { Dropdown, MenuProps, Tooltip } from 'antd';\nimport React from 'react';\n\nimport { useT } from '@creekjs/i18n/react';\n\nexport type SizeType = ProTableProps<any, any>['size'];\n\ninterface DensityIconProps {\n tableSize: SizeType;\n setTableSize: (size: SizeType) => void;\n}\n\nexport const DensityIcon: React.FC<DensityIconProps> = ({ tableSize, setTableSize }) => {\n const t = useT();\n\n const items: MenuProps['items'] = [\n {\n key: 'large',\n label: t('creek-table.components.DensityIcon.kuanSong', '宽松'),\n onClick: () => setTableSize('large'),\n },\n {\n key: 'middle',\n label: t('creek-table.components.DensityIcon.zhongDeng', '中等'),\n onClick: () => setTableSize('middle'),\n },\n {\n key: 'small',\n label: t('creek-table.components.DensityIcon.jinCou', '紧凑'),\n onClick: () => setTableSize('small'),\n },\n ];\n\n const getTitle = () => {\n switch (tableSize) {\n case 'large':\n return t('creek-table.components.DensityIcon.biaoGeMiDu(KuanSong)', '表格密度 (宽松)');\n case 'middle':\n return t('creek-table.components.DensityIcon.biaoGeMiDu(ZhongDeng)', '表格密度 (中等)');\n case 'small':\n return t('creek-table.components.DensityIcon.biaoGeMiDu(JinCou)', '表格密度 (紧凑)');\n default:\n return t('creek-table.components.DensityIcon.biaoGeMiDu', '表格密度');\n }\n };\n\n return (\n <Dropdown\n menu={{\n items,\n selectedKeys: [tableSize || 'large'],\n selectable: true,\n }}\n trigger={['click']}\n >\n <Tooltip title={getTitle()}>\n <ColumnHeightOutlined style={{ fontSize: 16, cursor: 'pointer' }} />\n </Tooltip>\n </Dropdown>\n );\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAqC;AAErC,kBAA6C;AAG7C,mBAAqB;AAqDb;AA5CD,IAAM,cAA0C,CAAC,EAAE,WAAW,aAAa,MAAM;AACtF,QAAM,QAAI,mBAAK;AAEf,QAAM,QAA4B;AAAA,IAChC;AAAA,MACE,KAAK;AAAA,MACL,OAAO,EAAE,+CAA+C,IAAI;AAAA,MAC5D,SAAS,MAAM,aAAa,OAAO;AAAA,IACrC;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO,EAAE,gDAAgD,IAAI;AAAA,MAC7D,SAAS,MAAM,aAAa,QAAQ;AAAA,IACtC;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO,EAAE,6CAA6C,IAAI;AAAA,MAC1D,SAAS,MAAM,aAAa,OAAO;AAAA,IACrC;AAAA,EACF;AAEA,QAAM,WAAW,MAAM;AACrB,YAAQ,WAAW;AAAA,MACjB,KAAK;AACH,eAAO,EAAE,2DAA2D,WAAW;AAAA,MACjF,KAAK;AACH,eAAO,EAAE,4DAA4D,WAAW;AAAA,MAClF,KAAK;AACH,eAAO,EAAE,yDAAyD,WAAW;AAAA,MAC/E;AACE,eAAO,EAAE,iDAAiD,MAAM;AAAA,IACpE;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,QACJ;AAAA,QACA,cAAc,CAAC,aAAa,OAAO;AAAA,QACnC,YAAY;AAAA,MACd;AAAA,MACA,SAAS,CAAC,OAAO;AAAA,MAEjB,sDAAC,uBAAQ,OAAO,SAAS,GACvB,sDAAC,qCAAqB,OAAO,EAAE,UAAU,IAAI,QAAQ,UAAU,GAAG,GACpE;AAAA;AAAA,EACF;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -36,7 +36,7 @@ var import_icons = require("@ant-design/icons");
36
36
  var import_antd = require("antd");
37
37
  var import_antd_style = require("antd-style");
38
38
  var import_react = __toESM(require("react"));
39
- var import_i18n = require("../../utils/i18n");
39
+ var import_react2 = require("@creekjs/i18n/react");
40
40
  var import_jsx_runtime = require("react/jsx-runtime");
41
41
  var useStyles = (0, import_antd_style.createStyles)(({ css, token }) => {
42
42
  return {
@@ -69,7 +69,7 @@ var useStyles = (0, import_antd_style.createStyles)(({ css, token }) => {
69
69
  };
70
70
  });
71
71
  var EllipsisTooltip = ({ children }) => {
72
- const t = (0, import_i18n.useT)();
72
+ const t = (0, import_react2.useT)();
73
73
  const { styles } = useStyles();
74
74
  const { getPrefixCls } = (0, import_react.useContext)(import_antd.ConfigProvider.ConfigContext);
75
75
  const textRef = (0, import_react.useRef)(null);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/creek-table/components/EllipsisTooltip.tsx"],
4
- "sourcesContent": ["import { CopyOutlined } from '@ant-design/icons';\nimport { ConfigProvider, Flex, Tooltip, Typography, message } from 'antd';\nimport { createStyles } from 'antd-style';\nimport React, { useContext, useEffect, useRef, useState } from 'react';\n\nimport { useT } from '@/utils/i18n';\n\nconst useStyles = createStyles(({ css, token }) => {\n return {\n text: css`\n width: 100%;\n margin: 0;\n padding: 0;\n // Ensure the wrapper behaves like a block/inline-block that can have width\n display: block;\n overflow: hidden;\n `,\n tooltipContent: css`\n max-width: 500px;\n max-height: 300px;\n overflow-y: auto;\n `,\n tooltipText: css`\n word-break: break-all;\n white-space: pre-wrap;\n `,\n copyIcon: css`\n cursor: pointer;\n color: inherit;\n transition: color 0.2s;\n\n &:hover {\n color: ${token.colorPrimary};\n }\n `,\n };\n});\n\n/**\n * 使用 Antd Typography 组件实现省略提示\n * 修复了 findDOMNode 警告问题:通过显式使用 Tooltip 包裹 div 容器\n * 实现了智能提示:只有内容实际溢出时才显示 Tooltip\n */\nexport const EllipsisTooltip = ({ children }: { children: React.ReactNode }) => {\n const t = useT();\n\n const { styles } = useStyles();\n const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);\n const textRef = useRef<HTMLDivElement>(null);\n const [isEllipsis, setIsEllipsis] = useState(false);\n const isSimpleContent = typeof children === 'string' || typeof children === 'number';\n\n useEffect(() => {\n const checkEllipsis = () => {\n if (textRef.current) {\n const prefixCls = getPrefixCls('typography');\n // Typography.Text renders a span or div with .ant-typography\n const typographyEl = textRef.current.querySelector(`.${prefixCls}`);\n if (typographyEl) {\n // For simple ellipsis={true}, Antd uses CSS ellipsis.\n // We can detect if it's truncated by comparing scrollWidth and clientWidth\n // We add a small buffer (1px) for browser sub-pixel rendering differences\n setIsEllipsis(typographyEl.scrollWidth > typographyEl.clientWidth + 1);\n }\n }\n };\n\n // Initial check\n checkEllipsis();\n // Use ResizeObserver for more robust size change detection\n const observer = new ResizeObserver(checkEllipsis);\n if (textRef.current) {\n observer.observe(textRef.current);\n }\n\n return () => {\n observer.disconnect();\n };\n }, [children]);\n\n const text = String(children);\n\n const handleCopy = (e: React.MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n navigator.clipboard\n .writeText(text)\n .then(() => {\n message.success(t('creek-table.components.EllipsisTooltip.fuZhiChengGong', '复制成功'));\n })\n .catch(() => {\n message.error(t('creek-table.components.EllipsisTooltip.fuZhiShiBai', '复制失败'));\n });\n };\n\n // Memoize tooltip title content\n const tooltipTitle = React.useMemo(() => {\n if (!isSimpleContent) {\n return children;\n }\n return (\n <Flex align=\"center\" gap={8} className={styles.tooltipContent}>\n <span className={styles.tooltipText}>{children}</span>\n <CopyOutlined onClick={handleCopy} className={styles.copyIcon} title={t('creek-table.components.EllipsisTooltip.fuZhi', '复制')} />\n </Flex>\n );\n }, [children, isSimpleContent]);\n\n return (\n <Tooltip title={isEllipsis ? tooltipTitle : undefined} placement=\"topLeft\" mouseLeaveDelay={0.2} getPopupContainer={() => document.body}>\n <div ref={textRef} className={styles.text}>\n <Typography.Text ellipsis={true}>{children}</Typography.Text>\n </div>\n </Tooltip>\n );\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA6B;AAC7B,kBAAmE;AACnE,wBAA6B;AAC7B,mBAA+D;AAE/D,kBAAqB;AAgGf;AA9FN,IAAM,gBAAY,gCAAa,CAAC,EAAE,KAAK,MAAM,MAAM;AACjD,SAAO;AAAA,IACL,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQN,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,IAKhB,aAAa;AAAA;AAAA;AAAA;AAAA,IAIb,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAMG,MAAM;AAAA;AAAA;AAAA,EAGrB;AACF,CAAC;AAOM,IAAM,kBAAkB,CAAC,EAAE,SAAS,MAAqC;AAC9E,QAAM,QAAI,kBAAK;AAEf,QAAM,EAAE,OAAO,IAAI,UAAU;AAC7B,QAAM,EAAE,aAAa,QAAI,yBAAW,2BAAe,aAAa;AAChE,QAAM,cAAU,qBAAuB,IAAI;AAC3C,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,KAAK;AAClD,QAAM,kBAAkB,OAAO,aAAa,YAAY,OAAO,aAAa;AAE5E,8BAAU,MAAM;AACd,UAAM,gBAAgB,MAAM;AAC1B,UAAI,QAAQ,SAAS;AACnB,cAAM,YAAY,aAAa,YAAY;AAE3C,cAAM,eAAe,QAAQ,QAAQ,cAAc,IAAI,WAAW;AAClE,YAAI,cAAc;AAIhB,wBAAc,aAAa,cAAc,aAAa,cAAc,CAAC;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AAGA,kBAAc;AAEd,UAAM,WAAW,IAAI,eAAe,aAAa;AACjD,QAAI,QAAQ,SAAS;AACnB,eAAS,QAAQ,QAAQ,OAAO;AAAA,IAClC;AAEA,WAAO,MAAM;AACX,eAAS,WAAW;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,OAAO,OAAO,QAAQ;AAE5B,QAAM,aAAa,CAAC,MAAwB;AAC1C,MAAE,gBAAgB;AAClB,MAAE,eAAe;AACjB,cAAU,UACP,UAAU,IAAI,EACd,KAAK,MAAM;AACV,0BAAQ,QAAQ,EAAE,yDAAyD,MAAM,CAAC;AAAA,IACpF,CAAC,EACA,MAAM,MAAM;AACX,0BAAQ,MAAM,EAAE,sDAAsD,MAAM,CAAC;AAAA,IAC/E,CAAC;AAAA,EACL;AAGA,QAAM,eAAe,aAAAA,QAAM,QAAQ,MAAM;AACvC,QAAI,CAAC,iBAAiB;AACpB,aAAO;AAAA,IACT;AACA,WACE,6CAAC,oBAAK,OAAM,UAAS,KAAK,GAAG,WAAW,OAAO,gBAC7C;AAAA,kDAAC,UAAK,WAAW,OAAO,aAAc,UAAS;AAAA,MAC/C,4CAAC,6BAAa,SAAS,YAAY,WAAW,OAAO,UAAU,OAAO,EAAE,gDAAgD,IAAI,GAAG;AAAA,OACjI;AAAA,EAEJ,GAAG,CAAC,UAAU,eAAe,CAAC;AAE9B,SACE,4CAAC,uBAAQ,OAAO,aAAa,eAAe,QAAW,WAAU,WAAU,iBAAiB,KAAK,mBAAmB,MAAM,SAAS,MACjI,sDAAC,SAAI,KAAK,SAAS,WAAW,OAAO,MACnC,sDAAC,uBAAW,MAAX,EAAgB,UAAU,MAAO,UAAS,GAC7C,GACF;AAEJ;",
6
- "names": ["React"]
4
+ "sourcesContent": ["import { CopyOutlined } from '@ant-design/icons';\nimport { ConfigProvider, Flex, Tooltip, Typography, message } from 'antd';\nimport { createStyles } from 'antd-style';\nimport React, { useContext, useEffect, useRef, useState } from 'react';\n\nimport { useT } from '@creekjs/i18n/react';\n\nconst useStyles = createStyles(({ css, token }) => {\n return {\n text: css`\n width: 100%;\n margin: 0;\n padding: 0;\n // Ensure the wrapper behaves like a block/inline-block that can have width\n display: block;\n overflow: hidden;\n `,\n tooltipContent: css`\n max-width: 500px;\n max-height: 300px;\n overflow-y: auto;\n `,\n tooltipText: css`\n word-break: break-all;\n white-space: pre-wrap;\n `,\n copyIcon: css`\n cursor: pointer;\n color: inherit;\n transition: color 0.2s;\n\n &:hover {\n color: ${token.colorPrimary};\n }\n `,\n };\n});\n\n/**\n * 使用 Antd Typography 组件实现省略提示\n * 修复了 findDOMNode 警告问题:通过显式使用 Tooltip 包裹 div 容器\n * 实现了智能提示:只有内容实际溢出时才显示 Tooltip\n */\nexport const EllipsisTooltip = ({ children }: { children: React.ReactNode }) => {\n const t = useT();\n\n const { styles } = useStyles();\n const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);\n const textRef = useRef<HTMLDivElement>(null);\n const [isEllipsis, setIsEllipsis] = useState(false);\n const isSimpleContent = typeof children === 'string' || typeof children === 'number';\n\n useEffect(() => {\n const checkEllipsis = () => {\n if (textRef.current) {\n const prefixCls = getPrefixCls('typography');\n // Typography.Text renders a span or div with .ant-typography\n const typographyEl = textRef.current.querySelector(`.${prefixCls}`);\n if (typographyEl) {\n // For simple ellipsis={true}, Antd uses CSS ellipsis.\n // We can detect if it's truncated by comparing scrollWidth and clientWidth\n // We add a small buffer (1px) for browser sub-pixel rendering differences\n setIsEllipsis(typographyEl.scrollWidth > typographyEl.clientWidth + 1);\n }\n }\n };\n\n // Initial check\n checkEllipsis();\n // Use ResizeObserver for more robust size change detection\n const observer = new ResizeObserver(checkEllipsis);\n if (textRef.current) {\n observer.observe(textRef.current);\n }\n\n return () => {\n observer.disconnect();\n };\n }, [children]);\n\n const text = String(children);\n\n const handleCopy = (e: React.MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n navigator.clipboard\n .writeText(text)\n .then(() => {\n message.success(t('creek-table.components.EllipsisTooltip.fuZhiChengGong', '复制成功'));\n })\n .catch(() => {\n message.error(t('creek-table.components.EllipsisTooltip.fuZhiShiBai', '复制失败'));\n });\n };\n\n // Memoize tooltip title content\n const tooltipTitle = React.useMemo(() => {\n if (!isSimpleContent) {\n return children;\n }\n return (\n <Flex align=\"center\" gap={8} className={styles.tooltipContent}>\n <span className={styles.tooltipText}>{children}</span>\n <CopyOutlined onClick={handleCopy} className={styles.copyIcon} title={t('creek-table.components.EllipsisTooltip.fuZhi', '复制')} />\n </Flex>\n );\n }, [children, isSimpleContent]);\n\n return (\n <Tooltip title={isEllipsis ? tooltipTitle : undefined} placement=\"topLeft\" mouseLeaveDelay={0.2} getPopupContainer={() => document.body}>\n <div ref={textRef} className={styles.text}>\n <Typography.Text ellipsis={true}>{children}</Typography.Text>\n </div>\n </Tooltip>\n );\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA6B;AAC7B,kBAAmE;AACnE,wBAA6B;AAC7B,mBAA+D;AAE/D,IAAAA,gBAAqB;AAgGf;AA9FN,IAAM,gBAAY,gCAAa,CAAC,EAAE,KAAK,MAAM,MAAM;AACjD,SAAO;AAAA,IACL,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQN,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,IAKhB,aAAa;AAAA;AAAA;AAAA;AAAA,IAIb,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAMG,MAAM;AAAA;AAAA;AAAA,EAGrB;AACF,CAAC;AAOM,IAAM,kBAAkB,CAAC,EAAE,SAAS,MAAqC;AAC9E,QAAM,QAAI,oBAAK;AAEf,QAAM,EAAE,OAAO,IAAI,UAAU;AAC7B,QAAM,EAAE,aAAa,QAAI,yBAAW,2BAAe,aAAa;AAChE,QAAM,cAAU,qBAAuB,IAAI;AAC3C,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,KAAK;AAClD,QAAM,kBAAkB,OAAO,aAAa,YAAY,OAAO,aAAa;AAE5E,8BAAU,MAAM;AACd,UAAM,gBAAgB,MAAM;AAC1B,UAAI,QAAQ,SAAS;AACnB,cAAM,YAAY,aAAa,YAAY;AAE3C,cAAM,eAAe,QAAQ,QAAQ,cAAc,IAAI,WAAW;AAClE,YAAI,cAAc;AAIhB,wBAAc,aAAa,cAAc,aAAa,cAAc,CAAC;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AAGA,kBAAc;AAEd,UAAM,WAAW,IAAI,eAAe,aAAa;AACjD,QAAI,QAAQ,SAAS;AACnB,eAAS,QAAQ,QAAQ,OAAO;AAAA,IAClC;AAEA,WAAO,MAAM;AACX,eAAS,WAAW;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,OAAO,OAAO,QAAQ;AAE5B,QAAM,aAAa,CAAC,MAAwB;AAC1C,MAAE,gBAAgB;AAClB,MAAE,eAAe;AACjB,cAAU,UACP,UAAU,IAAI,EACd,KAAK,MAAM;AACV,0BAAQ,QAAQ,EAAE,yDAAyD,MAAM,CAAC;AAAA,IACpF,CAAC,EACA,MAAM,MAAM;AACX,0BAAQ,MAAM,EAAE,sDAAsD,MAAM,CAAC;AAAA,IAC/E,CAAC;AAAA,EACL;AAGA,QAAM,eAAe,aAAAC,QAAM,QAAQ,MAAM;AACvC,QAAI,CAAC,iBAAiB;AACpB,aAAO;AAAA,IACT;AACA,WACE,6CAAC,oBAAK,OAAM,UAAS,KAAK,GAAG,WAAW,OAAO,gBAC7C;AAAA,kDAAC,UAAK,WAAW,OAAO,aAAc,UAAS;AAAA,MAC/C,4CAAC,6BAAa,SAAS,YAAY,WAAW,OAAO,UAAU,OAAO,EAAE,gDAAgD,IAAI,GAAG;AAAA,OACjI;AAAA,EAEJ,GAAG,CAAC,UAAU,eAAe,CAAC;AAE9B,SACE,4CAAC,uBAAQ,OAAO,aAAa,eAAe,QAAW,WAAU,WAAU,iBAAiB,KAAK,mBAAmB,MAAM,SAAS,MACjI,sDAAC,SAAI,KAAK,SAAS,WAAW,OAAO,MACnC,sDAAC,uBAAW,MAAX,EAAgB,UAAU,MAAO,UAAS,GAC7C,GACF;AAEJ;",
6
+ "names": ["import_react", "React"]
7
7
  }
@@ -23,9 +23,9 @@ __export(useIndexColumn_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(useIndexColumn_exports);
25
25
  var import_react = require("react");
26
- var import_i18n = require("../../utils/i18n");
26
+ var import_react2 = require("@creekjs/i18n/react");
27
27
  var useIndexColumn = (columns = [], showIndex = true) => {
28
- const t = (0, import_i18n.useT)();
28
+ const t = (0, import_react2.useT)();
29
29
  return (0, import_react.useMemo)(() => {
30
30
  if (!showIndex) {
31
31
  return columns;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/creek-table/hooks/useIndexColumn.tsx"],
4
- "sourcesContent": ["import { ProColumns } from '@ant-design/pro-components';\nimport { useMemo } from 'react';\n\nimport { useT } from '@/utils/i18n';\n\nexport const useIndexColumn = <T = any, ValueType = 'text'>(columns: ProColumns<T, ValueType>[] = [], showIndex: boolean = true) => {\n const t = useT();\n\n return useMemo(() => {\n if (!showIndex) {\n return columns;\n }\n const indexColumn: ProColumns<T, ValueType> = {\n title: t('creek-table.hooks.useIndexColumn.xuHao', '序号'),\n dataIndex: 'index',\n width: 48,\n fixed: 'left',\n disable: true,\n hideInSearch: true,\n render: (dom, entity, index, action, schema) => {\n const { current = 1, pageSize = 20 } = action?.pageInfo || {};\n return (current - 1) * pageSize + index + 1;\n },\n };\n return [indexColumn, ...columns];\n }, [columns, showIndex, t]);\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAwB;AAExB,kBAAqB;AAEd,IAAM,iBAAiB,CAA8B,UAAsC,CAAC,GAAG,YAAqB,SAAS;AAClI,QAAM,QAAI,kBAAK;AAEf,aAAO,sBAAQ,MAAM;AACnB,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AACA,UAAM,cAAwC;AAAA,MAC5C,OAAO,EAAE,0CAA0C,IAAI;AAAA,MACvD,WAAW;AAAA,MACX,OAAO;AAAA,MACP,OAAO;AAAA,MACP,SAAS;AAAA,MACT,cAAc;AAAA,MACd,QAAQ,CAAC,KAAK,QAAQ,OAAO,QAAQ,WAAW;AAC9C,cAAM,EAAE,UAAU,GAAG,WAAW,GAAG,KAAI,iCAAQ,aAAY,CAAC;AAC5D,gBAAQ,UAAU,KAAK,WAAW,QAAQ;AAAA,MAC5C;AAAA,IACF;AACA,WAAO,CAAC,aAAa,GAAG,OAAO;AAAA,EACjC,GAAG,CAAC,SAAS,WAAW,CAAC,CAAC;AAC5B;",
6
- "names": []
4
+ "sourcesContent": ["import { ProColumns } from '@ant-design/pro-components';\nimport { useMemo } from 'react';\n\nimport { useT } from '@creekjs/i18n/react';\n\nexport const useIndexColumn = <T = any, ValueType = 'text'>(columns: ProColumns<T, ValueType>[] = [], showIndex: boolean = true) => {\n const t = useT();\n\n return useMemo(() => {\n if (!showIndex) {\n return columns;\n }\n const indexColumn: ProColumns<T, ValueType> = {\n title: t('creek-table.hooks.useIndexColumn.xuHao', '序号'),\n dataIndex: 'index',\n width: 48,\n fixed: 'left',\n disable: true,\n hideInSearch: true,\n render: (dom, entity, index, action, schema) => {\n const { current = 1, pageSize = 20 } = action?.pageInfo || {};\n return (current - 1) * pageSize + index + 1;\n },\n };\n return [indexColumn, ...columns];\n }, [columns, showIndex, t]);\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAwB;AAExB,IAAAA,gBAAqB;AAEd,IAAM,iBAAiB,CAA8B,UAAsC,CAAC,GAAG,YAAqB,SAAS;AAClI,QAAM,QAAI,oBAAK;AAEf,aAAO,sBAAQ,MAAM;AACnB,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AACA,UAAM,cAAwC;AAAA,MAC5C,OAAO,EAAE,0CAA0C,IAAI;AAAA,MACvD,WAAW;AAAA,MACX,OAAO;AAAA,MACP,OAAO;AAAA,MACP,SAAS;AAAA,MACT,cAAc;AAAA,MACd,QAAQ,CAAC,KAAK,QAAQ,OAAO,QAAQ,WAAW;AAC9C,cAAM,EAAE,UAAU,GAAG,WAAW,GAAG,KAAI,iCAAQ,aAAY,CAAC;AAC5D,gBAAQ,UAAU,KAAK,WAAW,QAAQ;AAAA,MAC5C;AAAA,IACF;AACA,WAAO,CAAC,aAAa,GAAG,OAAO;AAAA,EACjC,GAAG,CAAC,SAAS,WAAW,CAAC,CAAC;AAC5B;",
6
+ "names": ["import_react"]
7
7
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en_US.d.ts","sourceRoot":"","sources":["../../src/locales/en_US.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAuBE"}
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
16
16
  };
17
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
18
 
19
- // src/locales/en-US.ts
19
+ // src/locales/en_US.ts
20
20
  var en_US_exports = {};
21
21
  __export(en_US_exports, {
22
22
  default: () => en_US_default
@@ -46,4 +46,4 @@ var en_US_default = {
46
46
  "creek-locale-button.index.jianTiZhongWen": "Simplified Chinese",
47
47
  "creek-layout.ActionRender.LayoutSettings.keepAlive": "Enable Page Cache (Keep Alive)"
48
48
  };
49
- //# sourceMappingURL=en-US.js.map
49
+ //# sourceMappingURL=en_US.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/locales/en-US.ts"],
3
+ "sources": ["../../src/locales/en_US.ts"],
4
4
  "sourcesContent": ["export default {\n 'creek-keep-alive.index.guanBiDangQian': 'Close Current',\n 'creek-keep-alive.index.guanBiQiTa': 'Close Others',\n 'creek-keep-alive.index.guanBiYouCe': 'Close Right',\n 'creek-layout.ActionRender.FullScreen.tuiChuQuanPing': 'Exit Full Screen',\n 'creek-layout.ActionRender.FullScreen.quanPing': 'Full Screen',\n 'creek-table.components.DensityIcon.kuanSong': 'Loose',\n 'creek-table.components.DensityIcon.zhongDeng': 'Medium',\n 'creek-table.components.DensityIcon.jinCou': 'Compact',\n 'creek-table.components.DensityIcon.biaoGeMiDu(KuanSong)': 'Table Density (Loose)',\n 'creek-table.components.DensityIcon.biaoGeMiDu(ZhongDeng)': 'Table Density (Medium)',\n 'creek-table.components.DensityIcon.biaoGeMiDu(JinCou)': 'Table Density (Compact)',\n 'creek-table.components.DensityIcon.biaoGeMiDu': 'Table Density',\n 'creek-table.components.EllipsisTooltip.fuZhiChengGong': 'Copied Successfully',\n 'creek-table.components.EllipsisTooltip.fuZhiShiBai': 'Copy Failed',\n 'creek-table.components.EllipsisTooltip.fuZhi': 'Copy',\n 'creek-table.hooks.useIndexColumn.xuHao': 'No.',\n 'creek-layout.ActionRender.LayoutSettings.title': 'System Settings',\n 'creek-layout.ActionRender.LayoutSettings.themeColor': 'Theme Color',\n 'creek-layout.ActionRender.LayoutSettings.showFullScreen': 'Show Full Screen Button',\n 'creek-layout.ActionRender.LayoutSettings.showLocaleButton': 'Show Locale Button',\n 'creek-locale-button.index.jianTiZhongWen': 'Simplified Chinese',\n 'creek-layout.ActionRender.LayoutSettings.keepAlive': 'Enable Page Cache (Keep Alive)',\n};\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAO,gBAAQ;AAAA,EACb,yCAAyC;AAAA,EACzC,qCAAqC;AAAA,EACrC,sCAAsC;AAAA,EACtC,uDAAuD;AAAA,EACvD,iDAAiD;AAAA,EACjD,+CAA+C;AAAA,EAC/C,gDAAgD;AAAA,EAChD,6CAA6C;AAAA,EAC7C,2DAA2D;AAAA,EAC3D,4DAA4D;AAAA,EAC5D,yDAAyD;AAAA,EACzD,iDAAiD;AAAA,EACjD,yDAAyD;AAAA,EACzD,sDAAsD;AAAA,EACtD,gDAAgD;AAAA,EAChD,0CAA0C;AAAA,EAC1C,kDAAkD;AAAA,EAClD,uDAAuD;AAAA,EACvD,2DAA2D;AAAA,EAC3D,6DAA6D;AAAA,EAC7D,4CAA4C;AAAA,EAC5C,sDAAsD;AACxD;",
6
6
  "names": []
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zh_CN.d.ts","sourceRoot":"","sources":["../../src/locales/zh_CN.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAuBE"}
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
16
16
  };
17
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
18
 
19
- // src/locales/zh-CN.ts
19
+ // src/locales/zh_CN.ts
20
20
  var zh_CN_exports = {};
21
21
  __export(zh_CN_exports, {
22
22
  default: () => zh_CN_default
@@ -46,4 +46,4 @@ var zh_CN_default = {
46
46
  "creek-locale-button.index.jianTiZhongWen": "简体中文",
47
47
  "creek-layout.ActionRender.LayoutSettings.keepAlive": "开启页面缓存 (Keep Alive)"
48
48
  };
49
- //# sourceMappingURL=zh-CN.js.map
49
+ //# sourceMappingURL=zh_CN.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/locales/zh-CN.ts"],
3
+ "sources": ["../../src/locales/zh_CN.ts"],
4
4
  "sourcesContent": ["export default {\n \"creek-keep-alive.index.guanBiDangQian\": \"关闭当前\",\n \"creek-keep-alive.index.guanBiQiTa\": \"关闭其他\",\n \"creek-keep-alive.index.guanBiYouCe\": \"关闭右侧\",\n \"creek-layout.ActionRender.FullScreen.tuiChuQuanPing\": \"退出全屏\",\n \"creek-layout.ActionRender.FullScreen.quanPing\": \"全屏\",\n \"creek-table.components.DensityIcon.kuanSong\": \"宽松\",\n \"creek-table.components.DensityIcon.zhongDeng\": \"中等\",\n \"creek-table.components.DensityIcon.jinCou\": \"紧凑\",\n \"creek-table.components.DensityIcon.biaoGeMiDu(KuanSong)\": \"表格密度 (宽松)\",\n \"creek-table.components.DensityIcon.biaoGeMiDu(ZhongDeng)\": \"表格密度 (中等)\",\n \"creek-table.components.DensityIcon.biaoGeMiDu(JinCou)\": \"表格密度 (紧凑)\",\n \"creek-table.components.DensityIcon.biaoGeMiDu\": \"表格密度\",\n \"creek-table.components.EllipsisTooltip.fuZhiChengGong\": \"复制成功\",\n \"creek-table.components.EllipsisTooltip.fuZhiShiBai\": \"复制失败\",\n \"creek-table.components.EllipsisTooltip.fuZhi\": \"复制\",\n \"creek-table.hooks.useIndexColumn.xuHao\": \"序号\",\n \"creek-layout.ActionRender.LayoutSettings.title\": \"系统设置\",\n \"creek-layout.ActionRender.LayoutSettings.themeColor\": \"主题色\",\n \"creek-layout.ActionRender.LayoutSettings.showFullScreen\": \"展示全屏按钮\",\n \"creek-layout.ActionRender.LayoutSettings.showLocaleButton\": \"展示国际化按钮\",\n \"creek-locale-button.index.jianTiZhongWen\": \"简体中文\",\n \"creek-layout.ActionRender.LayoutSettings.keepAlive\": \"开启页面缓存 (Keep Alive)\"\n};"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAO,gBAAQ;AAAA,EACb,yCAAyC;AAAA,EACzC,qCAAqC;AAAA,EACrC,sCAAsC;AAAA,EACtC,uDAAuD;AAAA,EACvD,iDAAiD;AAAA,EACjD,+CAA+C;AAAA,EAC/C,gDAAgD;AAAA,EAChD,6CAA6C;AAAA,EAC7C,2DAA2D;AAAA,EAC3D,4DAA4D;AAAA,EAC5D,yDAAyD;AAAA,EACzD,iDAAiD;AAAA,EACjD,yDAAyD;AAAA,EACzD,sDAAsD;AAAA,EACtD,gDAAgD;AAAA,EAChD,0CAA0C;AAAA,EAC1C,kDAAkD;AAAA,EAClD,uDAAuD;AAAA,EACvD,2DAA2D;AAAA,EAC3D,6DAA6D;AAAA,EAC7D,4CAA4C;AAAA,EAC5C,sDAAsD;AACxD;",
6
6
  "names": []
package/i18n.config.ts CHANGED
@@ -4,24 +4,27 @@ module.exports = {
4
4
 
5
5
  // 语言包输出的主入口文件路径
6
6
  // 注意:实际生成的翻译文件会存放在该文件同级目录下以文件名命名的文件夹中
7
- // 例如:src/locales/zh-CN.ts -> 生成的文件在 src/locales/zh-CN/ 目录下
8
- localePath: './src/locales/zh-CN.ts',
7
+ // 例如:src/locales/zh_CN.ts -> 生成的文件在 src/locales/zh_CN/ 目录下
8
+ localePath: './src/locales/zh_CN.ts',
9
9
 
10
10
  // 要扫描的文件路径 (Glob)
11
11
  path: 'src/**/*.{ts,tsx,js,jsx}',
12
12
 
13
13
  // 排除的文件/目录
14
- exclude: ['**/node_modules/**', '**/dist/**', '**/.umi/**', '**/locales/**', '**/utils/i18n.ts'],
14
+ exclude: ['**/node_modules/**', '**/dist/**', '**/.umi/**', '**/locales/**'],
15
15
 
16
16
  // 国际化函数名称 (默认为 't')
17
17
  tFunction: 't',
18
18
 
19
19
  // 国际化函数的导入语句
20
- importStatement: 'import { t } from "@/utils/i18n"',
20
+ importStatement: "import { t } from '@creekjs/i18n/react'",
21
21
 
22
22
  // 是否使用目录结构作为命名空间 (默认为 true)
23
23
  useDirectoryAsNamespace: false,
24
24
 
25
25
  // 开启 React Hooks 模式 (useT)
26
26
  useT: true,
27
+
28
+ // useT 的导入语句
29
+ useTImportStatement: "import { useT } from '@creekjs/i18n/react'",
27
30
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@creekjs/web-components",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "keywords": [],
@@ -14,13 +14,13 @@
14
14
  "react-resizable": "^3.1.3",
15
15
  "react-router-dom": "^7.13.0",
16
16
  "zustand": "^5.0.1",
17
- "@creekjs/i18n": "^1.0.1"
17
+ "@creekjs/i18n": "^1.0.2"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@types/lodash": "^4.17.20",
21
21
  "@types/react-resizable": "^3.0.8",
22
22
  "react-intl": "^6.0.0",
23
- "@creekjs/i18n-extract": "^1.0.0"
23
+ "@creekjs/i18n-extract": "^1.0.1"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "react-intl": ">=3.0.0"
@@ -2,10 +2,6 @@ import { createContext } from 'react';
2
2
 
3
3
  export type CreekConfigContextProps = {
4
4
  iconFontCNs?: string[];
5
- /**
6
- * 国际化语言包
7
- */
8
- locale?: Record<string, string>;
9
5
  };
10
6
 
11
7
  export const CreekConfigContext = createContext<CreekConfigContextProps>({});
@@ -1,33 +1,43 @@
1
1
  import type { ReactNode } from 'react';
2
- import { createContext, useCallback, useContext, useEffect, useState } from 'react';
2
+ import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
3
3
 
4
- import { IntlContext, IntlProvider, getIntl, getLocale, setLocale, setLocaleMessages } from '@creekjs/i18n/react';
4
+ import { IntlContext, IntlProvider, appLocales, getIntl, getLocale, setLocale, setLocaleMessages } from '@creekjs/i18n/react';
5
5
 
6
- import enUS from '../locales/en-US';
7
- import zhCN from '../locales/zh-CN';
6
+ import enUS from '../locales/en_US';
7
+ import zhCN from '../locales/zh_CN';
8
8
 
9
- const DEFAULT_LOCALE = 'zh-CN';
9
+ const DEFAULT_LOCALE = 'zh_CN';
10
+
11
+ export type LocaleCode = 'en_US' | 'zh_CN';
12
+
13
+ const SUPPORTED_LOCALES: LocaleCode[] = ['zh_CN', 'en_US'];
14
+
15
+ const toUnderscoreLocale = (input?: string): LocaleCode => {
16
+ if (!input) return DEFAULT_LOCALE;
17
+ const normalized = input.replace('-', '_') as LocaleCode;
18
+ return SUPPORTED_LOCALES.includes(normalized) ? normalized : DEFAULT_LOCALE;
19
+ };
10
20
 
11
21
  export interface CreekI18nProviderProps {
12
22
  children?: ReactNode;
13
23
  /**
14
24
  * 语言标识
15
- * @default 'zh-CN'
25
+ * @default 'zh_CN'
16
26
  */
17
- locale?: string;
27
+ locale?: LocaleCode;
18
28
  /**
19
29
  * 国际化语言包,透传给 react-intl
20
30
  */
21
31
  messages?: Record<string, string>;
22
32
  }
23
33
 
24
- const MESSAGES_MAP: Record<string, Record<string, string>> = {
25
- [DEFAULT_LOCALE]: zhCN,
26
- 'en-US': enUS,
34
+ const MESSAGES_MAP: Record<LocaleCode, Record<string, string>> = {
35
+ zh_CN: zhCN,
36
+ en_US: enUS,
27
37
  };
28
38
 
29
39
  export const LocaleContext = createContext({
30
- locale: getLocale() || DEFAULT_LOCALE,
40
+ locale: toUnderscoreLocale(getLocale()),
31
41
  changeLocale: (lang: string) => {},
32
42
  });
33
43
 
@@ -36,52 +46,70 @@ export const useAppLocale = () => useContext(LocaleContext);
36
46
  export const CreekI18nProvider = (props: CreekI18nProviderProps) => {
37
47
  const { children, locale, messages } = props;
38
48
 
39
- // Try to get parent intl context
49
+ // 获取父级 intl context
40
50
  const parentIntl = useContext(IntlContext);
41
51
 
42
- const [intl, setIntl] = useState(() => getIntl());
52
+ // 内部维护的 locale 状态,仅在调用 changeLocale 时更新
53
+ const [internalLocale, setInternalLocale] = useState<string>();
43
54
 
44
55
  const changeLocale = useCallback((lang: string) => {
45
- setLocale(lang, false);
46
- setIntl(getIntl());
56
+ const underscore = toUnderscoreLocale(lang);
57
+ setLocale(underscore, false);
58
+ setInternalLocale(underscore);
47
59
  }, []);
48
60
 
49
61
  // 1. 确定最终生效的 locale
50
62
  // 优先级:当前组件内部的 state > props.locale > parentIntl.locale > 全局默认
51
- const currentLocale = intl?.locale || locale || parentIntl?.locale || DEFAULT_LOCALE;
63
+ const currentLocale = useMemo(() => {
64
+ const rawLocale = internalLocale || locale || parentIntl?.locale || getIntl()?.locale || DEFAULT_LOCALE;
65
+ return toUnderscoreLocale(rawLocale);
66
+ }, [internalLocale, locale, parentIntl?.locale]);
52
67
 
53
68
  // 2. 提取父级上下文的安全配置 (避免将 IntlShape 的内部方法直接传给 IntlProvider)
54
- const intlConfig = parentIntl || intl || {};
55
- const safeConfig = {
56
- formats: intlConfig.formats,
57
- defaultLocale: intlConfig.defaultLocale,
58
- defaultFormats: intlConfig.defaultFormats,
59
- onError: intlConfig.onError,
60
- };
69
+ const safeConfig = useMemo(() => {
70
+ const intlConfig = parentIntl || getIntl() || {};
71
+ return {
72
+ formats: intlConfig.formats,
73
+ defaultLocale: intlConfig.defaultLocale,
74
+ defaultFormats: intlConfig.defaultFormats,
75
+ onError: intlConfig.onError,
76
+ };
77
+ }, [parentIntl]);
61
78
 
62
79
  // 3. 确定最终的 messages
63
80
  // 避免使用 stale 的 parentIntl.messages
64
- let baseMessages = {};
65
- if (parentIntl && parentIntl.locale === currentLocale) {
66
- baseMessages = parentIntl.messages;
67
- } else {
68
- baseMessages = getIntl()?.messages || {};
69
- }
70
-
71
- const finalMessages = {
72
- ...baseMessages,
73
- ...(MESSAGES_MAP[currentLocale] || zhCN),
74
- ...(messages || {}),
75
- };
81
+ const finalMessages = useMemo(() => {
82
+ let baseMessages: Record<string, any> = {};
83
+ if (parentIntl && parentIntl.locale === currentLocale.replace('_', '-')) {
84
+ baseMessages = parentIntl.messages;
85
+ } else {
86
+ // 优先从 appLocales 中获取对应语言的 messages
87
+ baseMessages = appLocales?.[currentLocale] || getIntl()?.messages || {};
88
+ }
89
+
90
+ return {
91
+ ...baseMessages,
92
+ ...(MESSAGES_MAP[currentLocale] || zhCN),
93
+ ...(messages || {}),
94
+ };
95
+ }, [parentIntl, currentLocale, messages]);
76
96
 
77
97
  // 4. 同步给全局 globalIntl,确保非 React 组件能够拿到
78
98
  useEffect(() => {
79
99
  setLocaleMessages(currentLocale, finalMessages);
80
100
  }, [currentLocale, finalMessages]);
81
101
 
102
+ const contextValue = useMemo(
103
+ () => ({
104
+ locale: currentLocale,
105
+ changeLocale,
106
+ }),
107
+ [currentLocale, changeLocale],
108
+ );
109
+
82
110
  return (
83
- <IntlProvider {...safeConfig} locale={currentLocale} messages={finalMessages}>
84
- <LocaleContext.Provider value={{ locale: currentLocale, changeLocale }}>{children}</LocaleContext.Provider>
111
+ <IntlProvider {...safeConfig} locale={currentLocale.replace('_', '-')} messages={finalMessages}>
112
+ <LocaleContext.Provider value={contextValue}>{children}</LocaleContext.Provider>
85
113
  </IntlProvider>
86
114
  );
87
115
  };
@@ -7,7 +7,12 @@ import merge from 'lodash/merge';
7
7
  import { AppProvider } from '../creek-hooks';
8
8
  import { useLayoutSettingsStore } from '../creek-layout/useLayoutSettingsStore';
9
9
  import { CreekConfigContext, CreekConfigContextProps } from './CreekConfigContext';
10
- import { CreekI18nProvider, CreekI18nProviderProps, LocaleContext, useAppLocale } from './CreekI18nProvider';
10
+ import { CreekI18nProvider, CreekI18nProviderProps, LocaleCode, LocaleContext, useAppLocale } from './CreekI18nProvider';
11
+
12
+ const ANTD_LOCALE_MAP: Record<LocaleCode, any> = {
13
+ zh_CN: zhCN_antd,
14
+ en_US: enUS_antd,
15
+ };
11
16
 
12
17
  export type CreekConfigProviderProps = CreekConfigContextProps & Omit<ConfigProviderProps, 'locale'> & CreekI18nProviderProps;
13
18
 
@@ -33,12 +38,11 @@ const InnerConfigProvider = (props: Omit<CreekConfigProviderProps, 'locale' | 'm
33
38
  colorLinkActive: activeColorPrimary,
34
39
  },
35
40
  }
36
- : {}
41
+ : {},
37
42
  );
38
43
 
39
-
40
44
  return (
41
- <ConfigProvider locale={locale === 'en-US' ? enUS_antd : zhCN_antd} theme={finalTheme} {...more}>
45
+ <ConfigProvider locale={ANTD_LOCALE_MAP[locale] || zhCN_antd} theme={finalTheme} {...more}>
42
46
  <CreekConfigContext.Provider value={more as any}>
43
47
  <App>
44
48
  <AppProvider>{children}</AppProvider>
@@ -4,7 +4,7 @@ import { isRegExp, isString, omit } from 'lodash';
4
4
  import React, { useEffect, useState } from 'react';
5
5
  import { useLocation, useNavigate, useOutlet } from 'react-router-dom';
6
6
 
7
- import { useT } from '@/utils/i18n';
7
+ import { useT } from '@creekjs/i18n/react';
8
8
 
9
9
  export interface CreekKeepAliveProps {
10
10
  /**
@@ -4,7 +4,7 @@ import { Tooltip } from 'antd';
4
4
 
5
5
  import { create } from 'zustand';
6
6
 
7
- import { useT } from '@/utils/i18n';
7
+ import { useT } from '@creekjs/i18n/react';
8
8
 
9
9
  export type FullScreenStore = {
10
10
  isFullScreen: boolean;
@@ -2,10 +2,11 @@ import { ProLayout, ProLayoutProps } from '@ant-design/pro-components';
2
2
  import { useMemoizedFn } from 'ahooks';
3
3
  import { theme } from 'antd';
4
4
  import _ from 'lodash';
5
+ import { useContext } from 'react';
5
6
 
6
7
  import classnames from 'classnames';
7
8
 
8
- import { useT } from '@creekjs/i18n/react';
9
+ import { IntlContext, useT } from '@creekjs/i18n/react';
9
10
 
10
11
  import { CreekKeepAlive, CreekKeepAliveProps } from '../creek-keep-alive';
11
12
  import { CreekLocaleButton } from '../creek-locale-button';
@@ -66,8 +67,12 @@ export const CreekLayout = (props: LayoutProps) => {
66
67
 
67
68
  const _userConfig = { ...userConfig, ...runtimeConfig };
68
69
 
70
+ const intlContext = useContext(IntlContext);
71
+ const hasI18n = !!intlContext;
72
+
69
73
  const menuDataRender = useMemoizedFn((menuData: any[]) => {
70
- const isLocaleEnabled = more.menu?.locale !== false && _userConfig.menu?.locale !== false;
74
+ // 根据当前是否开启了国际化(上下文是否存在)以及用户配置来判断是否包裹菜单翻译
75
+ const isLocaleEnabled = hasI18n;
71
76
 
72
77
  const mapMenu = (items: any[]): any[] => {
73
78
  return items.map((item) => {
@@ -12,14 +12,14 @@ export const CreekLocaleButton = () => {
12
12
 
13
13
  const items = [
14
14
  {
15
- key: 'zh-CN',
15
+ key: 'zh_CN',
16
16
  label: t('creek-locale-button.index.jianTiZhongWen', '简体中文'),
17
- disabled: locale === 'zh-CN',
17
+ disabled: locale === 'zh_CN',
18
18
  },
19
19
  {
20
- key: 'en-US',
20
+ key: 'en_US',
21
21
  label: 'English',
22
- disabled: locale === 'en-US',
22
+ disabled: locale === 'en_US',
23
23
  },
24
24
  ];
25
25
 
@@ -3,7 +3,7 @@ import { ProTableProps } from '@ant-design/pro-components';
3
3
  import { Dropdown, MenuProps, Tooltip } from 'antd';
4
4
  import React from 'react';
5
5
 
6
- import { useT } from '@/utils/i18n';
6
+ import { useT } from '@creekjs/i18n/react';
7
7
 
8
8
  export type SizeType = ProTableProps<any, any>['size'];
9
9
 
@@ -3,7 +3,7 @@ import { ConfigProvider, Flex, Tooltip, Typography, message } from 'antd';
3
3
  import { createStyles } from 'antd-style';
4
4
  import React, { useContext, useEffect, useRef, useState } from 'react';
5
5
 
6
- import { useT } from '@/utils/i18n';
6
+ import { useT } from '@creekjs/i18n/react';
7
7
 
8
8
  const useStyles = createStyles(({ css, token }) => {
9
9
  return {
@@ -1,7 +1,7 @@
1
1
  import { ProColumns } from '@ant-design/pro-components';
2
2
  import { useMemo } from 'react';
3
3
 
4
- import { useT } from '@/utils/i18n';
4
+ import { useT } from '@creekjs/i18n/react';
5
5
 
6
6
  export const useIndexColumn = <T = any, ValueType = 'text'>(columns: ProColumns<T, ValueType>[] = [], showIndex: boolean = true) => {
7
7
  const t = useT();
@@ -1 +0,0 @@
1
- {"version":3,"file":"en-US.d.ts","sourceRoot":"","sources":["../../src/locales/en-US.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAuBE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"zh-CN.d.ts","sourceRoot":"","sources":["../../src/locales/zh-CN.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAuBE"}
@@ -1,2 +0,0 @@
1
- import { setLocaleMessages, t, useT } from '@creekjs/i18n/react';
2
- export { setLocaleMessages, t, useT };
@@ -1 +0,0 @@
1
- {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/utils/i18n.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC"}
@@ -1,34 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
-
19
- // src/utils/i18n.ts
20
- var i18n_exports = {};
21
- __export(i18n_exports, {
22
- setLocaleMessages: () => import_react.setLocaleMessages,
23
- t: () => import_react.t,
24
- useT: () => import_react.useT
25
- });
26
- module.exports = __toCommonJS(i18n_exports);
27
- var import_react = require("@creekjs/i18n/react");
28
- // Annotate the CommonJS export names for ESM import in node:
29
- 0 && (module.exports = {
30
- setLocaleMessages,
31
- t,
32
- useT
33
- });
34
- //# sourceMappingURL=i18n.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/utils/i18n.ts"],
4
- "sourcesContent": ["import { setLocaleMessages, t, useT } from '@creekjs/i18n/react';\n\nexport { setLocaleMessages, t, useT };\n\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA2C;",
6
- "names": []
7
- }
package/src/utils/i18n.ts DELETED
@@ -1,4 +0,0 @@
1
- import { setLocaleMessages, t, useT } from '@creekjs/i18n/react';
2
-
3
- export { setLocaleMessages, t, useT };
4
-
File without changes
File without changes
File without changes
File without changes