dsh-plugin-core-demo 0.1.2 → 0.1.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 (2) hide show
  1. package/dist/client.js +330 -203
  2. package/package.json +1 -1
package/dist/client.js CHANGED
@@ -1046,6 +1046,12 @@ var DICT = {
1046
1046
  }
1047
1047
  };
1048
1048
  var current2 = "zh";
1049
+ function setLocale(locale) {
1050
+ current2 = locale;
1051
+ }
1052
+ function getLocale() {
1053
+ return current2;
1054
+ }
1049
1055
  function t(key, vars) {
1050
1056
  const template = DICT[current2][key] ?? DICT.zh[key] ?? key;
1051
1057
  if (vars === void 0)
@@ -1742,11 +1748,255 @@ function NumberInput(props) {
1742
1748
  );
1743
1749
  }
1744
1750
 
1745
- // demo/sections/index.tsx
1751
+ // dist/utils/date.js
1752
+ function pad2(value) {
1753
+ return String(value).padStart(2, "0");
1754
+ }
1755
+ var FALLBACK = "\u2014";
1756
+ function formatDateTime(iso, opts) {
1757
+ const ms = Date.parse(iso);
1758
+ if (Number.isNaN(ms))
1759
+ return opts?.fallback ?? iso;
1760
+ const d = new Date(ms);
1761
+ const base = `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())} ${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
1762
+ return opts?.seconds === true ? `${base}:${pad2(d.getSeconds())}` : base;
1763
+ }
1764
+ function formatYmd(iso, opts) {
1765
+ const ms = Date.parse(iso);
1766
+ if (Number.isNaN(ms))
1767
+ return opts?.fallback ?? FALLBACK;
1768
+ const d = new Date(ms);
1769
+ return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
1770
+ }
1771
+ function formatClock(iso, opts) {
1772
+ const fb = opts?.fallback ?? "-";
1773
+ if (iso === null || iso === void 0 || iso === "")
1774
+ return fb;
1775
+ const ms = Date.parse(iso);
1776
+ if (Number.isNaN(ms))
1777
+ return fb;
1778
+ const d = new Date(ms);
1779
+ return `${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}`;
1780
+ }
1781
+ function formatDurationHms(ms) {
1782
+ if (!Number.isFinite(ms) || ms < 0)
1783
+ return "-";
1784
+ const totalSec = Math.round(ms / 1e3);
1785
+ const h31 = Math.floor(totalSec / 3600);
1786
+ const m = Math.floor(totalSec % 3600 / 60);
1787
+ const s = totalSec % 60;
1788
+ return h31 > 0 ? `${h31}:${pad2(m)}:${pad2(s)}` : `${pad2(m)}:${pad2(s)}`;
1789
+ }
1790
+ function sameCalendarDay(a, b) {
1791
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
1792
+ }
1793
+ function relativePast(iso, nowMs, translate) {
1794
+ const tt = translate ?? t;
1795
+ const diff = nowMs - Date.parse(iso);
1796
+ if (Number.isNaN(diff) || !(diff >= 0))
1797
+ return tt("relNow");
1798
+ if (diff < 6e4)
1799
+ return tt("relJustNow");
1800
+ const minutes = Math.floor(diff / 6e4);
1801
+ if (minutes < 60)
1802
+ return tt("relMinutesAgo", { n: minutes });
1803
+ const hours = Math.floor(minutes / 60);
1804
+ if (hours < 24)
1805
+ return tt("relHoursAgo", { n: hours });
1806
+ const days = Math.floor(hours / 24);
1807
+ if (days < 7)
1808
+ return tt("relDaysAgo", { n: days });
1809
+ if (days < 30)
1810
+ return tt("relWeeksAgo", { n: Math.floor(days / 7) });
1811
+ const months = Math.floor(days / 30);
1812
+ if (months < 12)
1813
+ return tt("relMonthsAgo", { n: months });
1814
+ return tt("relYearsAgo", { n: Math.floor(days / 365) });
1815
+ }
1816
+ function relativeFuture(iso, nowMs, translate) {
1817
+ const tt = translate ?? t;
1818
+ const diff = Date.parse(iso) - nowMs;
1819
+ if (Number.isNaN(diff))
1820
+ return formatYmd(iso);
1821
+ if (diff <= 0)
1822
+ return tt("relNow");
1823
+ if (diff < 6e4)
1824
+ return tt("relInJustNow");
1825
+ const minutes = Math.floor(diff / 6e4);
1826
+ if (minutes < 60)
1827
+ return tt("relInMinutes", { n: minutes });
1828
+ const hours = Math.floor(minutes / 60);
1829
+ if (hours < 24)
1830
+ return tt("relInHours", { n: hours });
1831
+ const days = Math.floor(hours / 24);
1832
+ if (days < 30)
1833
+ return tt("relInDays", { n: days });
1834
+ const months = Math.floor(days / 30);
1835
+ if (months < 12)
1836
+ return tt("relInMonths", { n: months });
1837
+ return tt("relInYears", { n: Math.floor(days / 365) });
1838
+ }
1839
+ function formatRange(fromIso, toIso, opts) {
1840
+ const from = Date.parse(fromIso);
1841
+ const to = Date.parse(toIso);
1842
+ if (Number.isNaN(from) || Number.isNaN(to))
1843
+ return FALLBACK;
1844
+ const a = new Date(from);
1845
+ const b = new Date(to);
1846
+ const clock = (d) => opts?.seconds === true ? `${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}` : `${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
1847
+ if (sameCalendarDay(a, b))
1848
+ return `${clock(a)} \u2013 ${clock(b)}`;
1849
+ const day = (d) => `${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
1850
+ return `${day(a)} ${clock(a)} \u2013 ${day(b)} ${clock(b)}`;
1851
+ }
1852
+
1853
+ // dist/utils/number.js
1854
+ function formatBytes(bytes) {
1855
+ if (!Number.isFinite(bytes) || bytes <= 0)
1856
+ return "\u2014";
1857
+ if (bytes < 1024)
1858
+ return `${bytes} B`;
1859
+ const units = ["KB", "MB", "GB", "TB"];
1860
+ let value = bytes / 1024;
1861
+ let unit = 0;
1862
+ while (value >= 1024 && unit < units.length - 1) {
1863
+ value /= 1024;
1864
+ unit++;
1865
+ }
1866
+ return `${value >= 10 ? String(Math.round(value)) : value.toFixed(1)} ${units[unit]}`;
1867
+ }
1868
+
1869
+ // dist/utils/path.js
1870
+ var IMAGE_EXT = {
1871
+ png: "image/png",
1872
+ jpg: "image/jpeg",
1873
+ jpeg: "image/jpeg",
1874
+ gif: "image/gif",
1875
+ webp: "image/webp",
1876
+ bmp: "image/bmp",
1877
+ svg: "image/svg+xml",
1878
+ ico: "image/x-icon"
1879
+ };
1880
+ function mimeOf(path) {
1881
+ const ext = extOf(path);
1882
+ return ext === "" ? void 0 : IMAGE_EXT[ext];
1883
+ }
1884
+ function extOf(path) {
1885
+ const name = path.slice(path.lastIndexOf("/") + 1);
1886
+ const dot = name.lastIndexOf(".");
1887
+ return dot <= 0 ? "" : name.slice(dot + 1).toLowerCase();
1888
+ }
1889
+ function crumbsOf(path) {
1890
+ return path.split("/").filter((s) => s !== "");
1891
+ }
1892
+ function parentOf(path) {
1893
+ const cut = path.lastIndexOf("/");
1894
+ return cut < 0 ? "" : path.slice(0, cut);
1895
+ }
1896
+ function joinPath(dir, name) {
1897
+ return dir === "" ? name : `${dir}/${name}`;
1898
+ }
1899
+
1900
+ // packages/demo/src/sections/index.tsx
1746
1901
  var import_react30 = require("react");
1747
1902
 
1748
- // demo/sections/design.tsx
1903
+ // packages/demo/src/sections/design.tsx
1749
1904
  var import_react19 = require("react");
1905
+
1906
+ // packages/demo/src/i18n.ts
1907
+ var DICT2 = {
1908
+ zh: {
1909
+ sessionHint: "\u4E09\u79CD\u627F\u8F7D\uFF1Amodal / sidebar / page\uFF1Bsource \u662F mock \u7684\uFF1BrenderMessage \u53EF\u63A5\u7BA1\u5BCC\u5185\u5BB9",
1910
+ explorerHint: "\u9762\u5305\u5C51 + \u76EE\u5F55\u6811 + \u9884\u89C8\uFF1BworkspaceFiles \u662F mock \u7684\uFF08\u771F\u5B9E\u63D2\u4EF6\u4ECE ctx \u53D6\u51FA\u540E\u6CE8\u5165\uFF09",
1911
+ utilsHint: "\u89E3\u6790\u5931\u8D25\u4E0D\u629B\u9519\u3001\u7ED9\u515C\u5E95\u3001\u4E0D\u7F16\u9020\uFF1B\u6240\u6709\u51FD\u6570\u65E0 UI \u4F9D\u8D56",
1912
+ displayCardHint: "\u6392\u7248\u5B8C\u5168\u7531\u8C03\u7528\u65B9\u51B3\u5B9A\u2014\u2014\u771F\u5B9E\u63D2\u4EF6\u7684\u5F62\u6001\uFF1A\u6807\u9898\u884C + \u53F3\u4FA7\u5143\u4FE1\u606F + chips \u884C\uFF1Baccent \u4E94\u6863\u89C1\u4E0B\u65B9\u901F\u89C8",
1913
+ displayStripHint: "\u540C\u4E00\u4E2A\u8272\u6761\u673A\u5236\uFF0C\u5916\u89C2\u662F\u901A\u9AD8\u8D34\u9876\u5230\u5E95\u2014\u2014\u771F\u5B9E\u63D2\u4EF6\u7684\u5F62\u6001\uFF1A\u6807\u9898 + \u5143\u4FE1\u606F\u884C + \u53F3\u4FA7\u65F6\u95F4/\u64CD\u4F5C",
1914
+ displayChipHint: "chip \u53EA\u6709\u300C\u80F6\u56CA\u6807\u7B7E\u300D\u4E00\u5957\u76AE\u80A4\uFF1A\u5BBD\u5EA6\u6309\u6587\u5B57\u6491\u5F00\u3001\u4E0D\u6362\u884C\uFF1B\u6700\u540E\u4E00\u9897\u662F\u957F\u6587\u5B57\uFF0C\u82E5\u88AB\u538B\u6210 28px \u7AD6\u6392\u5C31\u662F\u53C8\u6DF7\u8FDB\u4E86\u56FE\u6807\u6309\u94AE\u7684\u5B9A\u5BBD\u89C4\u5219",
1915
+ feedbackModalHint: "\u81EA\u7ED8 overlay\uFF08\u4E0D\u7528 portal\uFF09\uFF1B\u70B9\u906E\u7F69 / Esc / \u2715 \u90FD\u80FD\u5173\u3002\u6807\u9898\u680F\u7684 \u2715 \u662F 24\xD724 \u56FE\u6807\u4F4D\uFF0C\u4E0D\u8BE5\u51FA\u73B0\u8FB9\u6846\u6216 120px \u5BBD\u7684\u5E95\u8272\u5757",
1916
+ feedbackToastHint: "\u547D\u4EE4\u5F0F showToast\uFF0C\u4E0D\u8981\u6C42\u6302\u7EC4\u4EF6",
1917
+ pickerHint: "\u5355\u9009 / \u591A\u9009 / \u4E0A\u9650 / \u641C\u7D22 / \u5206\u7EC4 / \u7A7A\u6001 / \u964D\u7EA7\u2014\u2014\u5168\u90E8\u53EF\u7528 props \u63A7\u5236",
1918
+ modelPickerHint: "flat \u4E00\u4E2A\u4E0B\u62C9 / cascade \u5148\u9009\u4F9B\u5E94\u5546\u518D\u9009\u6A21\u578B\u2014\u2014\u540C\u4E00\u4EFD\u6570\u636E\u4E24\u79CD\u5F62\u6001",
1919
+ workspacePickerHint: "\u6570\u636E\u8C03\u7528\u65B9\u7ED9\uFF08\u8981\u8DE8 host\u2194client \u8FB9\u754C\uFF0C\u7EC4\u4EF6\u53D6\u4E0D\u5230\uFF09",
1920
+ buttonHint: "variant \u56DB\u6863 \xD7 size \u4E09\u6863",
1921
+ inputHint: "Input / PrefixedInput / NumberInput / Textarea\uFF0C\u90FD\u652F\u6301 error \u63CF\u7EA2\uFF1B\u884C\u5C3E\u53EF\u6302 FieldHint \u95EE\u53F7\u63D0\u793A",
1922
+ checkboxHint: "\u5916\u89C2\u5BF9\u9F50\u771F\u5B9E\u63D2\u4EF6\uFF1A\u7070\u5E95 inset\uFF08\u65E0\u5916\u63CF\u8FB9\uFF09\uFF1B\u5E26\u63CF\u8FB9\u7684 default \u4EC5\u4F9B\u7279\u6B8A\u573A\u5408\uFF0C\u89C1\u4E0B",
1923
+ designTokenHint: "\u989C\u8272\u5168\u90E8\u6765\u81EA design \u7684 token\uFF1B\u5207\u6362\u53F3\u4E0A\u89D2\u660E\u6697\uFF0C\u4E0B\u9762\u4F1A\u8DDF\u7740\u53D8",
1924
+ designInjectHint: "\u63A7\u4EF6\u6E32\u67D3\u524D\u8C03\u4E00\u6B21 setStyleKit + ensureControls\uFF0Ctoken \u4E0E\u63A7\u4EF6 CSS \u7531 kit \u6CE8\u5165 <head>",
1925
+ fieldHintDate: "\u4EFB\u52A1\u81EA\u8BE5\u65E5\u8D77\u5F00\u59CB\u6267\u884C\u3002\u53EF\u63D0\u524D\u521B\u5EFA\u4EFB\u52A1\uFF0C\u81F3\u8BE5\u65E5\u81EA\u52A8\u5F00\u8DD1\uFF1B\u300C\u6BCF N \u5468\u300D\u4EA6\u81EA\u8BE5\u65E5\u8D77\u7B97\u9996\u5468\u3002",
1926
+ loadingNote: "Loading \u662F\u8D34\u5230\u4E3B\u5BB9\u5668\u53F3\u4E0B\u89D2\u7684\u6307\u793A\u5668\uFF08anchorId \u9ED8\u8BA4 dsh-tdt-main\uFF09\uFF0C\u6B64\u5904\u4E0D\u6E32\u67D3\u4EE5\u514D\u906E\u6321\u3002",
1927
+ secDesign: "\u8BBE\u8BA1\u57FA\u7840",
1928
+ secButtons: "\u6309\u94AE\u4E0E\u8F93\u5165",
1929
+ secPickers: "\u9009\u62E9\u5668",
1930
+ secFeedback: "\u5F39\u7A97\u4E0E\u53CD\u9988",
1931
+ secDisplay: "\u5361\u7247\u4E0E\u5C55\u793A",
1932
+ secUtils: "\u901A\u7528\u65B9\u6CD5",
1933
+ secExplorer: "\u5DE5\u4F5C\u533A\u6D4F\u89C8",
1934
+ secSession: "\u4F1A\u8BDD\u9884\u89C8",
1935
+ demoTokenPalette: "token \u8272\u677F",
1936
+ demoStyleInject: "\u6837\u5F0F\u6CE8\u5165\u673A\u5236",
1937
+ demoInputFamily: "Input \u5BB6\u65CF",
1938
+ demoUtilsTitle: "\u65E5\u671F / \u5B57\u7B26\u4E32 / \u5B57\u8282",
1939
+ demoCardTitle: "Card\uFF08\u5706\u89D2 + \u8FB9\u6846 + \u77ED\u8272\u6761\uFF09",
1940
+ demoStripTitle: "StripCard\uFF08\u65E0\u8FB9\u6846 + \u901A\u9AD8\u7AD6\u7EBF\uFF09",
1941
+ designInjectNote: "\u672C\u9884\u89C8\u63D2\u4EF6\u81EA\u5DF1\u5C31\u662F\u8FD9\u4E48\u505A\u521D\u59CB\u5316\u7684\u2014\u2014\u9884\u89C8\u4E0E\u771F\u5B9E\u63D2\u4EF6\u8D70\u540C\u4E00\u6761\u8DEF\u3002",
1942
+ pluginTitle: "\u7EC4\u4EF6\u9884\u89C8",
1943
+ pluginCardDesc: "\u6253\u5F00 dsh-plugin-core \u7684\u63A7\u4EF6\u4E0E\u4E1A\u52A1\u7EC4\u4EF6\u5C55\u793A\u9875",
1944
+ pluginCardOpen: "\u6253\u5F00 \u203A"
1945
+ },
1946
+ en: {
1947
+ sessionHint: "Three carriers: modal / sidebar / page; source is mocked; renderMessage can take over rich content",
1948
+ explorerHint: "Breadcrumb + directory tree + preview; workspaceFiles is mocked (a real plugin reads it from ctx and injects)",
1949
+ utilsHint: "No throw on parse failure \u2014 falls back gracefully and never fabricates; all functions are UI-free",
1950
+ displayCardHint: "Layout is entirely up to the caller \u2014 the real-plugin shape: title row + right-side meta + chips row; five accent tiers below",
1951
+ displayStripHint: "Same accent-bar mechanism, but full-height edge-to-edge \u2014 real-plugin shape: title + meta row + right-side time/actions",
1952
+ displayChipHint: "Chip has one pill skin only: width hugs the text, no wrap; the last one is long text \u2014 if squeezed into a 28px vertical stack, the icon-button fixed-width rule crept back in",
1953
+ feedbackModalHint: "Hand-rolled overlay (no portal); click backdrop / Esc / \u2715 all close it. The header \u2715 is a 24\xD724 icon slot \u2014 no border or 120px-wide color block should appear",
1954
+ feedbackToastHint: "Imperative showToast \u2014 no component mounting required",
1955
+ pickerHint: "Single / multi / max / search / grouped / empty / degraded \u2014 all driven by props",
1956
+ modelPickerHint: "flat: one dropdown / cascade: pick provider then model \u2014 same data, two shapes",
1957
+ workspacePickerHint: "Data is supplied by the caller (crosses the host\u2194client boundary; the component cannot fetch it)",
1958
+ buttonHint: "Four variants \xD7 three sizes",
1959
+ inputHint: "Input / PrefixedInput / NumberInput / Textarea, all support error highlighting; a FieldHint question-mark tip can hang at the row end",
1960
+ checkboxHint: "Looks match the real plugin: grey inset background (no outer border); the bordered default is for special cases only, see below",
1961
+ designTokenHint: "All colors come from design tokens; switch light/dark at top-right and these update with it",
1962
+ designInjectHint: "Call setStyleKit + ensureControls once before controls render; the kit injects tokens and control CSS into <head>",
1963
+ fieldHintDate: 'The task runs starting from this date. You can create it ahead of time and it auto-starts on that day; "every N weeks" also counts its first week from this date.',
1964
+ loadingNote: "Loading is an indicator pinned to the bottom-right of the main container (anchorId defaults to dsh-tdt-main); not rendered here to avoid covering content.",
1965
+ secDesign: "Design basics",
1966
+ secButtons: "Buttons & inputs",
1967
+ secPickers: "Pickers",
1968
+ secFeedback: "Modal & feedback",
1969
+ secDisplay: "Cards & display",
1970
+ secUtils: "Utilities",
1971
+ secExplorer: "Workspace browsing",
1972
+ secSession: "Session preview",
1973
+ demoTokenPalette: "Token palette",
1974
+ demoStyleInject: "Style injection",
1975
+ demoInputFamily: "Input family",
1976
+ demoUtilsTitle: "Date / String / Bytes",
1977
+ demoCardTitle: "Card (rounded + border + accent bar)",
1978
+ demoStripTitle: "StripCard (borderless + full-height stripe)",
1979
+ designInjectNote: "This preview plugin initializes itself exactly this way \u2014 preview and real plugin take the same path.",
1980
+ pluginTitle: "Component preview",
1981
+ pluginCardDesc: "Open the showcase of dsh-plugin-core controls and business components",
1982
+ pluginCardOpen: "Open \u203A"
1983
+ }
1984
+ };
1985
+ var boundT;
1986
+ function setDemoTranslate(fn) {
1987
+ boundT = fn;
1988
+ }
1989
+ function t2(key, vars) {
1990
+ if (boundT !== void 0) return boundT(key, vars);
1991
+ const template = DICT2[getLocale()][key] ?? DICT2.zh[key] ?? key;
1992
+ if (vars === void 0) return template;
1993
+ return template.replace(/\{(\w+)\}/g, (whole, name) => {
1994
+ const value = vars[name];
1995
+ return value === void 0 ? whole : String(value);
1996
+ });
1997
+ }
1998
+
1999
+ // packages/demo/src/sections/design.tsx
1750
2000
  var TOKENS = [
1751
2001
  { label: "business", cssVar: "--tdt-business" },
1752
2002
  { label: "success", cssVar: "--tdt-success" },
@@ -1766,24 +2016,24 @@ function DesignSection() {
1766
2016
  null,
1767
2017
  (0, import_react19.createElement)(
1768
2018
  Demo,
1769
- { title: "token \u8272\u677F", hint: "\u989C\u8272\u5168\u90E8\u6765\u81EA design \u7684 token\uFF1B\u5207\u6362\u53F3\u4E0A\u89D2\u660E\u6697\uFF0C\u4E0B\u9762\u4F1A\u8DDF\u7740\u53D8" },
2019
+ { title: t2("demoTokenPalette"), hint: t2("designTokenHint") },
1770
2020
  (0, import_react19.createElement)(
1771
2021
  "div",
1772
2022
  { style: { display: "flex", flexWrap: "wrap", gap: "10px" } },
1773
2023
  TOKENS.map(
1774
- (t2) => (0, import_react19.createElement)(
2024
+ (t3) => (0, import_react19.createElement)(
1775
2025
  "div",
1776
- { key: t2.cssVar, style: { width: "104px" } },
2026
+ { key: t3.cssVar, style: { width: "104px" } },
1777
2027
  (0, import_react19.createElement)("div", {
1778
2028
  style: {
1779
2029
  height: "40px",
1780
2030
  borderRadius: "6px",
1781
- background: `var(${t2.cssVar})`,
2031
+ background: `var(${t3.cssVar})`,
1782
2032
  border: "1px solid var(--tdt-border-faint)"
1783
2033
  }
1784
2034
  }),
1785
- (0, import_react19.createElement)("div", { style: { fontSize: "11px", marginTop: "4px" } }, t2.label),
1786
- (0, import_react19.createElement)("div", { style: { fontSize: "10px", color: "var(--tdt-fg-4)" } }, t2.cssVar)
2035
+ (0, import_react19.createElement)("div", { style: { fontSize: "11px", marginTop: "4px" } }, t3.label),
2036
+ (0, import_react19.createElement)("div", { style: { fontSize: "10px", color: "var(--tdt-fg-4)" } }, t3.cssVar)
1787
2037
  )
1788
2038
  )
1789
2039
  )
@@ -1791,8 +2041,8 @@ function DesignSection() {
1791
2041
  (0, import_react19.createElement)(
1792
2042
  Demo,
1793
2043
  {
1794
- title: "\u6837\u5F0F\u6CE8\u5165\u673A\u5236",
1795
- hint: "\u63A7\u4EF6\u6E32\u67D3\u524D\u8C03\u4E00\u6B21 setStyleKit + ensureControls\uFF0Ctoken \u4E0E\u63A7\u4EF6 CSS \u7531 kit \u6CE8\u5165 <head>",
2044
+ title: t2("demoStyleInject"),
2045
+ hint: t2("designInjectHint"),
1796
2046
  code: `import { createStyleKit } from 'dsh-plugin-core/design'
1797
2047
  import { ensureControls, setStyleKit } from 'dsh-plugin-core/ui'
1798
2048
 
@@ -1802,13 +2052,13 @@ ensureControls()`
1802
2052
  (0, import_react19.createElement)(
1803
2053
  "div",
1804
2054
  { style: { color: "var(--tdt-fg-3)", fontSize: "12px" } },
1805
- "\u672C\u9884\u89C8\u7AD9\u81EA\u5DF1\u5C31\u662F\u8FD9\u4E48\u505A\u521D\u59CB\u5316\u7684\uFF08\u89C1 demo/main.tsx\uFF09\u2014\u2014\u9884\u89C8\u4E0E\u771F\u5B9E\u63D2\u4EF6\u8D70\u540C\u4E00\u6761\u8DEF\u3002"
2055
+ t2("designInjectNote")
1806
2056
  )
1807
2057
  )
1808
2058
  );
1809
2059
  }
1810
2060
 
1811
- // demo/sections/buttons.tsx
2061
+ // packages/demo/src/sections/buttons.tsx
1812
2062
  var import_react20 = require("react");
1813
2063
  function ButtonsSection() {
1814
2064
  const [text, setText] = (0, import_react20.useState)("");
@@ -1822,7 +2072,7 @@ function ButtonsSection() {
1822
2072
  null,
1823
2073
  (0, import_react20.createElement)(
1824
2074
  Demo,
1825
- { title: "Button", hint: "variant \u56DB\u6863 \xD7 size \u4E09\u6863" },
2075
+ { title: "Button", hint: t2("buttonHint") },
1826
2076
  (0, import_react20.createElement)(
1827
2077
  "div",
1828
2078
  { style: { display: "flex", gap: "8px", flexWrap: "wrap", alignItems: "center" } },
@@ -1837,7 +2087,7 @@ function ButtonsSection() {
1837
2087
  ),
1838
2088
  (0, import_react20.createElement)(
1839
2089
  Demo,
1840
- { title: "Input \u5BB6\u65CF", hint: "Input / PrefixedInput / NumberInput / Textarea\uFF0C\u90FD\u652F\u6301 error \u63CF\u7EA2\uFF1B\u884C\u5C3E\u53EF\u6302 FieldHint \u95EE\u53F7\u63D0\u793A" },
2090
+ { title: t2("demoInputFamily"), hint: t2("inputHint") },
1841
2091
  (0, import_react20.createElement)(
1842
2092
  "div",
1843
2093
  { style: { display: "flex", flexDirection: "column", gap: "10px", maxWidth: "380px" } },
@@ -1846,7 +2096,7 @@ function ButtonsSection() {
1846
2096
  { style: { display: "flex", alignItems: "center", gap: "6px" } },
1847
2097
  (0, import_react20.createElement)("span", { style: { color: "var(--tdt-fg-2)", fontSize: "13px", flex: "none" } }, "\u5F00\u59CB\u65F6\u95F4"),
1848
2098
  (0, import_react20.createElement)(Input, { value: text, onChange: setText, placeholder: "\u9009\u62E9\u65E5\u671F" }),
1849
- (0, import_react20.createElement)(FieldHint, { text: "\u4EFB\u52A1\u81EA\u8BE5\u65E5\u8D77\u5F00\u59CB\u6267\u884C\u3002\u53EF\u63D0\u524D\u521B\u5EFA\u4EFB\u52A1\uFF0C\u81F3\u8BE5\u65E5\u81EA\u52A8\u5F00\u8DD1\uFF1B\u300C\u6BCF N \u5468\u300D\u4EA6\u81EA\u8BE5\u65E5\u8D77\u7B97\u9996\u5468\u3002" })
2099
+ (0, import_react20.createElement)(FieldHint, { text: t2("fieldHintDate") })
1850
2100
  ),
1851
2101
  (0, import_react20.createElement)(Input, { value: "bad value", onChange: () => {
1852
2102
  }, error: true, placeholder: "\u6821\u9A8C\u5931\u8D25\u6001" }),
@@ -1856,7 +2106,7 @@ function ButtonsSection() {
1856
2106
  ),
1857
2107
  (0, import_react20.createElement)(
1858
2108
  Demo,
1859
- { title: "Checkbox / Segmented", hint: "\u5916\u89C2\u5BF9\u9F50\u771F\u5B9E\u63D2\u4EF6\uFF1A\u7070\u5E95 inset\uFF08\u65E0\u5916\u63CF\u8FB9\uFF09\uFF1B\u5E26\u63CF\u8FB9\u7684 default \u4EC5\u4F9B\u7279\u6B8A\u573A\u5408\uFF0C\u89C1\u4E0B" },
2109
+ { title: "Checkbox / Segmented", hint: t2("checkboxHint") },
1860
2110
  (0, import_react20.createElement)(
1861
2111
  "div",
1862
2112
  { style: { display: "flex", flexDirection: "column", gap: "14px", alignItems: "flex-start" } },
@@ -1934,7 +2184,7 @@ function ButtonsSection() {
1934
2184
  );
1935
2185
  }
1936
2186
 
1937
- // demo/sections/pickers.tsx
2187
+ // packages/demo/src/sections/pickers.tsx
1938
2188
  var import_react21 = require("react");
1939
2189
  var MODELS = [
1940
2190
  {
@@ -1962,7 +2212,7 @@ function PickersSection() {
1962
2212
  null,
1963
2213
  (0, import_react21.createElement)(
1964
2214
  Demo,
1965
- { title: "Picker", hint: "\u5355\u9009 / \u591A\u9009 / \u4E0A\u9650 / \u641C\u7D22 / \u5206\u7EC4 / \u7A7A\u6001 / \u964D\u7EA7\u2014\u2014\u5168\u90E8\u53EF\u7528 props \u63A7\u5236" },
2215
+ { title: "Picker", hint: t2("pickerHint") },
1966
2216
  (0, import_react21.createElement)(
1967
2217
  "div",
1968
2218
  { style: { display: "flex", gap: "12px", flexWrap: "wrap", alignItems: "flex-start" } },
@@ -1997,7 +2247,7 @@ function PickersSection() {
1997
2247
  ),
1998
2248
  (0, import_react21.createElement)(
1999
2249
  Demo,
2000
- { title: "ModelPicker", hint: "flat \u4E00\u4E2A\u4E0B\u62C9 / cascade \u5148\u9009\u4F9B\u5E94\u5546\u518D\u9009\u6A21\u578B\u2014\u2014\u540C\u4E00\u4EFD\u6570\u636E\u4E24\u79CD\u5F62\u6001" },
2250
+ { title: "ModelPicker", hint: t2("modelPickerHint") },
2001
2251
  (0, import_react21.createElement)(
2002
2252
  "div",
2003
2253
  { style: { display: "flex", gap: "12px", flexWrap: "wrap" } },
@@ -2007,7 +2257,7 @@ function PickersSection() {
2007
2257
  ),
2008
2258
  (0, import_react21.createElement)(
2009
2259
  Demo,
2010
- { title: "WorkspacePicker / FilePicker", hint: "\u6570\u636E\u8C03\u7528\u65B9\u7ED9\uFF08\u8981\u8DE8 host\u2194client \u8FB9\u754C\uFF0C\u7EC4\u4EF6\u53D6\u4E0D\u5230\uFF09" },
2260
+ { title: "WorkspacePicker / FilePicker", hint: t2("workspacePickerHint") },
2011
2261
  (0, import_react21.createElement)(
2012
2262
  "div",
2013
2263
  { style: { display: "flex", gap: "12px", flexWrap: "wrap" } },
@@ -2028,7 +2278,7 @@ function PickersSection() {
2028
2278
  );
2029
2279
  }
2030
2280
 
2031
- // demo/sections/feedback.tsx
2281
+ // packages/demo/src/sections/feedback.tsx
2032
2282
  var import_react22 = require("react");
2033
2283
  function Boom() {
2034
2284
  throw new Error("\u6F14\u793A\uFF1A\u5B50\u7EC4\u4EF6\u629B\u9519\u88AB\u8FB9\u754C\u63A5\u4F4F");
@@ -2043,7 +2293,7 @@ function FeedbackSection() {
2043
2293
  Demo,
2044
2294
  {
2045
2295
  title: "Modal",
2046
- hint: "\u81EA\u7ED8 overlay\uFF08\u4E0D\u7528 portal\uFF09\uFF1B\u70B9\u906E\u7F69 / Esc / \u2715 \u90FD\u80FD\u5173\u3002\u6807\u9898\u680F\u7684 \u2715 \u662F 24\xD724 \u56FE\u6807\u4F4D\uFF0C\u4E0D\u8BE5\u51FA\u73B0\u8FB9\u6846\u6216 120px \u5BBD\u7684\u5E95\u8272\u5757"
2296
+ hint: t2("feedbackModalHint")
2047
2297
  },
2048
2298
  (0, import_react22.createElement)(
2049
2299
  "div",
@@ -2058,7 +2308,7 @@ function FeedbackSection() {
2058
2308
  ),
2059
2309
  (0, import_react22.createElement)(
2060
2310
  Demo,
2061
- { title: "toast", hint: "\u547D\u4EE4\u5F0F showToast\uFF0C\u4E0D\u8981\u6C42\u6302\u7EC4\u4EF6" },
2311
+ { title: "toast", hint: t2("feedbackToastHint") },
2062
2312
  (0, import_react22.createElement)(
2063
2313
  "div",
2064
2314
  { style: { display: "flex", gap: "8px" } },
@@ -2082,14 +2332,14 @@ function FeedbackSection() {
2082
2332
  (0, import_react22.createElement)(
2083
2333
  "div",
2084
2334
  { style: { color: "var(--tdt-fg-3)", fontSize: "12px" } },
2085
- "Loading \u662F\u8D34\u5230\u4E3B\u5BB9\u5668\u53F3\u4E0B\u89D2\u7684\u6307\u793A\u5668\uFF08anchorId \u9ED8\u8BA4 dsh-tdt-main\uFF09\uFF0C\u6B64\u5904\u4E0D\u6E32\u67D3\u4EE5\u514D\u906E\u6321\u3002"
2335
+ t2("loadingNote")
2086
2336
  )
2087
2337
  )
2088
2338
  )
2089
2339
  );
2090
2340
  }
2091
2341
 
2092
- // demo/sections/display.tsx
2342
+ // packages/demo/src/sections/display.tsx
2093
2343
  var import_react23 = require("react");
2094
2344
  function DisplaySection() {
2095
2345
  const [open, setOpen] = (0, import_react23.useState)(false);
@@ -2098,7 +2348,7 @@ function DisplaySection() {
2098
2348
  null,
2099
2349
  (0, import_react23.createElement)(
2100
2350
  Demo,
2101
- { title: "Card\uFF08\u5706\u89D2 + \u8FB9\u6846 + \u77ED\u8272\u6761\uFF09", hint: "\u6392\u7248\u5B8C\u5168\u7531\u8C03\u7528\u65B9\u51B3\u5B9A\u2014\u2014\u771F\u5B9E\u63D2\u4EF6\u7684\u5F62\u6001\uFF1A\u6807\u9898\u884C + \u53F3\u4FA7\u5143\u4FE1\u606F + chips \u884C\uFF1Baccent \u4E94\u6863\u89C1\u4E0B\u65B9\u901F\u89C8" },
2351
+ { title: t2("demoCardTitle"), hint: t2("displayCardHint") },
2102
2352
  (0, import_react23.createElement)(
2103
2353
  "div",
2104
2354
  { style: { display: "flex", flexDirection: "column", gap: "10px", maxWidth: "640px" } },
@@ -2142,7 +2392,7 @@ function DisplaySection() {
2142
2392
  ),
2143
2393
  (0, import_react23.createElement)(
2144
2394
  Demo,
2145
- { title: "StripCard\uFF08\u65E0\u8FB9\u6846 + \u901A\u9AD8\u7AD6\u7EBF\uFF09", hint: "\u540C\u4E00\u4E2A\u8272\u6761\u673A\u5236\uFF0C\u5916\u89C2\u662F\u901A\u9AD8\u8D34\u9876\u5230\u5E95\u2014\u2014\u771F\u5B9E\u63D2\u4EF6\u7684\u5F62\u6001\uFF1A\u6807\u9898 + \u5143\u4FE1\u606F\u884C + \u53F3\u4FA7\u65F6\u95F4/\u64CD\u4F5C" },
2395
+ { title: t2("demoStripTitle"), hint: t2("displayStripHint") },
2146
2396
  (0, import_react23.createElement)(
2147
2397
  "div",
2148
2398
  { style: { maxWidth: "640px", background: "var(--tdt-surface-sunken)", borderRadius: "8px", overflow: "hidden" } },
@@ -2188,7 +2438,7 @@ function DisplaySection() {
2188
2438
  Demo,
2189
2439
  {
2190
2440
  title: "Chip / SectionHead / MarqueeText / LiveText",
2191
- hint: "chip \u53EA\u6709\u300C\u80F6\u56CA\u6807\u7B7E\u300D\u4E00\u5957\u76AE\u80A4\uFF1A\u5BBD\u5EA6\u6309\u6587\u5B57\u6491\u5F00\u3001\u4E0D\u6362\u884C\uFF1B\u6700\u540E\u4E00\u9897\u662F\u957F\u6587\u5B57\uFF0C\u82E5\u88AB\u538B\u6210 28px \u7AD6\u6392\u5C31\u662F\u53C8\u6DF7\u8FDB\u4E86\u56FE\u6807\u6309\u94AE\u7684\u5B9A\u5BBD\u89C4\u5219"
2441
+ hint: t2("displayChipHint")
2192
2442
  },
2193
2443
  (0, import_react23.createElement)(
2194
2444
  "div",
@@ -2213,159 +2463,8 @@ function DisplaySection() {
2213
2463
  );
2214
2464
  }
2215
2465
 
2216
- // demo/sections/utils.tsx
2466
+ // packages/demo/src/sections/utils.tsx
2217
2467
  var import_react24 = require("react");
2218
-
2219
- // dist/utils/date.js
2220
- function pad2(value) {
2221
- return String(value).padStart(2, "0");
2222
- }
2223
- var FALLBACK = "\u2014";
2224
- function formatDateTime(iso, opts) {
2225
- const ms = Date.parse(iso);
2226
- if (Number.isNaN(ms))
2227
- return opts?.fallback ?? iso;
2228
- const d = new Date(ms);
2229
- const base = `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())} ${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
2230
- return opts?.seconds === true ? `${base}:${pad2(d.getSeconds())}` : base;
2231
- }
2232
- function formatYmd(iso, opts) {
2233
- const ms = Date.parse(iso);
2234
- if (Number.isNaN(ms))
2235
- return opts?.fallback ?? FALLBACK;
2236
- const d = new Date(ms);
2237
- return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
2238
- }
2239
- function formatClock(iso, opts) {
2240
- const fb = opts?.fallback ?? "-";
2241
- if (iso === null || iso === void 0 || iso === "")
2242
- return fb;
2243
- const ms = Date.parse(iso);
2244
- if (Number.isNaN(ms))
2245
- return fb;
2246
- const d = new Date(ms);
2247
- return `${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}`;
2248
- }
2249
- function formatDurationHms(ms) {
2250
- if (!Number.isFinite(ms) || ms < 0)
2251
- return "-";
2252
- const totalSec = Math.round(ms / 1e3);
2253
- const h31 = Math.floor(totalSec / 3600);
2254
- const m = Math.floor(totalSec % 3600 / 60);
2255
- const s = totalSec % 60;
2256
- return h31 > 0 ? `${h31}:${pad2(m)}:${pad2(s)}` : `${pad2(m)}:${pad2(s)}`;
2257
- }
2258
- function sameCalendarDay(a, b) {
2259
- return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
2260
- }
2261
- function relativePast(iso, nowMs, translate) {
2262
- const tt = translate ?? t;
2263
- const diff = nowMs - Date.parse(iso);
2264
- if (Number.isNaN(diff) || !(diff >= 0))
2265
- return tt("relNow");
2266
- if (diff < 6e4)
2267
- return tt("relJustNow");
2268
- const minutes = Math.floor(diff / 6e4);
2269
- if (minutes < 60)
2270
- return tt("relMinutesAgo", { n: minutes });
2271
- const hours = Math.floor(minutes / 60);
2272
- if (hours < 24)
2273
- return tt("relHoursAgo", { n: hours });
2274
- const days = Math.floor(hours / 24);
2275
- if (days < 7)
2276
- return tt("relDaysAgo", { n: days });
2277
- if (days < 30)
2278
- return tt("relWeeksAgo", { n: Math.floor(days / 7) });
2279
- const months = Math.floor(days / 30);
2280
- if (months < 12)
2281
- return tt("relMonthsAgo", { n: months });
2282
- return tt("relYearsAgo", { n: Math.floor(days / 365) });
2283
- }
2284
- function relativeFuture(iso, nowMs, translate) {
2285
- const tt = translate ?? t;
2286
- const diff = Date.parse(iso) - nowMs;
2287
- if (Number.isNaN(diff))
2288
- return formatYmd(iso);
2289
- if (diff <= 0)
2290
- return tt("relNow");
2291
- if (diff < 6e4)
2292
- return tt("relInJustNow");
2293
- const minutes = Math.floor(diff / 6e4);
2294
- if (minutes < 60)
2295
- return tt("relInMinutes", { n: minutes });
2296
- const hours = Math.floor(minutes / 60);
2297
- if (hours < 24)
2298
- return tt("relInHours", { n: hours });
2299
- const days = Math.floor(hours / 24);
2300
- if (days < 30)
2301
- return tt("relInDays", { n: days });
2302
- const months = Math.floor(days / 30);
2303
- if (months < 12)
2304
- return tt("relInMonths", { n: months });
2305
- return tt("relInYears", { n: Math.floor(days / 365) });
2306
- }
2307
- function formatRange(fromIso, toIso, opts) {
2308
- const from = Date.parse(fromIso);
2309
- const to = Date.parse(toIso);
2310
- if (Number.isNaN(from) || Number.isNaN(to))
2311
- return FALLBACK;
2312
- const a = new Date(from);
2313
- const b = new Date(to);
2314
- const clock = (d) => opts?.seconds === true ? `${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}` : `${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
2315
- if (sameCalendarDay(a, b))
2316
- return `${clock(a)} \u2013 ${clock(b)}`;
2317
- const day = (d) => `${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
2318
- return `${day(a)} ${clock(a)} \u2013 ${day(b)} ${clock(b)}`;
2319
- }
2320
-
2321
- // dist/utils/number.js
2322
- function formatBytes(bytes) {
2323
- if (!Number.isFinite(bytes) || bytes <= 0)
2324
- return "\u2014";
2325
- if (bytes < 1024)
2326
- return `${bytes} B`;
2327
- const units = ["KB", "MB", "GB", "TB"];
2328
- let value = bytes / 1024;
2329
- let unit = 0;
2330
- while (value >= 1024 && unit < units.length - 1) {
2331
- value /= 1024;
2332
- unit++;
2333
- }
2334
- return `${value >= 10 ? String(Math.round(value)) : value.toFixed(1)} ${units[unit]}`;
2335
- }
2336
-
2337
- // dist/utils/path.js
2338
- var IMAGE_EXT = {
2339
- png: "image/png",
2340
- jpg: "image/jpeg",
2341
- jpeg: "image/jpeg",
2342
- gif: "image/gif",
2343
- webp: "image/webp",
2344
- bmp: "image/bmp",
2345
- svg: "image/svg+xml",
2346
- ico: "image/x-icon"
2347
- };
2348
- function mimeOf(path) {
2349
- const ext = extOf(path);
2350
- return ext === "" ? void 0 : IMAGE_EXT[ext];
2351
- }
2352
- function extOf(path) {
2353
- const name = path.slice(path.lastIndexOf("/") + 1);
2354
- const dot = name.lastIndexOf(".");
2355
- return dot <= 0 ? "" : name.slice(dot + 1).toLowerCase();
2356
- }
2357
- function crumbsOf(path) {
2358
- return path.split("/").filter((s) => s !== "");
2359
- }
2360
- function parentOf(path) {
2361
- const cut = path.lastIndexOf("/");
2362
- return cut < 0 ? "" : path.slice(0, cut);
2363
- }
2364
- function joinPath(dir, name) {
2365
- return dir === "" ? name : `${dir}/${name}`;
2366
- }
2367
-
2368
- // demo/sections/utils.tsx
2369
2468
  var NOW = Date.parse("2026-10-18T12:00:00.000Z");
2370
2469
  var ROWS = [
2371
2470
  ["formatDateTime", formatDateTime("2026-10-18T09:30:05.000Z", { seconds: true }), "2026-10-18 09:30:05"],
@@ -2380,7 +2479,7 @@ var ROWS = [
2380
2479
  function UtilsSection() {
2381
2480
  return (0, import_react24.createElement)(
2382
2481
  Demo,
2383
- { title: "\u65E5\u671F / \u5B57\u7B26\u4E32 / \u5B57\u8282", hint: "\u89E3\u6790\u5931\u8D25\u4E0D\u629B\u9519\u3001\u7ED9\u515C\u5E95\u3001\u4E0D\u7F16\u9020\uFF1B\u6240\u6709\u51FD\u6570\u65E0 UI \u4F9D\u8D56" },
2482
+ { title: t2("demoUtilsTitle"), hint: t2("utilsHint") },
2384
2483
  (0, import_react24.createElement)(
2385
2484
  "table",
2386
2485
  { style: { borderCollapse: "collapse", fontSize: "13px" } },
@@ -2412,7 +2511,7 @@ function UtilsSection() {
2412
2511
  var th = { textAlign: "left", padding: "6px 14px 6px 0", color: "var(--tdt-fg-3)" };
2413
2512
  var td = { padding: "5px 14px 5px 0", borderTop: "1px solid var(--tdt-border-faint)" };
2414
2513
 
2415
- // demo/sections/explorer.tsx
2514
+ // packages/demo/src/sections/explorer.tsx
2416
2515
  var import_react27 = require("react");
2417
2516
 
2418
2517
  // dist/explorer/ExplorerPanel.js
@@ -2595,7 +2694,7 @@ function ExplorerPanel(props) {
2595
2694
  }))));
2596
2695
  }
2597
2696
 
2598
- // demo/mock.ts
2697
+ // packages/demo/src/mock.ts
2599
2698
  var TREE = {
2600
2699
  ".": [
2601
2700
  { name: "src", type: "directory" },
@@ -2730,14 +2829,14 @@ function delay(ms) {
2730
2829
  return new Promise((r) => setTimeout(r, ms));
2731
2830
  }
2732
2831
 
2733
- // demo/sections/explorer.tsx
2832
+ // packages/demo/src/sections/explorer.tsx
2734
2833
  function ExplorerSection() {
2735
2834
  const [selected, setSelected] = (0, import_react27.useState)(null);
2736
2835
  return (0, import_react27.createElement)(
2737
2836
  Demo,
2738
2837
  {
2739
2838
  title: "ExplorerPanel",
2740
- hint: "\u9762\u5305\u5C51 + \u76EE\u5F55\u6811 + \u9884\u89C8\uFF1BworkspaceFiles \u662F mock \u7684\uFF08\u771F\u5B9E\u63D2\u4EF6\u4ECE ctx \u53D6\u51FA\u540E\u6CE8\u5165\uFF09"
2839
+ hint: t2("explorerHint")
2741
2840
  },
2742
2841
  (0, import_react27.createElement)(
2743
2842
  "div",
@@ -2769,7 +2868,7 @@ function ExplorerSection() {
2769
2868
  );
2770
2869
  }
2771
2870
 
2772
- // demo/sections/session.tsx
2871
+ // packages/demo/src/sections/session.tsx
2773
2872
  var import_react29 = require("react");
2774
2873
 
2775
2874
  // dist/session/index.js
@@ -2832,14 +2931,14 @@ function SessionPreview(props) {
2832
2931
  return (0, import_react28.createElement)("div", { className: `dsh-tdt-ses dsh-tdt-ses--${variant}` }, props.onClose === void 0 ? null : (0, import_react28.createElement)("div", { className: "dsh-tdt-ses__head" }, (0, import_react28.createElement)("button", { type: "button", className: "dsh-tdt-exp__crumb", onClick: props.onClose }, "\u2715")), body);
2833
2932
  }
2834
2933
 
2835
- // demo/sections/session.tsx
2934
+ // packages/demo/src/sections/session.tsx
2836
2935
  function SessionSection() {
2837
2936
  const [open, setOpen] = (0, import_react29.useState)(false);
2838
2937
  return (0, import_react29.createElement)(
2839
2938
  Demo,
2840
2939
  {
2841
2940
  title: "SessionPreview",
2842
- hint: "\u4E09\u79CD\u627F\u8F7D\uFF1Amodal / sidebar / page\uFF1Bsource \u662F mock \u7684\uFF1BrenderMessage \u53EF\u63A5\u7BA1\u5BCC\u5185\u5BB9"
2941
+ hint: t2("sessionHint")
2843
2942
  },
2844
2943
  (0, import_react29.createElement)(
2845
2944
  "div",
@@ -2861,7 +2960,7 @@ function SessionSection() {
2861
2960
  }
2862
2961
  }
2863
2962
 
2864
- // demo/sections/index.tsx
2963
+ // packages/demo/src/sections/index.tsx
2865
2964
  function Demo(props) {
2866
2965
  return (0, import_react30.createElement)(
2867
2966
  "section",
@@ -2904,21 +3003,21 @@ function SectionHead2(props) {
2904
3003
  );
2905
3004
  }
2906
3005
  var ALL_SECTIONS = [
2907
- { id: "design", title: "\u8BBE\u8BA1\u57FA\u7840", render: () => (0, import_react30.createElement)(DesignSection, null) },
2908
- { id: "buttons", title: "\u6309\u94AE\u4E0E\u8F93\u5165", render: () => (0, import_react30.createElement)(ButtonsSection, null) },
2909
- { id: "pickers", title: "\u9009\u62E9\u5668", render: () => (0, import_react30.createElement)(PickersSection, null) },
2910
- { id: "feedback", title: "\u5F39\u7A97\u4E0E\u53CD\u9988", render: () => (0, import_react30.createElement)(FeedbackSection, null) },
2911
- { id: "display", title: "\u5361\u7247\u4E0E\u5C55\u793A", render: () => (0, import_react30.createElement)(DisplaySection, null) },
2912
- { id: "utils", title: "\u901A\u7528\u65B9\u6CD5", render: () => (0, import_react30.createElement)(UtilsSection, null) },
2913
- { id: "explorer", title: "\u5DE5\u4F5C\u533A\u6D4F\u89C8", render: () => (0, import_react30.createElement)(ExplorerSection, null) },
2914
- { id: "session", title: "\u4F1A\u8BDD\u9884\u89C8", render: () => (0, import_react30.createElement)(SessionSection, null) }
3006
+ { id: "design", titleKey: "secDesign", render: () => (0, import_react30.createElement)(DesignSection, null) },
3007
+ { id: "buttons", titleKey: "secButtons", render: () => (0, import_react30.createElement)(ButtonsSection, null) },
3008
+ { id: "pickers", titleKey: "secPickers", render: () => (0, import_react30.createElement)(PickersSection, null) },
3009
+ { id: "feedback", titleKey: "secFeedback", render: () => (0, import_react30.createElement)(FeedbackSection, null) },
3010
+ { id: "display", titleKey: "secDisplay", render: () => (0, import_react30.createElement)(DisplaySection, null) },
3011
+ { id: "utils", titleKey: "secUtils", render: () => (0, import_react30.createElement)(UtilsSection, null) },
3012
+ { id: "explorer", titleKey: "secExplorer", render: () => (0, import_react30.createElement)(ExplorerSection, null) },
3013
+ { id: "session", titleKey: "secSession", render: () => (0, import_react30.createElement)(SessionSection, null) }
2915
3014
  ];
2916
3015
  function Sections(props) {
2917
3016
  const current3 = ALL_SECTIONS.find((s) => s.id === props.active) ?? ALL_SECTIONS[0];
2918
3017
  return (0, import_react30.createElement)(
2919
3018
  "div",
2920
3019
  null,
2921
- (0, import_react30.createElement)(SectionHead2, { id: current3.id, title: current3.title }),
3020
+ (0, import_react30.createElement)(SectionHead2, { id: current3.id, title: t2(current3.titleKey) }),
2922
3021
  current3.render()
2923
3022
  );
2924
3023
  }
@@ -2929,11 +3028,23 @@ var ALIAS_TOKEN_NAMES = ["accent", "active", "border", "border-faint", "border-h
2929
3028
  // packages/demo/src/client/index.tsx
2930
3029
  var PANEL_ID = "dsh-plugin-core-demo";
2931
3030
  var PREFIX = "dshpc";
3031
+ var localeRuntime;
3032
+ function useLocaleTick() {
3033
+ const [, setTick] = (0, import_react31.useState)(0);
3034
+ (0, import_react31.useEffect)(() => {
3035
+ const rt = localeRuntime;
3036
+ if (rt === void 0) return;
3037
+ return rt.subscribe(() => {
3038
+ setTick((v) => v + 1);
3039
+ });
3040
+ }, []);
3041
+ }
2932
3042
  function aliasCss() {
2933
3043
  const decls = ALIAS_TOKEN_NAMES.map((n) => `--tdt-${n}:var(--${PREFIX}-${n})`);
2934
3044
  return `body{${decls.join(";")}}`;
2935
3045
  }
2936
3046
  function DemoPage() {
3047
+ useLocaleTick();
2937
3048
  const [active, setActive] = (0, import_react31.useState)(ALL_SECTIONS[0].id);
2938
3049
  return (0, import_react31.createElement)(
2939
3050
  "div",
@@ -2973,7 +3084,7 @@ function DemoPage() {
2973
3084
  marginBottom: "2px"
2974
3085
  }
2975
3086
  },
2976
- s.title
3087
+ t2(s.titleKey)
2977
3088
  )
2978
3089
  )
2979
3090
  ),
@@ -3006,14 +3117,14 @@ function OpenPreviewCard(props) {
3006
3117
  (0, import_react31.createElement)(
3007
3118
  "div",
3008
3119
  null,
3009
- (0, import_react31.createElement)("div", { style: { fontWeight: 600, fontSize: "14px" } }, "\u7EC4\u4EF6\u9884\u89C8"),
3120
+ (0, import_react31.createElement)("div", { style: { fontWeight: 600, fontSize: "14px" } }, t2("pluginTitle")),
3010
3121
  (0, import_react31.createElement)(
3011
3122
  "div",
3012
3123
  { style: { color: "var(--dshpc-fg-3)", fontSize: "12px", marginTop: "2px" } },
3013
- "\u6253\u5F00 dsh-plugin-core \u7684\u63A7\u4EF6\u4E0E\u4E1A\u52A1\u7EC4\u4EF6\u5C55\u793A\u9875"
3124
+ t2("pluginCardDesc")
3014
3125
  )
3015
3126
  ),
3016
- (0, import_react31.createElement)("span", { style: { color: "var(--dshpc-business)", fontSize: "13px" } }, "\u6253\u5F00 \u203A")
3127
+ (0, import_react31.createElement)("span", { style: { color: "var(--dshpc-business)", fontSize: "13px" } }, t2("pluginCardOpen"))
3017
3128
  );
3018
3129
  }
3019
3130
  function PanelIcon() {
@@ -3037,12 +3148,28 @@ function apply(ctx) {
3037
3148
  select(id);
3038
3149
  };
3039
3150
  });
3151
+ ctx.inject(["locale"], (sub) => {
3152
+ const loc = sub?.locale;
3153
+ if (loc === void 0) return;
3154
+ localeRuntime = loc;
3155
+ try {
3156
+ loc.register(PANEL_ID, "zh", { ...DICT2.zh });
3157
+ loc.register(PANEL_ID, "en", { ...DICT2.en });
3158
+ setDemoTranslate(loc.bind(PANEL_ID));
3159
+ } catch {
3160
+ }
3161
+ const sync = () => {
3162
+ setLocale(loc.getLocale().active === "en" ? "en" : "zh");
3163
+ };
3164
+ sync();
3165
+ loc.subscribe(sync);
3166
+ });
3040
3167
  ctx.inject(["slots"], (sub) => {
3041
3168
  const slots = sub.slots;
3042
3169
  if (slots === void 0) return;
3043
3170
  slots.inject("sidebar.panellist", () => {
3044
3171
  slots.register(
3045
- { name: "sidebar.panellist", id: PANEL_ID, order: 90, label: () => "\u7EC4\u4EF6\u9884\u89C8" },
3172
+ { name: "sidebar.panellist", id: PANEL_ID, order: 90, label: () => t2("pluginTitle") },
3046
3173
  PanelIcon
3047
3174
  );
3048
3175
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-core-demo",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "dsh-plugin-core 的组件预览插件:装进 DSH 宿主后,在真实宿主环境里预览控件与业务组件",
5
5
  "keywords": ["deepseek", "harness", "dsh", "dsh-plugin", "dsh-plugin-core"],
6
6
  "homepage": "https://github.com/cq-guojia/dsh-plugin-core/tree/main/packages/demo",