dsh-plugin-core-demo 0.7.3 → 0.7.4

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 +71 -21
  2. package/package.json +1 -1
package/dist/client.js CHANGED
@@ -146,9 +146,9 @@ var FIELD_CSS = `
146
146
  .dshpc-input--md{height:var(--dshpc-control-h-md);padding:0 10px;font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}
147
147
  .dshpc-input--lg{height:var(--dshpc-control-h-lg);padding:0 12px;font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}
148
148
  .dshpc-input::placeholder{color:var(--dshpc-fg-dim);}
149
- /* type="search" \u7684\u6E05\u7A7A\u94AE\u662F\u6D4F\u89C8\u5668 UA \u753B\u7684\uFF08::-webkit-search-cancel-button\uFF09\uFF0C\u9ED8\u8BA4\u7BAD\u5934\u5149\u6807\uFF1A
150
- \u770B\u7740\u50CF\u4E0D\u53EF\u70B9\u3002\u5B83\u662F\u771F\u6309\u94AE\uFF0C\u8865\u624B\u578B\uFF08Chromium / Safari \u4E13\u5C5E\u4F2A\u5143\u7D20\uFF1BFirefox \u6CA1\u6709\u8FD9\u4E2A\u94AE\uFF09\u3002 */
151
- .dshpc-input:not(:disabled)::-webkit-search-cancel-button{cursor:pointer;}
149
+ /* type="search"\uFF1A\u539F\u751F\u6E05\u9664\u94AE\uFF08::-webkit-search-cancel-button\uFF09\u6574\u4E2A\u9690\u6389\uFF0C\u6362\u7EC4\u4EF6\u81EA\u5DF1\u6302\u7684 plain IconButton
150
+ \u2014\u2014 \u539F\u751F\u90A3\u4E2A\u5404\u5B50\u7CFB\u7EDF\u957F\u76F8\u4E0D\u4E00\u3001\u8FD8\u4E0D\u5403 token\uFF082026-10-28 \u7528\u6237\uFF1A\u4E0D\u597D\u770B\uFF0C\u8981\u6570\u5B57\u6846\u52A0\u51CF\u53F7\u90A3\u79CD\uFF09\u3002 */
151
+ .dshpc-iwrap .dshpc-input::-webkit-search-cancel-button{display:none;}
152
152
  .dshpc-input:focus{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus);}
153
153
  .dshpc-input--error{border-color:var(--dshpc-danger);}
154
154
  .dshpc-input:disabled{cursor:default;opacity:.5;}
@@ -163,6 +163,16 @@ var FIELD_CSS = `
163
163
  /* \u7981\u7528\u65F6\u56FE\u6807\u8DDF\u8F93\u5165\u6846\u4E00\u8D77\u53D8\u6DE1\uFF08\u8F93\u5165\u6846\u81EA\u5DF1\u5DF2\u6709 opacity:.5\uFF0C\u56FE\u6807\u4E0D\u5728\u5B83\u91CC\u9762\uFF0C\u5F97\u5355\u72EC\u8DDF\u4E00\u4E0B\uFF09\u3002 */
164
164
  .dshpc-iwrap:has(> .dshpc-input:disabled) > .dshpc-iwrap__icon{opacity:.5;}
165
165
 
166
+ /* \u641C\u7D22\u6846\u7684\u6E05\u7A7A\u94AE\uFF08Field.ts \u5728\u300C\u6709\u7126\u70B9 + \u6709\u5185\u5BB9\u300D\u65F6\u624D\u6302\u51FA\u6765\uFF09\uFF1A**\u5E76\u8FDB\u6846\u91CC**\uFF0C\u4E0E\u6570\u5B57\u6846\u7684 \u2212 / +
167
+ \u540C\u5F62\u6001 \u2014\u2014 \u6574\u6BB5\u540C\u9AD8\u3001\u5DE6\u76F4\u53F3\u5706\u3001hover \u5E95\u8272\u94FA\u6EE1\u8FD9\u4E00\u683C\uFF082026-10-28 \u7528\u6237\uFF1A\u4E0D\u8981\u4E00\u9897\u60AC\u5728\u53F3\u8FB9\u7684\u5C0F\u6309\u94AE\uFF09\u3002
168
+ \u5411\u5185\u8BA9 1px\uFF0C\u514D\u5F97\u5E95\u8272\u538B\u4F4F\u8F93\u5165\u6846\u81EA\u5DF1\u7684\u8FB9\u6846\u3002 */
169
+ .dshpc-iwrap__clear.dshpc-iconbtn{position:absolute;right:1px;top:1px;bottom:1px;width:auto;aspect-ratio:1;
170
+ border-radius:0 var(--dshpc-radius-md) var(--dshpc-radius-md) 0;font-size:var(--dshpc-font-md);}
171
+ /* \u6587\u5B57\u8BA9\u5F00\u8FD9\u4E00\u6BB5\uFF08\u5BBD\u5EA6 = \u63A7\u4EF6\u9AD8 - 2\uFF0C\u6545\u6309\u6863\u4F4D\u8865\uFF09\u3002 */
172
+ .dshpc-iwrap--clear > .dshpc-input{padding-right:calc(var(--dshpc-control-h-md) + 3px);}
173
+ .dshpc-iwrap--clear.dshpc-iwrap--sm > .dshpc-input{padding-right:calc(var(--dshpc-control-h-sm) + 3px);}
174
+ .dshpc-iwrap--clear.dshpc-iwrap--lg > .dshpc-input{padding-right:calc(var(--dshpc-control-h-lg) + 3px);}
175
+
166
176
  .dshpc-pfx{display:inline-flex;align-items:center;box-sizing:border-box;overflow:hidden;
167
177
  border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);background:var(--dshpc-surface-1);color:var(--dshpc-fg);}
168
178
  .dshpc-pfx--sm{height:var(--dshpc-control-h-sm);}
@@ -6231,6 +6241,13 @@ function notify(message, opts) {
6231
6241
 
6232
6242
  // dist/ui/Segmented.js
6233
6243
  var import_react22 = require("react");
6244
+ function countText(value) {
6245
+ if (value === void 0)
6246
+ return null;
6247
+ if (typeof value === "number")
6248
+ return value > 0 ? String(value) : null;
6249
+ return value === "" ? null : value;
6250
+ }
6234
6251
  function Segmented(props) {
6235
6252
  ensureControls();
6236
6253
  ensureControls();
@@ -6299,6 +6316,8 @@ function Segmented(props) {
6299
6316
  onChange(item.value);
6300
6317
  }
6301
6318
  };
6319
+ const count3 = countText(item.count);
6320
+ const badge = countText(item.badge);
6302
6321
  const itemButton = (0, import_react22.createElement)("button", {
6303
6322
  key: item.value,
6304
6323
  type: "button",
@@ -6307,7 +6326,7 @@ function Segmented(props) {
6307
6326
  "aria-pressed": on,
6308
6327
  disabled,
6309
6328
  onClick: handle
6310
- }, item.label, item.count !== void 0 && item.count > 0 ? (0, import_react22.createElement)("span", { className: "dshpc-seg__count" }, String(item.count)) : null, item.badge !== void 0 && item.badge > 0 ? (0, import_react22.createElement)("span", { className: "dshpc-seg__badge" }, String(item.badge)) : null);
6329
+ }, item.label, count3 === null ? null : (0, import_react22.createElement)("span", { className: "dshpc-seg__count" }, count3), badge === null ? null : (0, import_react22.createElement)("span", { className: "dshpc-seg__badge" }, badge));
6311
6330
  if (item.tooltip !== void 0 && renderer2 !== void 0) {
6312
6331
  return renderer2({ label: item.tooltip, side: "top", children: itemButton });
6313
6332
  }
@@ -6699,7 +6718,7 @@ function PanelDock(props) {
6699
6718
  const panelRefs = (0, import_react28.useRef)(/* @__PURE__ */ new Map());
6700
6719
  const panes = panesOf(props.children);
6701
6720
  const { defaultWidth, minWidth: fallbackMin } = props.dock.defaults;
6702
- const widthOf = (pane) => state.widths[pane.id] ?? clampWidth(pane.width ?? defaultWidth, pane.minWidth ?? fallbackMin, pane.maxWidth);
6721
+ const widthOf = (pane) => clampWidth(state.widths[pane.id] ?? pane.width ?? defaultWidth, pane.minWidth ?? fallbackMin, pane.maxWidth);
6703
6722
  const earLabelOf = (id3) => {
6704
6723
  const pane = panes.find((item) => item.id === id3);
6705
6724
  if (pane === void 0)
@@ -6880,6 +6899,9 @@ function sizeClass(size4) {
6880
6899
  function Input(props) {
6881
6900
  ensureControls();
6882
6901
  const { value, onChange, placeholder: placeholder2, size: size4 = "lg", error, disabled, type: type3, icon: icon2, className: className2, style: style2 } = props;
6902
+ const [focused, setFocused] = (0, import_react29.useState)(false);
6903
+ const search = type3 === "search";
6904
+ const showClear = search && value !== "" && focused && disabled !== true;
6883
6905
  const input = (0, import_react29.createElement)("input", {
6884
6906
  ref: props.inputRef,
6885
6907
  type: type3 ?? "text",
@@ -6894,9 +6916,38 @@ function Input(props) {
6894
6916
  onChange(event.target.value);
6895
6917
  },
6896
6918
  onKeyDown: props.onKeyDown,
6897
- onBlur: props.onBlur
6919
+ onFocus: () => {
6920
+ setFocused(true);
6921
+ },
6922
+ onBlur: () => {
6923
+ setFocused(false);
6924
+ if (props.onBlur !== void 0)
6925
+ props.onBlur();
6926
+ }
6898
6927
  });
6899
- return withHint(icon2 === void 0 || icon2 === null ? input : (0, import_react29.createElement)("span", { className: `dshpc-iwrap dshpc-iwrap${sizeClass(size4)}` }, (0, import_react29.createElement)("span", { className: "dshpc-iwrap__icon" }, icon2), input), props.hint);
6928
+ const hasIcon = icon2 !== void 0 && icon2 !== null;
6929
+ if (!hasIcon && !search)
6930
+ return withHint(input, props.hint);
6931
+ return withHint((0, import_react29.createElement)(
6932
+ "span",
6933
+ { className: `dshpc-iwrap dshpc-iwrap${sizeClass(size4)}${showClear ? " dshpc-iwrap--clear" : ""}` },
6934
+ hasIcon ? (0, import_react29.createElement)("span", { className: "dshpc-iwrap__icon" }, icon2) : null,
6935
+ input,
6936
+ // 只在 mousedown 上拦焦点:不拦的话 input 先 blur ⇒ 按钮被卸掉 ⇒ 随后的 click 落空。
6937
+ showClear ? (0, import_react29.createElement)(IconButton, {
6938
+ className: "dshpc-iwrap__clear",
6939
+ variant: "plain",
6940
+ size: size4,
6941
+ icon: "\xD7",
6942
+ label: "\u6E05\u7A7A",
6943
+ onMouseDown: (event) => {
6944
+ event.preventDefault();
6945
+ },
6946
+ onClick: () => {
6947
+ onChange("");
6948
+ }
6949
+ }) : null
6950
+ ), props.hint);
6900
6951
  }
6901
6952
  function NumberInput(props) {
6902
6953
  ensureControls();
@@ -56940,8 +56991,8 @@ var docData = {
56940
56991
  "en": "IconButton: variant plain|outline|danger (default plain), size (default lg), icon (required), label (required, doubles as a11y name and title)."
56941
56992
  },
56942
56993
  {
56943
- "zh": "Segmented\uFF1A`items`\uFF08\u5FC5\u586B\uFF09\u652F\u6301\u5355\u9009 / \u591A\u9009\uFF0C`size`\uFF08\u9ED8\u8BA4 lg\uFF1B\u4E09\u6863\u603B\u9AD8 24 / 28 / 32\uFF09\u3001`bordered`\uFF081px \u5916\u6846\uFF0C\u603B\u9AD8\u4E0D\u53D8\uFF09\u3001`multiple`\uFF08\u591A\u9009\uFF09\u3002\u5916\u89C2\u53EA\u6709\u4E00\u5957\uFF1A\u7070\u5E95\u8F68\u9053 + \u767D\u8272\u9009\u4E2D\u7247\uFF0C\u9009\u4E2D\u7247\u7684\u63CF\u8FB9\u73AF\u4E0E\u9634\u5F71\u7531\u5BBF\u4E3B elevation token \u63D0\u4F9B\uFF08\u79BB\u7EBF\u515C\u5E95\u503C\u6CA1\u6709\u90A3\u5708\u73AF\uFF09\u3002",
56944
- "en": "Segmented: `items` (required) supports single or multiple selection; `size` (default lg; totals 24 / 28 / 32), `bordered` (1px outer frame, same total height), `multiple` (multi-select). One look only: grey track + white selected pill; its stroke ring and shadow come from the host elevation token (the offline fallback has no ring)."
56994
+ "zh": "Segmented\uFF1A`items`\uFF08\u5FC5\u586B\uFF09\u652F\u6301\u5355\u9009 / \u591A\u9009\uFF0C`size`\uFF08\u9ED8\u8BA4 lg\uFF1B\u4E09\u6863\u603B\u9AD8 24 / 28 / 32\uFF09\u3001`bordered`\uFF081px \u5916\u6846\uFF0C\u603B\u9AD8\u4E0D\u53D8\uFF09\u3001`multiple`\uFF08\u591A\u9009\uFF09\u3002\u5916\u89C2\u53EA\u6709\u4E00\u5957\uFF1A\u7070\u5E95\u8F68\u9053 + \u767D\u8272\u9009\u4E2D\u7247\uFF0C\u9009\u4E2D\u7247\u7684\u63CF\u8FB9\u73AF\u4E0E\u9634\u5F71\u7531\u5BBF\u4E3B elevation token \u63D0\u4F9B\uFF08\u79BB\u7EBF\u515C\u5E95\u503C\u6CA1\u6709\u90A3\u5708\u73AF\uFF09\u3002\u6BB5\u5185 `count`\uFF08\u5F31\u5316\u7070\u5B57\uFF09/ `badge`\uFF08\u7EA2\u89D2\u6807\uFF09\u63A5\u53D7 `number | string`\uFF1A\u6570\u5B57 \u22640 \u4E0D\u663E\u793A\uFF0C\u5B57\u7B26\u4E32\u539F\u6837\u663E\u793A\uFF08\u5982 `1K` / `99+`\uFF09\u3002",
56995
+ "en": "Segmented: `items` (required) supports single or multiple selection; `size` (default lg; totals 24 / 28 / 32), `bordered` (1px outer frame, same total height), `multiple` (multi-select). One look only: grey track + white selected pill; its stroke ring and shadow come from the host elevation token (the offline fallback has no ring). An item\u2019s `count` (muted text) and `badge` (red pill) take `number | string`: numbers \u22640 render nothing, strings render as given (e.g. `'1K'` / `'99+'`)."
56945
56996
  }
56946
56997
  ],
56947
56998
  "api": [
@@ -57048,8 +57099,8 @@ var docData = {
57048
57099
  "type": "value onChange(v) size(\u9ED8\u8BA4 sm) error disabled type icon placeholder inputRef onKeyDown onBlur aria-label title hint",
57049
57100
  "def": "\u2014",
57050
57101
  "desc": {
57051
- "zh": "\u57FA\u7840\u8F93\u5165\u6846\uFF1Berror \u63CF\u7EA2\uFF1Bhint \u7ED9\u5B57\u7B26\u4E32\u5373\u81EA\u52A8\u6302\u6807\u51C6\u95EE\u53F7\u63D0\u793A\uFF1Bicon \u662F\u5DE6\u4FA7\u56FE\u6807\u69FD\uFF08\u4E0D\u5403\u70B9\u51FB\uFF0C\u5C3A\u5BF8\u53D6 fieldMetricsOf(size).icon\uFF09",
57052
- "en": "Basic input; error turns it red; passing hint as a string auto-attaches a standard question-mark hint; icon is the leading icon slot (does not swallow clicks; size from fieldMetricsOf(size).icon)"
57102
+ "zh": "\u57FA\u7840\u8F93\u5165\u6846\uFF1Berror \u63CF\u7EA2\uFF1Bhint \u7ED9\u5B57\u7B26\u4E32\u5373\u81EA\u52A8\u6302\u6807\u51C6\u95EE\u53F7\u63D0\u793A\uFF1Bicon \u662F\u5DE6\u4FA7\u56FE\u6807\u69FD\uFF08\u4E0D\u5403\u70B9\u51FB\uFF0C\u5C3A\u5BF8\u53D6 fieldMetricsOf(size).icon\uFF09\uFF1Btype=search \u65F6\u805A\u7126\u4E14\u6709\u5185\u5BB9\u624D\u5728\u53F3\u4FA7\u51FA\u6E05\u7A7A\u94AE",
57103
+ "en": "Basic input; error turns it red; passing hint as a string auto-attaches a standard question-mark hint; icon is the leading icon slot (does not swallow clicks; size from fieldMetricsOf(size).icon); with type=search a clear button appears on the right only while focused and non-empty"
57053
57104
  }
57054
57105
  },
57055
57106
  {
@@ -58632,7 +58683,7 @@ const [kw, setKw] = useState('')
58632
58683
 
58633
58684
  // hint \u53C2\u6570\u7248\uFF1A\u95EE\u53F7\u63D0\u793A\u7531\u7EC4\u4EF6\u81EA\u5DF1\u6302\uFF0C\u4E0D\u7528\u624B\u52A8\u62FC FieldHint
58634
58685
  <Input value={text} onChange={setText} placeholder="\u8BF7\u8F93\u5165\u7528\u6237\u540D" hint="\u7528\u6237\u540D\u53EA\u80FD\u5305\u542B\u5B57\u6BCD\u3001\u6570\u5B57\u4E0E\u8FDE\u5B57\u7B26\u3002" />
58635
- // \u641C\u7D22\u6846\uFF1Atype="search" \u53EA\u900F\u4F20\u539F\u751F input\uFF0C\u53F3\u4FA7\u5C0F\u53C9\u662F\u6D4F\u89C8\u5668\u81EA\u5E26\u7684\u6E05\u7A7A\u94AE\uFF08\u4E0D\u662F\u6838\u5FC3\u5E93\u753B\u7684\uFF09
58686
+ // \u641C\u7D22\u6846\uFF1Atype="search" \u21D2 \u805A\u7126\u4E14\u6709\u5185\u5BB9\u65F6\u53F3\u4FA7\u624D\u51FA\u6E05\u7A7A\u94AE\uFF08\u6570\u5B57\u6846\u52A0\u51CF\u53F7\u540C\u6B3E\u7684 plain IconButton\uFF0C\u539F\u751F\u90A3\u679A\u5DF2\u9690\u6389\uFF09
58636
58687
  // icon \u662F\u5DE6\u4FA7\u56FE\u6807\u69FD\uFF08\u4E0D\u5403\u70B9\u51FB\uFF0C\u70B9\u5728\u56FE\u6807\u4E0A\u7167\u6837\u805A\u7126\uFF09\uFF1B\u56FE\u6807\u5C3A\u5BF8\u6309\u6863\u53D6 fieldMetricsOf(size).icon
58637
58688
  <Input type="search" icon={<IconSearchOutlineRegular size={16} />} value={kw} onChange={setKw} placeholder="\u641C\u7D22" />
58638
58689
  // \u6821\u9A8C\u5931\u8D25\u6001\uFF1A\u63CF\u7EA2
@@ -58708,7 +58759,7 @@ function InputPage() {
58708
58759
  "div",
58709
58760
  { style: { display: "flex", alignItems: "center", gap: "6px" } },
58710
58761
  (0, import_react57.createElement)("span", { style: { color: "var(--dshpc-fg-2)", fontSize: "13px", flex: "none" } }, "\u641C\u7D22"),
58711
- // 左侧图标槽(icon)+ 原生清除钮(type="search" 透传,小叉由浏览器画)
58762
+ // 左侧图标槽(icon)+ 聚焦且有内容才出的清空钮(type="search")
58712
58763
  (0, import_react57.createElement)(Input, { type: "search", icon: (0, import_react57.createElement)(import_dsh_client_ui_primitives2.IconSearchOutlineRegular, { size: 16 }), value: kw, onChange: setKw, placeholder: "\u641C\u7D22" })
58713
58764
  ),
58714
58765
  (0, import_react57.createElement)(Input, { value: "bad value", onChange: () => {
@@ -61176,8 +61227,7 @@ function openFilePreview(options) {
61176
61227
  maxPanels: 1,
61177
61228
  defaultWidth: options.width ?? 460,
61178
61229
  minWidth: options.minWidth ?? 320,
61179
- // 每次打开都从默认宽度起步(预览是临时面板,不继承上次的落位)。
61180
- storageKey: false,
61230
+ // 宽度按面板 id 记(用户 2026-10-28:拖过一次,下次弹出还是这个宽)。
61181
61231
  // 关钮被点 ⇒ 整个挂载体回收(close 内部幂等,不受 onClose 回调顺序影响)。
61182
61232
  onClose: () => {
61183
61233
  close();
@@ -61845,9 +61895,9 @@ function ReferencePage() {
61845
61895
  "tbody",
61846
61896
  null,
61847
61897
  [
61848
- [t3("buildCore"), `v${"0.7.3"}`],
61849
- [t3("buildDemo"), `v${"0.7.3"}`],
61850
- [t3("buildStamp"), "261028-084445-341"]
61898
+ [t3("buildCore"), `v${"0.7.4"}`],
61899
+ [t3("buildDemo"), `v${"0.7.4"}`],
61900
+ [t3("buildStamp"), "261028-090558-450"]
61851
61901
  ].map(
61852
61902
  ([label, value]) => (0, import_react67.createElement)(
61853
61903
  "tr",
@@ -62169,9 +62219,9 @@ function DemoPage() {
62169
62219
  lineHeight: "14px"
62170
62220
  }
62171
62221
  },
62172
- (0, import_react69.createElement)("span", null, `core v${"0.7.3"}`),
62173
- (0, import_react69.createElement)("span", null, `demo v${"0.7.3"}`),
62174
- (0, import_react69.createElement)("span", { style: { marginTop: "4px", fontSize: "9px" } }, "261028-084445-341")
62222
+ (0, import_react69.createElement)("span", null, `core v${"0.7.4"}`),
62223
+ (0, import_react69.createElement)("span", null, `demo v${"0.7.4"}`),
62224
+ (0, import_react69.createElement)("span", { style: { marginTop: "4px", fontSize: "9px" } }, "261028-090558-450")
62175
62225
  )
62176
62226
  )
62177
62227
  ),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-core-demo",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "description": "The shared UI foundation for DSH plugins, with a live component preview: design tokens, common controls, workspace browsing and notifications maintained in one place — install it to preview every component in a real host.",
5
5
  "icon": "./assets/icon-components.svg",
6
6
  "keywords": [