dsh-plugin-core-demo 0.2.0 → 0.2.2

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 +391 -49
  2. package/package.json +1 -1
package/dist/client.js CHANGED
@@ -100,6 +100,26 @@ body{
100
100
  /* \u8BED\u4E49\u8272**\u5B9E\u9762**\u4E0A\u7684\u5B57\uFF08\u89D2\u6807 / \u5B9E\u5FC3\u63D0\u793A\uFF09\uFF1A\u5BBF\u4E3B\u7EA2\u7EFF\u9EC4\u4E09\u8272\u90FD\u662F\u4E2D\u8C03 \u21D2 \u767D\u5B57\u4E24\u4E2A\u4E3B\u9898\u90FD\u53EF\u8BFB\uFF0C
101
101
  \u6545\u8FD9\u662F\u4E00\u6761\u4E0E\u4E3B\u9898\u65E0\u5173\u7684\u5E38\u91CF\uFF1B\u4E0D\u8981\u62FF --dshpc-fg-inverse \u9876\u2014\u2014\u5B83\u5728\u6697\u8272\u4E0B\u662F\u8FD1\u9ED1\uFF0C\u538B\u5728\u7EA2\u5E95\u4E0A\u770B\u4E0D\u6E05\u3002 */
102
102
  --dshpc-on-signal:#fff;
103
+ /* \u9EC4\u5E95\u4E0A\u7684\u5B57\uFF1A\u9EC4\u8272\u662F\u4E2D\u9AD8\u660E\u5EA6\uFF0C\u767D\u5B57\u770B\u4E0D\u6E05 \u21D2 \u56FA\u5B9A\u6DF1\u8272\uFF08\u4E0E\u4E3B\u9898\u65E0\u5173\uFF09\u3002 */
104
+ --dshpc-on-warning:#1f2328;
105
+
106
+ /* \u2500\u2500 \u5B9E\u5FC3\u6309\u94AE\u7684 hover / active \u6D3E\u751F\u6001\uFF082026-10-19 \u7528\u6237\u70B9\u540D\uFF09\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
107
+ \u539F\u5B9E\u73B0\u662F :hover \u76F4\u63A5\u538B opacity .9\uFF1A\u9ED1\u5E95\u538B 10% \u51E0\u4E4E\u770B\u4E0D\u51FA\u6765\uFF0C\u7528\u6237\u539F\u8BDD\u300C\u5B8C\u5168\u611F\u89C9\u4E0D\u5230\u989C\u8272\u53D8\u4E86\u300D\u3002
108
+ \u21D2 \u6539\u6210\u5BF9\u5E95\u8272\u505A**\u660E\u786E\u7684\u6DF7\u8272**\uFF08\u538B 22% / 34%\uFF09\uFF0C\u4E0D\u7528 opacity\uFF1A
109
+ \xB7 \u4EAE\u8272\u4E3B\u9898\uFF1A\u9ED1\u5E95\uFF08--dshpc-accent\uFF09\u63BA\u767D\u63D0\u4EAE\uFF1B\u7EA2 / \u7EFF / \u9EC4 / \u84DD\u5E95\u63BA\u9ED1\u538B\u6DF1\uFF1B
110
+ \xB7 \u6697\u8272\u4E3B\u9898\uFF1A\u53CD\u8FC7\u6765\uFF08\u6697\u5E95\u63BA\u767D\u3001\u4EAE\u5E95\u63BA\u9ED1\uFF09\u3002
111
+ \u6DF7\u8272\u5BF9\u8C61\u662F**\u56FA\u5B9A\u4E2D\u6027\u8272\u5B57\u9762\u91CF**\uFF08#fff / #000\uFF09\uFF0C\u4E0D\u4F9D\u8D56\u5BBF\u4E3B static-neutral \u662F\u5426\u5B58\u5728\uFF1B
112
+ \u65E7\u5185\u6838\u4E0D\u8BA4 color-mix \u65F6\u6574\u6761\u58F0\u660E\u4F5C\u5E9F \u21D2 \u56DE\u843D\u5404\u6863\u539F\u8272\uFF08\u53EF\u63A5\u53D7\uFF1A\u4ECD\u53EF\u70B9\uFF0C\u53EA\u662F\u6CA1\u6709 hover \u53CD\u9988\uFF09\u3002 */
113
+ --dshpc-accent-hover:color-mix(in srgb,var(--dshpc-accent) 78%,#ffffff);
114
+ --dshpc-accent-active:color-mix(in srgb,var(--dshpc-accent) 64%,#ffffff);
115
+ --dshpc-danger-hover:color-mix(in srgb,var(--dshpc-danger) 78%,#000000);
116
+ --dshpc-danger-active:color-mix(in srgb,var(--dshpc-danger) 64%,#000000);
117
+ --dshpc-success-hover:color-mix(in srgb,var(--dshpc-success) 78%,#000000);
118
+ --dshpc-success-active:color-mix(in srgb,var(--dshpc-success) 64%,#000000);
119
+ --dshpc-warning-hover:color-mix(in srgb,var(--dshpc-warning) 78%,#000000);
120
+ --dshpc-warning-active:color-mix(in srgb,var(--dshpc-warning) 64%,#000000);
121
+ --dshpc-business-hover:color-mix(in srgb,var(--dshpc-business) 78%,#000000);
122
+ --dshpc-business-active:color-mix(in srgb,var(--dshpc-business) 64%,#000000);
103
123
  /* \u8BED\u4E49\u8272**\u6D45\u5E95**\uFF1A\u72B6\u6001\u8272\u7CFB\u7684\u300C\u4E00\u5757\u5E95\u8272\u300D\u2014\u2014\u6267\u884C\u8BB0\u5F55\u9875\u6BCF\u6761\u6D41\u6C34\u8D26\u7684\u5757\u5E95\u5C31\u662F\u5B83
104
124
  \uFF08\u7528\u6237 2026-10-04\uFF1A\u6B63\u5E38\u6001\u7ED9\u540C\u8272\u7CFB\u5F88\u6D45\u7684\u900F\u660E\u5E95\u3001\u5931\u8D25\u7528\u7EA2\u5E95\u900F\u51FA\u6765\uFF09\u3002
105
125
  \u7528 \u300Ccolor-mix\u300D \u73B0\u7B97\u800C\u4E0D\u5199\u6B7B rgba\uFF1A\u72B6\u6001\u8272\u672C\u8EAB\u8DDF\u968F\u5BBF\u4E3B alias\uFF0C\u4E3B\u9898\u4E00\u6362\u81EA\u52A8\u6210\u7ACB\u3002
@@ -211,6 +231,18 @@ body{
211
231
  body[data-ds-dark-theme]{
212
232
  --dshpc-solid:var(--dsw-static-neutral-900,#0f0f0f);
213
233
  --dshpc-on-solid:var(--dsw-static-neutral-00,#fff);
234
+ /* \u5B9E\u5FC3\u6309\u94AE hover / active\uFF08\u6697\u8272\u7248\uFF09\uFF1A\u9ED1\u5E95\uFF08\u6D45\u8272\u4E3B\u9898\u7684\u8FD1\u9ED1 \u2192 \u6697\u8272\u4E0B\u7684\u8FD1\u767D\uFF09\u63BA\u9ED1\u538B\u6DF1\uFF1B
235
+ \u7EA2 / \u7EFF / \u9EC4 / \u84DD\u63BA\u767D\u63D0\u4EAE\u3002\u4E0E\u4EAE\u8272\u6BB5\u65B9\u5411\u76F8\u53CD\uFF0C\u4FDD\u8BC1\u4E24\u79CD\u4E3B\u9898\u4E0B\u300C\u4E00\u773C\u770B\u51FA\u53D8\u4E86\u300D\u3002 */
236
+ --dshpc-accent-hover:color-mix(in srgb,var(--dshpc-accent) 80%,#000000);
237
+ --dshpc-accent-active:color-mix(in srgb,var(--dshpc-accent) 66%,#000000);
238
+ --dshpc-danger-hover:color-mix(in srgb,var(--dshpc-danger) 78%,#ffffff);
239
+ --dshpc-danger-active:color-mix(in srgb,var(--dshpc-danger) 64%,#ffffff);
240
+ --dshpc-success-hover:color-mix(in srgb,var(--dshpc-success) 78%,#ffffff);
241
+ --dshpc-success-active:color-mix(in srgb,var(--dshpc-success) 64%,#ffffff);
242
+ --dshpc-warning-hover:color-mix(in srgb,var(--dshpc-warning) 78%,#ffffff);
243
+ --dshpc-warning-active:color-mix(in srgb,var(--dshpc-warning) 64%,#ffffff);
244
+ --dshpc-business-hover:color-mix(in srgb,var(--dshpc-business) 78%,#ffffff);
245
+ --dshpc-business-active:color-mix(in srgb,var(--dshpc-business) 64%,#ffffff);
214
246
  /* \u6697\u8272 hover \u63BA\u767D 14% / active 24%\uFF08\u5BF9\u9F50\u4E0A\u9762 2026-10-18 \u7684\u52A0\u91CD\u62CD\u677F\uFF09\u3002rgba \u515C\u5E95\u884C\u540C\u4E0A\u3002 */
215
247
  --dshpc-hover:rgba(255,255,255,.14);
216
248
  --dshpc-hover:color-mix(in srgb,var(--dsw-static-neutral-00,#fff) 14%,transparent);
@@ -338,20 +370,27 @@ var SEGMENTED_CSS = `
338
370
  inset \u65E0\u8FB9\u6846\u6545 padding \u6536 3px \u628A\u7F3A\u7684 1px \u8865\u56DE\uFF0C\u4E24\u79CD\u5916\u89C2\u603B\u9AD8\u90FD == token\uFF0824/28/32\uFF09\uFF0C\u4E0D\u518D\u591A +2px\u3002
339
371
  \u4EE5\u540E Button / Input \u7684\u6709\u8FB9 / \u65E0\u8FB9\u540C\u6B64\u89C4\u5219\u3002 */
340
372
  .dshpc-seg{display:inline-flex;align-items:center;gap:2px;padding:2px;border-radius:var(--dshpc-radius-md);background:var(--seg-track);}
341
- /* \u9009\u4E2D\u7247 = --dshpc-solid\uFF08\u4EAE=\u767D\u7247 / \u6697=\u9ED1\u7247\uFF0C2026-10-18 \u5BF9\u9F50\u771F\u5B9E\u63D2\u4EF6\u622A\u56FE\uFF09\u3002
342
- \u539F\u5148\u53D6 surface-raised \u21D2 \u4E0E\u5361\u7247\u5E95\uFF08\u540C\u4E3A bg-layer-1\uFF09\u540C\u8272\uFF0C\u9009\u4E2D\u7247\u5728\u5361\u4E0A\u9690\u5F62\u3001\u53EA\u5269\u9634\u5F71\u5708\u3002 */
343
- .dshpc-seg--default{--seg-track:var(--dshpc-surface-2);--seg-thumb:var(--dshpc-solid);border:1px solid var(--dshpc-border);}
344
- .dshpc-seg--inset{--seg-track:var(--dshpc-hover);--seg-thumb:var(--dshpc-solid);border:0;padding:3px;}
373
+ /* \u9009\u4E2D\u7247 = --dshpc-surface-raised\uFF08\u5144\u5F1F\u9879\u76EE dsh-task-dispatch-table \u7684\u53D6\u6CD5\uFF0C2026-10-19 \u7528\u6237\u70B9\u540D
374
+ \u300C\u628A\u5144\u5F1F\u7684\u6837\u5F0F\u6E05\u4E86\u5C31\u4E0D\u6B63\u5E38 \u21D2 \u6CA1\u642C\u5168\u300D\u540E\u6539\u56DE\uFF09\u300210-18 \u66FE\u6539\u6210 --dshpc-solid\uFF0C\u4F46\u5B83\u5728\u6697\u8272\u4E3B\u9898\u4E0B
375
+ \u662F\u8FD1\u9ED1\uFF08\u6BD4\u8F68\u9053\u8FD8\u6697\uFF09\u21D2 \u9009\u4E2D\u7247\u9677\u8FDB\u8F68\u9053\u91CC\uFF1Braised \u5728\u4E24\u4E2A\u4E3B\u9898\u4E0B\u90FD\u6BD4\u8F68\u9053\u4EAE\u4E00\u6863\uFF0C\u65B9\u5411\u6B63\u786E\u3002
376
+ raised \u4E0E\u5361\u7247\u5E95\u540C\u4E3A bg-layer-1 \u21D2 \u9009\u4E2D\u7247\u9760**1px \u63CF\u8FB9 + \u9634\u5F71**\u4E0E\u5361\u7247\u533A\u5206\uFF08\u89C1 __item[aria-pressed]\uFF09\u3002 */
377
+ .dshpc-seg--default{--seg-track:var(--dshpc-surface-2);--seg-thumb:var(--dshpc-surface-raised);border:1px solid var(--dshpc-border);}
378
+ .dshpc-seg--inset{--seg-track:var(--dshpc-hover);--seg-thumb:var(--dshpc-surface-raised);border:0;padding:3px;}
345
379
 
346
380
  .dshpc-seg__item{appearance:none;display:inline-flex;align-items:center;gap:4px;box-sizing:border-box;
347
- height:calc(var(--dshpc-control-h-sm) - 6px);padding:0 12px;border:0;border-radius:var(--dshpc-radius-sm);
381
+ height:calc(var(--dshpc-control-h-sm) - 6px);padding:0 12px;border:1px solid transparent;border-radius:var(--dshpc-radius-sm);
348
382
  background:transparent;color:var(--dshpc-fg-2);font-family:inherit;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);
349
383
  font-weight:400;white-space:nowrap;cursor:pointer;
350
384
  transition:color var(--dshpc-dur-fast) var(--dshpc-ease),background-color var(--dshpc-dur-fast) var(--dshpc-ease),box-shadow var(--dshpc-dur-fast) var(--dshpc-ease);}
351
385
  .dshpc-seg--md .dshpc-seg__item{height:calc(var(--dshpc-control-h-md) - 6px);}
352
386
  .dshpc-seg--lg .dshpc-seg__item{height:calc(var(--dshpc-control-h-lg) - 6px);}
353
- .dshpc-seg__item:hover:not([aria-pressed='true']):not(:disabled){color:var(--dshpc-fg);}
354
- .dshpc-seg__item[aria-pressed='true']{background:var(--seg-thumb);box-shadow:var(--dshpc-shadow-raised);color:var(--dshpc-fg);font-weight:600;}
387
+ /* \u672A\u9009\u4E2D\u9879 hover\uFF1A\u7ED9\u4E00\u5C42\u6D45\u5E95\uFF08\u6B64\u524D\u53EA\u63D0\u4EAE\u6587\u5B57\uFF0C\u7528\u6237\u770B\u4E0D\u51FA\u300C\u8FD9\u91CC\u53EF\u4EE5\u70B9\u300D\uFF09\u3002
388
+ inset \u7684\u8F68\u9053\u672C\u8EAB\u5C31\u662F --dshpc-hover \u21D2 \u90A3\u91CC\u7528 active \u4E00\u6863\uFF0C\u907F\u514D hover \u4E0E\u8F68\u9053\u540C\u8272\u7B49\u4E8E\u6CA1\u53D8\u3002 */
389
+ .dshpc-seg__item:hover:not([aria-pressed='true']):not(:disabled){color:var(--dshpc-fg);background:var(--dshpc-hover);}
390
+ .dshpc-seg--inset .dshpc-seg__item:hover:not([aria-pressed='true']):not(:disabled){background:var(--dshpc-active);}
391
+ /* \u9009\u4E2D\u7247\uFF1A\u4EAE\u7247 + \u63CF\u8FB9 + \u6D6E\u8D77\u9634\u5F71 \u21D2 \u5728\u5361\u7247\u5E95\uFF08\u4E0E\u4EAE\u7247\u540C\u8272\uFF09\u4E0A\u4E5F\u770B\u5F97\u51FA\u8FB9\u754C */
392
+ .dshpc-seg__item[aria-pressed='true']{background:var(--seg-thumb);border-color:var(--dshpc-border);
393
+ box-shadow:var(--dshpc-shadow-raised);color:var(--dshpc-fg);font-weight:600;}
355
394
  .dshpc-seg__item:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:-2px;}
356
395
  .dshpc-seg__item:disabled{cursor:default;opacity:.4;}
357
396
 
@@ -394,33 +433,91 @@ var BUTTON_CSS = `
394
433
  /* \u2500\u2500 \u6309\u94AE / \u56FE\u6807\u94AE P2 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
395
434
  \u4E0E Segmented \u540C\u4E00\u6761\u9AD8\u5EA6\u7EAA\u5F8B\uFF1A--dshpc-control-h-sm(24) / -md(28) / -lg(32)\uFF0C
396
435
  \u6709\u8FB9\u6846\u7684 variant \u7528 1px \u771F\u8FB9\u6846 + \u5185\u90E8 padding \u8865\u56DE\uFF0C**\u6709\u8FB9 / \u65E0\u8FB9\u540C\u9AD8**\u3002
397
- variant \u53EA\u6362\u989C\u8272\uFF0C\u7ED3\u6784 / \u5C3A\u5BF8 / \u4EA4\u4E92\u53EA\u6B64\u4E00\u4EFD\u3002 */
398
- .dshpc-btn{appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:var(--dshpc-space-1);
399
- box-sizing:border-box;border:1px solid transparent;border-radius:var(--dshpc-radius-md);
400
- background:transparent;color:var(--dshpc-fg);font-family:inherit;font-weight:500;white-space:nowrap;cursor:pointer;
401
- transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),border-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease),opacity var(--dshpc-dur-fast) var(--dshpc-ease);}
402
- .dshpc-btn--sm{height:var(--dshpc-control-h-sm);padding:0 10px;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);}
403
- .dshpc-btn--md{height:var(--dshpc-control-h-md);padding:0 12px;font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}
404
- .dshpc-btn--lg{height:var(--dshpc-control-h-lg);padding:0 14px;font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}
405
- .dshpc-btn__icon{display:inline-flex;align-items:center;flex:none;}
406
-
407
- .dshpc-btn--primary{background:var(--dshpc-accent);color:var(--dshpc-fg-inverse);}
408
- .dshpc-btn--primary:hover:not(:disabled){opacity:.9;}
409
- .dshpc-btn--outline{background:var(--dshpc-surface-1);border-color:var(--dshpc-border-strong);color:var(--dshpc-fg);}
410
- .dshpc-btn--outline:hover:not(:disabled){background:var(--dshpc-hover);}
411
- .dshpc-btn--ghost{color:var(--dshpc-fg-2);}
412
- .dshpc-btn--ghost:hover:not(:disabled){background:var(--dshpc-hover);color:var(--dshpc-fg);}
413
- .dshpc-btn--danger{background:var(--dshpc-danger);color:var(--dshpc-on-signal);}
414
- .dshpc-btn--danger:hover:not(:disabled){opacity:.9;}
415
- /* danger-ink\uFF1A\u7EA2\u5B57\u63CF\u8FB9\uFF08\u7834\u574F\u6027\u6B21\u8981\u64CD\u4F5C\uFF0C\u5982\u5361\u7247\u4E0A\u7684\u300C\u5220\u9664\u300D\uFF09\uFF0C\u6302\u4E0E outline \u7EC4\u5408\u7684\u4FEE\u9970\u7C7B */
416
- .dshpc-btn--danger-ink{border-color:var(--dshpc-danger);color:var(--dshpc-danger);}
417
- .dshpc-btn--danger-ink:hover:not(:disabled){background:color-mix(in srgb,var(--dshpc-danger) 10%,transparent);color:var(--dshpc-danger);}
418
- /* link\uFF1A\u884C\u5185\u6587\u5B57\u94FE\u63A5\u578B\uFF08\u4F1A\u8BDD / \u4EA7\u51FA\u6587\u4EF6\u540D\uFF09\uFF0C\u65E0\u5E95\u65E0\u8FB9\u3001\u54C1\u724C\u84DD\u3001hover \u4E0B\u5212\u7EBF */
419
- .dshpc-btn--link{height:auto;padding:0;border:0;background:none;color:var(--dshpc-link);font-weight:400;text-align:left;}
420
- .dshpc-btn--link:hover:not(:disabled){background:none;color:var(--dshpc-link);text-decoration:underline;}
436
+
437
+ \u4E09\u6761\u53D7\u63A7\u8F74\uFF082026-10-19 \u91CD\u5199\uFF0C\u5BF9\u9F50\u4E3B\u6D41 UI \u6846\u67B6\u7684\u5206\u7C7B\u53E3\u5F84\uFF09\uFF1A
438
+ \xB7 variant \u2014\u2014 \u5916\u89C2\u6863 = \u5F62\u6001 + \u8BED\u4E49\u8272\uFF0C\u5171 10 \u6863\uFF1A
439
+ primary / secondary / outline / ghost / danger / success / warning / info /
440
+ danger-outline\uFF08\u7EA2\u5B57\u63CF\u8FB9\uFF09/ link\uFF08\u884C\u5185\u94FE\u63A5\uFF09
441
+ \xB7 size \u2014\u2014 sm / md / lg
442
+ \xB7 block \u2014\u2014 \u6491\u6EE1\u7236\u5BBD
443
+ \u6BCF\u4E00\u6863**\u53EA\u586B 5 \u4E2A\u5C40\u90E8\u53D8\u91CF**\uFF08--btn-bg / -fg / -border / -bg-hover / -bg-active\uFF09\uFF0C
444
+ \u7ED3\u6784\u4E0E\u4EA4\u4E92\u53EA\u6709\u4E0A\u9762\u8FD9\u4E00\u4EFD\uFF1B\u4EFB\u4F55\u6863\u4F4D\u90FD\u4E0D\u8BB8\u518D\u5199\u4E00\u904D display/height/padding\u3002
445
+ \u81EA\u5B9A\u4E49\u989C\u8272\uFF08Button \u7684 color \u53C2\u6570\uFF09\u540C\u6837\u53EA\u8986\u76D6\u8FD9 5 \u4E2A\u53D8\u91CF\uFF08token \u8986\u76D6\uFF0C\u4E0D\u662F\u65B0\u76AE\u80A4\uFF09\u3002
446
+
447
+ \u26A0\uFE0F hover \u4E0D\u518D\u7528 opacity \u538B\u4E00\u5C42\uFF08\u7528\u6237 2026-10-19\uFF1A\u300C\u9ED1\u8272\u548C\u7EA2\u8272\u7684\u6309\u94AE\u79FB\u4E0A\u53BB\u53D8\u5316\u592A\u5C0F\uFF0C
448
+ \u5B8C\u5168\u611F\u89C9\u4E0D\u5230\u989C\u8272\u53D8\u4E86\u300D\uFF09\u21D2 \u8D70 --dshpc-*-hover / -active \u7684\u660E\u786E\u6DF7\u8272\uFF0C\u89C1 tokens-css.ts\u3002 */
449
+ .dshpc-btn{--btn-bg:transparent;--btn-fg:var(--dshpc-fg);--btn-border:transparent;--btn-pad:12px;
450
+ --btn-bg-hover:var(--dshpc-hover);--btn-bg-active:var(--dshpc-active);--btn-fg-hover:var(--btn-fg);
451
+ appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:6px;
452
+ box-sizing:border-box;border:1px solid var(--btn-border);border-radius:var(--dshpc-radius-md);
453
+ background-color:var(--btn-bg);color:var(--btn-fg);font-family:inherit;font-weight:500;white-space:nowrap;cursor:pointer;
454
+ transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),border-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease),box-shadow var(--dshpc-dur-fast) var(--dshpc-ease),transform var(--dshpc-dur-fast) var(--dshpc-ease);}
455
+ .dshpc-btn--sm{--btn-pad:10px;height:var(--dshpc-control-h-sm);padding:0 var(--btn-pad);font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);}
456
+ .dshpc-btn--md{--btn-pad:12px;height:var(--dshpc-control-h-md);padding:0 var(--btn-pad);font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}
457
+ .dshpc-btn--lg{--btn-pad:14px;height:var(--dshpc-control-h-lg);padding:0 var(--btn-pad);font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}
458
+ /* block\uFF1A\u6491\u6EE1\u7236\u5BBD\uFF08\u8868\u5355\u5E95\u680F / \u62BD\u5C49\u5E95\u90E8\u7684\u4E3B\u64CD\u4F5C\uFF09 */
459
+ .dshpc-btn--block{display:flex;width:100%;}
460
+ /* block + \u524D\u7F6E\u56FE\u6807 \u21D2 \u6587\u5B57\u89C6\u89C9\u5C45\u4E2D\uFF082026-10-19 \u7528\u6237\u70B9\u540D\uFF09\uFF1A
461
+ \u5185\u5BB9\u7EC4 [\u56FE\u6807 + \u95F4\u8DDD + \u6587\u5B57] \u6574\u4F53\u5728\u76D2\u5185\u5C45\u4E2D\u65F6\uFF0C**\u6587\u5B57**\u7684\u4E2D\u5FC3\u4F1A\u88AB\u56FE\u6807\u63A8\u53F3\u534A\u683C\u3002
462
+ \u628A\u53F3\u5185\u8FB9\u8DDD\u8865\u4E0A\u300C\u56FE\u6807\u5BBD + \u95F4\u8DDD\u300D\uFF0C\u53EF\u7528\u76D2\u968F\u4E4B\u5DE6\u79FB\u540C\u91CF \u21D2 \u6587\u5B57\u843D\u56DE\u89C6\u89C9\u4E2D\u5FC3\uFF0C\u56FE\u6807\u8D34\u5DE6\u4FA7\u3002
463
+ \u56FE\u6807\u5BBD\u6309 1.2em \u4F30\uFF08\u5B98\u65B9\u56FE\u6807 14/16px vs \u5B57\u53F7 12/13px\uFF09\uFF0Cem \u968F\u5B57\u53F7\u6863\u81EA\u52A8\u7F29\u653E\u3002 */
464
+ .dshpc-btn--block.dshpc-btn--icon-start{padding-right:calc(var(--btn-pad) + 1.2em + 6px);}
465
+ .dshpc-btn__icon,.dshpc-btn__icon-end{display:inline-flex;align-items:center;justify-content:center;flex:none;}
466
+ /* loading\uFF1A\u4E0D\u6362 DOM \u7ED3\u6784\uFF0C\u53EA\u5728\u6587\u6848\u524D\u63D2\u4E00\u4E2A\u540C\u8272\u5C0F\u5708\uFF08\u5C3A\u5BF8\u968F\u5B57\u53F7\uFF0C\u7F29\u653E\u4E0D\u4F9D\u8D56\u5E38\u91CF\uFF09 */
467
+ .dshpc-btn__spinner{display:inline-block;flex:none;width:1em;height:1em;box-sizing:border-box;
468
+ border:1.5px solid currentColor;border-right-color:transparent;border-radius:50%;
469
+ animation:dshpc-btn-spin .7s linear infinite;}
470
+ @keyframes dshpc-btn-spin{to{transform:rotate(360deg)}}
471
+
472
+ /* \u4EA4\u4E92\u6001\uFF1A\u989C\u8272\u53D8\u5316\u5199\u5728\u53D8\u91CF\u4E0A \u21D2 \u6240\u6709\u6863\u4F4D\u4E00\u6B21\u751F\u6548\uFF0C\u4E14\u53D8\u5316\u5E45\u5EA6\u7531 token \u51B3\u5B9A\uFF08\u591F\u660E\u663E\uFF09 */
473
+ .dshpc-btn:hover:not(:disabled){background-color:var(--btn-bg-hover);color:var(--btn-fg-hover);}
474
+ .dshpc-btn:active:not(:disabled){background-color:var(--btn-bg-active);transform:translateY(1px);}
421
475
  .dshpc-btn:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:2px;}
422
476
  .dshpc-btn:disabled{cursor:default;opacity:.5;}
423
477
 
478
+ .dshpc-btn--primary{--btn-bg:var(--dshpc-accent);--btn-fg:var(--dshpc-fg-inverse);
479
+ --btn-bg-hover:var(--dshpc-accent-hover);--btn-bg-active:var(--dshpc-accent-active);}
480
+ /* secondary\uFF1A\u4E2D\u6027\u5B9E\u5FC3\uFF08\u7070\u9762\uFF09\uFF0C\u7528\u4E8E\u300C\u53D6\u6D88 / \u6B21\u8981\u300D\u8FD9\u7C7B\u4E0E\u4E3B\u64CD\u4F5C\u5E76\u6392\u7684\u6309\u94AE */
481
+ .dshpc-btn--secondary{--btn-bg:var(--dshpc-hover);--btn-fg:var(--dshpc-fg);
482
+ --btn-bg-hover:var(--dshpc-active);--btn-bg-active:var(--dshpc-active);}
483
+ .dshpc-btn--outline{--btn-bg:var(--dshpc-surface-1);--btn-border:var(--dshpc-border-strong);
484
+ --btn-bg-hover:var(--dshpc-hover);--btn-bg-active:var(--dshpc-active);}
485
+ .dshpc-btn--ghost{--btn-fg:var(--dshpc-fg-2);--btn-fg-hover:var(--dshpc-fg);
486
+ --btn-bg-hover:var(--dshpc-hover);--btn-bg-active:var(--dshpc-active);}
487
+ .dshpc-btn--danger{--btn-bg:var(--dshpc-danger);--btn-fg:var(--dshpc-on-signal);
488
+ --btn-bg-hover:var(--dshpc-danger-hover);--btn-bg-active:var(--dshpc-danger-active);}
489
+ .dshpc-btn--success{--btn-bg:var(--dshpc-success);--btn-fg:var(--dshpc-on-signal);
490
+ --btn-bg-hover:var(--dshpc-success-hover);--btn-bg-active:var(--dshpc-success-active);}
491
+ .dshpc-btn--warning{--btn-bg:var(--dshpc-warning);--btn-fg:var(--dshpc-on-warning);
492
+ --btn-bg-hover:var(--dshpc-warning-hover);--btn-bg-active:var(--dshpc-warning-active);}
493
+ .dshpc-btn--info{--btn-bg:var(--dshpc-business);--btn-fg:var(--dshpc-on-signal);
494
+ --btn-bg-hover:var(--dshpc-business-hover);--btn-bg-active:var(--dshpc-business-active);}
495
+ /* danger-outline\uFF1A\u7EA2\u5B57\u63CF\u8FB9\uFF08\u7834\u574F\u6027\u6B21\u8981\u64CD\u4F5C\uFF0C\u5982\u5361\u7247\u4E0A\u7684\u300C\u5220\u9664\u300D\uFF09\u3002
496
+ \u26A0\uFE0F \u65E7\u4FEE\u9970\u7C7B danger-ink \u4FDD\u7559\u4E3A\u522B\u540D\uFF08\u6D88\u8D39\u65B9\u53EF\u80FD\u8FD8\u5728\u6302\uFF09\uFF0C\u4E24\u8005\u540C\u4E00\u5957\u76AE\u80A4\u3002 */
497
+ .dshpc-btn--danger-outline,.dshpc-btn--danger-ink{--btn-border:var(--dshpc-danger);--btn-fg:var(--dshpc-danger);
498
+ --btn-fg-hover:var(--dshpc-danger);--btn-bg-hover:var(--dshpc-danger-soft);--btn-bg-active:var(--dshpc-danger-soft);}
499
+ /* link\uFF1A\u884C\u5185\u6587\u5B57\u94FE\u63A5\u578B\uFF08\u4F1A\u8BDD / \u4EA7\u51FA\u6587\u4EF6\u540D\uFF09\uFF0C\u65E0\u5E95\u65E0\u8FB9\u3001\u54C1\u724C\u84DD\u3001hover \u4E0B\u5212\u7EBF */
500
+ .dshpc-btn--link{--btn-fg:var(--dshpc-link);--btn-fg-hover:var(--dshpc-link);
501
+ --btn-bg-hover:transparent;--btn-bg-active:transparent;
502
+ height:auto;padding:0;border:0;background:none;font-weight:400;text-align:left;}
503
+ .dshpc-btn--link:hover:not(:disabled){text-decoration:underline;}
504
+
505
+ /* \u56FE\u6807\u94AE\uFF1A\u7EAF\u56FE\u6807\uFF0C\u65B9\u5F62\uFF1B\u5C3A\u5BF8\u6863\u7684\u5BBD\u9AD8\u4E0E\u540C\u6863\u6587\u5B57\u6309\u94AE\u7B49\u9AD8 */
506
+ .dshpc-iconbtn{appearance:none;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;
507
+ border:1px solid transparent;border-radius:var(--dshpc-radius-sm);background:transparent;color:var(--dshpc-fg-2);
508
+ font-family:inherit;cursor:pointer;flex:none;
509
+ transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),border-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease),opacity var(--dshpc-dur-fast) var(--dshpc-ease);}
510
+ .dshpc-iconbtn--sm{width:var(--dshpc-control-h-sm);height:var(--dshpc-control-h-sm);font-size:var(--dshpc-font-sm);}
511
+ .dshpc-iconbtn--md{width:var(--dshpc-control-h-md);height:var(--dshpc-control-h-md);font-size:var(--dshpc-font-md);}
512
+ .dshpc-iconbtn--lg{width:var(--dshpc-control-h-lg);height:var(--dshpc-control-h-lg);font-size:var(--dshpc-font-md);}
513
+ .dshpc-iconbtn--plain{color:var(--dshpc-fg-2);}
514
+ .dshpc-iconbtn--outline{background:var(--dshpc-surface-1);border-color:var(--dshpc-border);color:var(--dshpc-fg-2);}
515
+ .dshpc-iconbtn--danger{color:var(--dshpc-danger);}
516
+ .dshpc-iconbtn:hover:not(:disabled){background:var(--dshpc-hover);color:var(--dshpc-fg);}
517
+ .dshpc-iconbtn--danger:hover:not(:disabled){background:var(--dshpc-danger-soft);color:var(--dshpc-danger);}
518
+ .dshpc-iconbtn:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:2px;}
519
+ .dshpc-iconbtn:disabled{cursor:default;opacity:.4;}
520
+
424
521
  .dshpc-iconbtn{appearance:none;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;
425
522
  border:1px solid transparent;border-radius:var(--dshpc-radius-sm);background:transparent;color:var(--dshpc-fg-2);
426
523
  font-family:inherit;cursor:pointer;flex:none;
@@ -1413,19 +1510,40 @@ var ErrorBoundary = class extends import_react8.Component {
1413
1510
 
1414
1511
  // dist/ui/Button.js
1415
1512
  var import_react9 = require("react");
1416
- function buttonClass(variant, size, extra) {
1417
- return `dshpc-btn dshpc-btn--${variant} dshpc-btn--${size}${extra !== void 0 && extra !== "" ? ` ${extra}` : ""}`;
1513
+ var SOLID_VARIANTS = ["primary", "secondary", "danger", "success", "warning", "info"];
1514
+ function colorVars(variant, color) {
1515
+ if (color === void 0 || color === "")
1516
+ return void 0;
1517
+ if (SOLID_VARIANTS.includes(variant)) {
1518
+ return {
1519
+ "--btn-bg": color,
1520
+ // 亮色主题下 --dshpc-fg 是黑 ⇒ 压深;暗色下是白 ⇒ 提亮。两边都能明确看出变化。
1521
+ "--btn-bg-hover": `color-mix(in srgb, ${color} 82%, var(--dshpc-fg))`,
1522
+ "--btn-bg-active": `color-mix(in srgb, ${color} 70%, var(--dshpc-fg))`
1523
+ };
1524
+ }
1525
+ return {
1526
+ "--btn-fg": color,
1527
+ "--btn-fg-hover": color,
1528
+ "--btn-border": color,
1529
+ "--btn-bg-hover": `color-mix(in srgb, ${color} 12%, transparent)`,
1530
+ "--btn-bg-active": `color-mix(in srgb, ${color} 18%, transparent)`
1531
+ };
1532
+ }
1533
+ function buttonClass(variant, size, block, hasIcon, extra) {
1534
+ return `dshpc-btn dshpc-btn--${variant} dshpc-btn--${size}${block ? " dshpc-btn--block" : ""}${hasIcon ? " dshpc-btn--icon-start" : ""}${extra !== void 0 && extra !== "" ? ` ${extra}` : ""}`;
1418
1535
  }
1419
1536
  function Button(props) {
1420
1537
  ensureControls();
1421
- const { variant = "outline", size = "lg", icon, className, style, children, ...rest } = props;
1538
+ const { variant = "outline", size = "lg", icon, iconRight, color, loading = false, block = false, className, style, children, ...rest } = props;
1422
1539
  const attrs = {
1423
1540
  ...rest,
1424
1541
  type: rest.type ?? "button",
1425
- className: buttonClass(variant, size, className),
1426
- style
1542
+ disabled: rest.disabled === true || loading,
1543
+ className: buttonClass(variant, size, block, icon !== void 0 && icon !== null && !loading, className),
1544
+ style: { ...colorVars(variant, color), ...style }
1427
1545
  };
1428
- return (0, import_react9.createElement)("button", attrs, icon !== void 0 && icon !== null ? (0, import_react9.createElement)("span", { className: "dshpc-btn__icon" }, icon) : null, children);
1546
+ return (0, import_react9.createElement)("button", attrs, loading ? (0, import_react9.createElement)("span", { className: "dshpc-btn__spinner", "aria-hidden": true }) : icon !== void 0 && icon !== null ? (0, import_react9.createElement)("span", { className: "dshpc-btn__icon" }, icon) : null, children, iconRight !== void 0 && iconRight !== null ? (0, import_react9.createElement)("span", { className: "dshpc-btn__icon-end" }, iconRight) : null);
1429
1547
  }
1430
1548
  function IconButton(props) {
1431
1549
  ensureControls();
@@ -1902,7 +2020,24 @@ var DICT2 = {
1902
2020
  pickerHint: "\u5355\u9009 / \u591A\u9009 / \u4E0A\u9650 / \u641C\u7D22 / \u5206\u7EC4 / \u7A7A\u6001 / \u964D\u7EA7\u2014\u2014\u5168\u90E8\u53EF\u7528 props \u63A7\u5236",
1903
2021
  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",
1904
2022
  workspacePickerHint: "\u6570\u636E\u8C03\u7528\u65B9\u7ED9\uFF08\u8981\u8DE8 host\u2194client \u8FB9\u754C\uFF0C\u7EC4\u4EF6\u53D6\u4E0D\u5230\uFF09",
1905
- buttonHint: "variant \u56DB\u6863 \xD7 size \u4E09\u6863",
2023
+ buttonHint: "10 \u6863\u5916\u89C2 \xD7 3 \u6863\u9AD8\u5EA6 \xD7 \u56FE\u6807 / \u72B6\u6001 / \u81EA\u5B9A\u4E49\u989C\u8272",
2024
+ btnTextTitle: "\u6309\u94AE\u6587\u6848\u4E0E\u8BED\u8A00",
2025
+ btnTextHint: "\u6587\u6848\u7531\u8C03\u7528\u65B9\u7ED9\uFF1A\u4E2D\u6587\u73AF\u5883\u51FA\u4E2D\u6587\u3001\u82F1\u6587\u73AF\u5883\u51FA\u82F1\u6587\uFF1B\u4E2D\u82F1\u5E76\u6392\u7684\u7EC4\u5408\u4E5F\u652F\u6301\uFF08\u6700\u53F3\u4E00\u9897\uFF09",
2026
+ btnVariantTitle: "\u5916\u89C2\u6863\uFF0810 \u6863\uFF09",
2027
+ btnVariantHint: "\u5B9E\u5FC3\uFF1Aprimary / secondary / danger / success / warning / info\uFF1B\u7EBF\u6846\uFF1Aoutline / danger-outline\uFF1B\u65E0\u5E95\uFF1Aghost / link",
2028
+ btnSizeTitle: "\u5C3A\u5BF8 / \u56FE\u6807 / block",
2029
+ btnSizeHint: "sm 24 \xB7 md 28 \xB7 lg 32 \u540C\u9AD8\uFF1Bicon \u6536\u7684\u662F ReactNode\u2014\u2014\u5B98\u65B9\u56FE\u6807\u7EC4\u4EF6\u3001\u81EA\u7ED8 SVG\u3001\u751A\u81F3\u4E00\u4E2A\u5B57\u7B26\u90FD\u884C\uFF0C\u4E0D\u662F\u540D\u5B57\u4E5F\u4E0D\u662F class\uFF08\u4E0B\u9762\u4E09\u9897\u5206\u522B\u662F\u8FD9\u4E09\u79CD\uFF09\uFF1BiconRight \u540E\u7F6E\u3001block \u6491\u6EE1\u7236\u5BBD",
2030
+ btnIconOnly: "\u7EAF\u56FE\u6807\u94AE",
2031
+ btnHintTitle: "\u95EE\u53F7\u63D0\u793A\uFF08FieldHint\uFF09",
2032
+ btnHintHint: "\u72EC\u7ACB\u7EC4\u4EF6\uFF0C\u653E\u54EA\u90FD\u884C\uFF1A\u6807\u9898\u540E / \u6309\u94AE\u540E / \u4E00\u6BB5\u6587\u5B57\u540E / \u8F93\u5165\u6846\u540E\uFF1B\u9F20\u6807\u60AC\u505C\u6216\u952E\u76D8\u805A\u7126\u6D6E\u51FA\u6C14\u6CE1",
2033
+ btnStateTitle: "\u72B6\u6001",
2034
+ btnStateHint: "disabled \u534A\u900F\u660E\u4E0D\u53EF\u70B9\uFF1Bloading \u524D\u7F6E\u540C\u8272\u5C0F\u5708\u5E76\u81EA\u52A8\u7981\u7528",
2035
+ btnColorTitle: "\u81EA\u5B9A\u4E49\u989C\u8272",
2036
+ btnColorHint: "color \u4F20\u4EFB\u610F CSS \u8272\u503C\uFF1A\u5B9E\u5FC3\u6863\u4F5C\u5E95\u8272\u3001\u7EBF\u6846\u4E0E\u6587\u5B57\u6863\u4F5C\u4E3B\u8272\uFF1Bhover / \u6309\u4E0B\u81EA\u52A8\u6309\u8BE5\u8272\u6DF7\u51FA",
2037
+ btnLabelSave: "\u4FDD\u5B58\u4FEE\u6539",
2038
+ btnLabelCancel: "\u53D6\u6D88",
2039
+ btnLabelDelete: "\u5220\u9664",
2040
+ btnLabelMixed: "\u4FDD\u5B58 Save",
1906
2041
  inputHint: "Input / PrefixedInput / NumberInput / Textarea\uFF0C\u90FD\u652F\u6301 error \u63CF\u7EA2\uFF1B\u884C\u5C3E\u53EF\u6302 FieldHint \u95EE\u53F7\u63D0\u793A",
1907
2042
  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",
1908
2043
  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",
@@ -1940,7 +2075,24 @@ var DICT2 = {
1940
2075
  pickerHint: "Single / multi / max / search / grouped / empty / degraded \u2014 all driven by props",
1941
2076
  modelPickerHint: "flat: one dropdown / cascade: pick provider then model \u2014 same data, two shapes",
1942
2077
  workspacePickerHint: "Data is supplied by the caller (crosses the host\u2194client boundary; the component cannot fetch it)",
1943
- buttonHint: "Four variants \xD7 three sizes",
2078
+ buttonHint: "10 variants \xD7 3 sizes \xD7 icons / states / custom colors",
2079
+ btnTextTitle: "Button labels & language",
2080
+ btnTextHint: "Labels come from the caller: Chinese in zh, English in en; a mixed zh+en label is fine too (rightmost)",
2081
+ btnVariantTitle: "Variants (10)",
2082
+ btnVariantHint: "Solid: primary / secondary / danger / success / warning / info; outlined: outline / danger-outline; flat: ghost / link",
2083
+ btnSizeTitle: "Sizes / icons / block",
2084
+ btnSizeHint: "sm 24 \xB7 md 28 \xB7 lg 32, same height; icon takes any ReactNode \u2014 an official icon component, your own SVG, even a single character (not a name, not a class); iconRight trails, block fills the parent",
2085
+ btnIconOnly: "Icon-only",
2086
+ btnHintTitle: "Question-mark hint (FieldHint)",
2087
+ btnHintHint: "Standalone component, drop it anywhere: after a title, a button, a sentence, or an input; hover or keyboard-focus to reveal",
2088
+ btnStateTitle: "States",
2089
+ btnStateHint: "disabled is dimmed and unclickable; loading shows a same-color spinner and disables itself",
2090
+ btnColorTitle: "Custom colors",
2091
+ btnColorHint: "Pass any CSS color as color: solid variants use it as fill, outlined/text variants as the accent; hover/press are mixed from it",
2092
+ btnLabelSave: "Save changes",
2093
+ btnLabelCancel: "Cancel",
2094
+ btnLabelDelete: "Delete",
2095
+ btnLabelMixed: "Save \u4FDD\u5B58",
1944
2096
  inputHint: "Input / PrefixedInput / NumberInput / Textarea, all support error highlighting; a FieldHint question-mark tip can hang at the row end",
1945
2097
  checkboxHint: "Looks match the real plugin: grey inset background (no outer border); the bordered default is for special cases only, see below",
1946
2098
  designTokenHint: "All colors come from design tokens; switch light/dark at top-right and these update with it",
@@ -2045,6 +2197,62 @@ ensureControls()`
2045
2197
 
2046
2198
  // packages/demo/src/sections/buttons.tsx
2047
2199
  var import_react20 = require("react");
2200
+ var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
2201
+ var BUTTON_ICONS = [
2202
+ { name: "plus", Icon: import_dsh_client_ui_primitives.IconPlusOutlineRegular },
2203
+ { name: "check", Icon: import_dsh_client_ui_primitives.IconCheckOutlineRegular },
2204
+ { name: "close", Icon: import_dsh_client_ui_primitives.IconCloseOutlineRegular },
2205
+ { name: "refresh", Icon: import_dsh_client_ui_primitives.IconRefreshOutlineRegular },
2206
+ { name: "copy", Icon: import_dsh_client_ui_primitives.IconCopyOutlineRegular },
2207
+ { name: "search", Icon: import_dsh_client_ui_primitives.IconSearchOutlineRegular },
2208
+ { name: "edit", Icon: import_dsh_client_ui_primitives.IconEditOutlineRegular },
2209
+ { name: "play", Icon: import_dsh_client_ui_primitives.IconPlayOutlineRegular },
2210
+ { name: "send", Icon: import_dsh_client_ui_primitives.IconPaperPlaneOutlineRegular },
2211
+ { name: "clock", Icon: import_dsh_client_ui_primitives.IconClockOutlineRegular },
2212
+ { name: "sparkle", Icon: import_dsh_client_ui_primitives.IconSparkleRegular },
2213
+ { name: "chevron", Icon: import_dsh_client_ui_primitives.IconChevronDownOutlineRegular }
2214
+ ];
2215
+ function iconOf(name, size = 14) {
2216
+ const found = BUTTON_ICONS.find((item) => item.name === name);
2217
+ return found === void 0 ? null : (0, import_react20.createElement)(found.Icon, { size });
2218
+ }
2219
+ function StarSvg() {
2220
+ return (0, import_react20.createElement)(
2221
+ "svg",
2222
+ { width: 14, height: 14, viewBox: "0 0 16 16", fill: "none", "aria-hidden": true },
2223
+ (0, import_react20.createElement)("path", {
2224
+ d: "M8 1.6l1.9 4 4.4.6-3.2 3 .8 4.3L8 11.4l-3.9 2.1.8-4.3-3.2-3 4.4-.6z",
2225
+ stroke: "currentColor",
2226
+ strokeWidth: 1.2,
2227
+ strokeLinejoin: "round"
2228
+ })
2229
+ );
2230
+ }
2231
+ var ICON_SIZE = { sm: 12, md: 14, lg: 16 };
2232
+ var VARIANTS = [
2233
+ { value: "primary", icon: "check" },
2234
+ { value: "secondary", icon: "copy" },
2235
+ { value: "outline", icon: "edit" },
2236
+ { value: "ghost", icon: "refresh" },
2237
+ { value: "danger", icon: "close" },
2238
+ { value: "success", icon: "play" },
2239
+ { value: "warning", icon: "clock" },
2240
+ { value: "info", icon: "send" },
2241
+ { value: "danger-outline", icon: "close" },
2242
+ { value: "link", icon: "search" }
2243
+ ];
2244
+ var CUSTOM_COLORS = ["#7c3aed", "#0ea5e9", "#f97316", "#16a34a"];
2245
+ function Row(props) {
2246
+ return (0, import_react20.createElement)("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", alignItems: "center" } }, props.children);
2247
+ }
2248
+ function Labeled(props) {
2249
+ return (0, import_react20.createElement)(
2250
+ "div",
2251
+ { style: { display: "flex", gap: "10px", alignItems: "center", flexWrap: "wrap" } },
2252
+ (0, import_react20.createElement)("span", { style: { width: "64px", flex: "none", color: "var(--dshpc-fg-3)", fontSize: "12px" } }, props.label),
2253
+ props.children
2254
+ );
2255
+ }
2048
2256
  function ButtonsSection() {
2049
2257
  const [text, setText] = (0, import_react20.useState)("");
2050
2258
  const [num, setNum] = (0, import_react20.useState)(3);
@@ -2055,21 +2263,152 @@ function ButtonsSection() {
2055
2263
  return (0, import_react20.createElement)(
2056
2264
  "div",
2057
2265
  null,
2266
+ // ── 文案与语言 ──────────────────────────────────────────────────────
2267
+ (0, import_react20.createElement)(
2268
+ Demo,
2269
+ { title: t2("btnTextTitle"), hint: t2("btnTextHint") },
2270
+ (0, import_react20.createElement)(
2271
+ "div",
2272
+ { style: { display: "flex", flexDirection: "column", gap: "12px" } },
2273
+ (0, import_react20.createElement)(
2274
+ Labeled,
2275
+ { label: "locale" },
2276
+ (0, import_react20.createElement)(Button, { variant: "primary", icon: iconOf("check", ICON_SIZE.lg) }, t2("btnLabelSave")),
2277
+ (0, import_react20.createElement)(Button, { variant: "outline" }, t2("btnLabelCancel")),
2278
+ (0, import_react20.createElement)(Button, { variant: "danger", icon: iconOf("close", ICON_SIZE.lg) }, t2("btnLabelDelete"))
2279
+ ),
2280
+ (0, import_react20.createElement)(
2281
+ Labeled,
2282
+ { label: "en" },
2283
+ (0, import_react20.createElement)(Button, { variant: "primary" }, "Save"),
2284
+ (0, import_react20.createElement)(Button, { variant: "outline" }, "Cancel"),
2285
+ (0, import_react20.createElement)(Button, { variant: "ghost" }, "Learn more")
2286
+ ),
2287
+ (0, import_react20.createElement)(
2288
+ Labeled,
2289
+ { label: "zh" },
2290
+ (0, import_react20.createElement)(Button, { variant: "primary" }, "\u4FDD\u5B58"),
2291
+ (0, import_react20.createElement)(Button, { variant: "outline" }, "\u53D6\u6D88"),
2292
+ (0, import_react20.createElement)(Button, { variant: "ghost" }, "\u4E86\u89E3\u66F4\u591A")
2293
+ ),
2294
+ (0, import_react20.createElement)(
2295
+ Labeled,
2296
+ { label: "zh + en" },
2297
+ (0, import_react20.createElement)(Button, { variant: "primary", icon: iconOf("sparkle", ICON_SIZE.lg) }, t2("btnLabelMixed")),
2298
+ (0, import_react20.createElement)(Button, { variant: "outline" }, "\u590D\u5236 Copy"),
2299
+ (0, import_react20.createElement)(Button, { variant: "secondary" }, "\u91CD\u8BD5 Retry")
2300
+ )
2301
+ )
2302
+ ),
2303
+ // ── 10 档外观 ──────────────────────────────────────────────────────
2058
2304
  (0, import_react20.createElement)(
2059
2305
  Demo,
2060
- { title: "Button", hint: t2("buttonHint") },
2306
+ { title: t2("btnVariantTitle"), hint: t2("btnVariantHint") },
2061
2307
  (0, import_react20.createElement)(
2062
2308
  "div",
2063
- { style: { display: "flex", gap: "8px", flexWrap: "wrap", alignItems: "center" } },
2064
- ["primary", "outline", "ghost", "danger"].map(
2065
- (v) => (0, import_react20.createElement)(Button, { key: v, variant: v, onClick: () => {
2066
- } }, v)
2309
+ { style: { display: "flex", flexDirection: "column", gap: "10px" } },
2310
+ (0, import_react20.createElement)(Row, null, VARIANTS.map((item) => (0, import_react20.createElement)(Button, { key: item.value, variant: item.value, icon: iconOf(item.icon, ICON_SIZE.lg) }, item.value))),
2311
+ (0, import_react20.createElement)(Row, null, VARIANTS.map((item) => (0, import_react20.createElement)(Button, { key: item.value, variant: item.value, size: "sm", icon: iconOf(item.icon, ICON_SIZE.sm) }, item.value)))
2312
+ )
2313
+ ),
2314
+ // ── 尺寸 / 图标位置 / block ─────────────────────────────────────────
2315
+ (0, import_react20.createElement)(
2316
+ Demo,
2317
+ { title: t2("btnSizeTitle"), hint: t2("btnSizeHint") },
2318
+ (0, import_react20.createElement)(
2319
+ "div",
2320
+ { style: { display: "flex", flexDirection: "column", gap: "12px" } },
2321
+ (0, import_react20.createElement)(
2322
+ Labeled,
2323
+ { label: "size" },
2324
+ ["sm", "md", "lg"].map((size) => (0, import_react20.createElement)(Button, { key: size, size, variant: "outline", icon: iconOf("plus", ICON_SIZE[size]) }, size))
2067
2325
  ),
2068
- (0, import_react20.createElement)(Button, { size: "sm" }, "sm"),
2069
- (0, import_react20.createElement)(Button, { size: "lg" }, "lg"),
2070
- (0, import_react20.createElement)(IconButton, { icon: "+", label: "\u65B0\u589E" })
2326
+ // icon 收的是 ReactNode:官方图标组件 / 自绘 SVG / 一个字符,三种来源各一颗
2327
+ (0, import_react20.createElement)(
2328
+ Labeled,
2329
+ { label: "icon" },
2330
+ (0, import_react20.createElement)(Button, { variant: "primary", icon: iconOf("send", ICON_SIZE.lg) }, "\u5B98\u65B9\u56FE\u6807"),
2331
+ (0, import_react20.createElement)(Button, { variant: "outline", icon: (0, import_react20.createElement)(StarSvg, null) }, "\u81EA\u7ED8 SVG"),
2332
+ (0, import_react20.createElement)(Button, { variant: "ghost", icon: "+" }, "\u4E00\u4E2A\u5B57\u7B26")
2333
+ ),
2334
+ (0, import_react20.createElement)(
2335
+ Labeled,
2336
+ { label: "iconRight" },
2337
+ (0, import_react20.createElement)(Button, { variant: "outline", iconRight: iconOf("chevron", ICON_SIZE.lg) }, "\u66F4\u591A"),
2338
+ (0, import_react20.createElement)(Button, { variant: "primary" }, "\u4E0B\u4E00\u6B65")
2339
+ ),
2340
+ // block + 前置图标:文字要在视觉中心,不能整组内容居中(那样文字会被图标推右)
2341
+ (0, import_react20.createElement)(
2342
+ Labeled,
2343
+ { label: "block" },
2344
+ (0, import_react20.createElement)(
2345
+ "div",
2346
+ { style: { width: "260px" } },
2347
+ (0, import_react20.createElement)(Button, { variant: "primary", block: true, icon: iconOf("check", ICON_SIZE.lg) }, "\u6491\u6EE1\u7236\u5BBD"),
2348
+ (0, import_react20.createElement)("div", { style: { height: "8px" } }),
2349
+ (0, import_react20.createElement)(Button, { variant: "outline", block: true }, "\u65E0\u56FE\u6807\u5BF9\u7167")
2350
+ )
2351
+ ),
2352
+ (0, import_react20.createElement)(
2353
+ Labeled,
2354
+ { label: t2("btnIconOnly") },
2355
+ BUTTON_ICONS.slice(0, 6).map((item) => (0, import_react20.createElement)(IconButton, { key: item.name, icon: (0, import_react20.createElement)(item.Icon, { size: 16 }), label: item.name }))
2356
+ )
2357
+ )
2358
+ ),
2359
+ // ── 问号提示:证明它不属于 Input 家族,随处可挂 ──────────────────────
2360
+ (0, import_react20.createElement)(
2361
+ Demo,
2362
+ { title: t2("btnHintTitle"), hint: t2("btnHintHint") },
2363
+ (0, import_react20.createElement)(
2364
+ "div",
2365
+ { style: { display: "flex", flexDirection: "column", gap: "10px" } },
2366
+ (0, import_react20.createElement)(
2367
+ Row,
2368
+ null,
2369
+ (0, import_react20.createElement)("b", { style: { fontSize: "13px" } }, "\u4E00\u4E2A\u6807\u9898"),
2370
+ (0, import_react20.createElement)(FieldHint, { text: "\u6302\u5728\u6807\u9898\u540E\u9762\uFF1A\u8BF4\u660E\u8FD9\u4E00\u5757\u662F\u5E72\u4EC0\u4E48\u7684\u3002" })
2371
+ ),
2372
+ (0, import_react20.createElement)(
2373
+ Row,
2374
+ null,
2375
+ (0, import_react20.createElement)(Button, { variant: "outline" }, "\u4E00\u4E2A\u6309\u94AE"),
2376
+ (0, import_react20.createElement)(FieldHint, { text: "\u6302\u5728\u6309\u94AE\u540E\u9762\uFF1A\u89E3\u91CA\u8FD9\u4E2A\u64CD\u4F5C\u4F1A\u53D1\u751F\u4EC0\u4E48\u3002" })
2377
+ ),
2378
+ (0, import_react20.createElement)(
2379
+ Row,
2380
+ null,
2381
+ (0, import_react20.createElement)("span", { style: { fontSize: "13px" } }, "\u4E00\u6BB5\u666E\u901A\u6587\u5B57"),
2382
+ (0, import_react20.createElement)(FieldHint, { text: "\u6302\u5728\u4EFB\u4F55\u6587\u5B57\u540E\u9762\u90FD\u884C\uFF0C\u5B83\u53EA\u662F\u4E00\u4E2A 14px \u7684\u5185\u8054\u5143\u7D20\u3002" })
2383
+ )
2384
+ )
2385
+ ),
2386
+ // ── 状态 ───────────────────────────────────────────────────────────
2387
+ (0, import_react20.createElement)(
2388
+ Demo,
2389
+ { title: t2("btnStateTitle"), hint: t2("btnStateHint") },
2390
+ (0, import_react20.createElement)(
2391
+ Row,
2392
+ null,
2393
+ (0, import_react20.createElement)(Button, { variant: "primary" }, "\u9ED8\u8BA4"),
2394
+ (0, import_react20.createElement)(Button, { variant: "primary", disabled: true }, "\u7981\u7528"),
2395
+ (0, import_react20.createElement)(Button, { variant: "danger", disabled: true, icon: iconOf("close", ICON_SIZE.lg) }, "\u7981\u7528"),
2396
+ (0, import_react20.createElement)(Button, { variant: "outline", loading: true }, "\u52A0\u8F7D\u4E2D"),
2397
+ (0, import_react20.createElement)(Button, { variant: "primary", loading: true, icon: iconOf("refresh", ICON_SIZE.lg) }, "\u63D0\u4EA4\u4E2D")
2398
+ )
2399
+ ),
2400
+ // ── 自定义颜色 ─────────────────────────────────────────────────────
2401
+ (0, import_react20.createElement)(
2402
+ Demo,
2403
+ { title: t2("btnColorTitle"), hint: t2("btnColorHint") },
2404
+ (0, import_react20.createElement)(
2405
+ "div",
2406
+ { style: { display: "flex", flexDirection: "column", gap: "10px" } },
2407
+ (0, import_react20.createElement)(Row, null, CUSTOM_COLORS.map((color) => (0, import_react20.createElement)(Button, { key: color, variant: "primary", color, icon: iconOf("sparkle", ICON_SIZE.lg) }, color))),
2408
+ (0, import_react20.createElement)(Row, null, CUSTOM_COLORS.map((color) => (0, import_react20.createElement)(Button, { key: color, variant: "outline", color }, color)))
2071
2409
  )
2072
2410
  ),
2411
+ // ── Input 家族 ─────────────────────────────────────────────────────
2073
2412
  (0, import_react20.createElement)(
2074
2413
  Demo,
2075
2414
  { title: t2("demoInputFamily"), hint: t2("inputHint") },
@@ -2089,6 +2428,7 @@ function ButtonsSection() {
2089
2428
  (0, import_react20.createElement)(Textarea, { value: text, onChange: setText, placeholder: "\u591A\u884C\u8F93\u5165" })
2090
2429
  )
2091
2430
  ),
2431
+ // ── Checkbox / Segmented ───────────────────────────────────────────
2092
2432
  (0, import_react20.createElement)(
2093
2433
  Demo,
2094
2434
  { title: "Checkbox / Segmented", hint: t2("checkboxHint") },
@@ -3025,13 +3365,15 @@ function DemoPage() {
3025
3365
  const [active, setActive] = (0, import_react31.useState)(ALL_SECTIONS[0].id);
3026
3366
  return (0, import_react31.createElement)(
3027
3367
  "div",
3028
- { style: { display: "flex", alignItems: "flex-start", height: "100%", minHeight: 0 } },
3368
+ { style: { display: "flex", alignItems: "stretch", height: "100%", minHeight: 0, overflow: "hidden" } },
3029
3369
  (0, import_react31.createElement)(
3030
3370
  "aside",
3031
3371
  {
3032
3372
  style: {
3033
3373
  width: "180px",
3034
3374
  flex: "none",
3375
+ height: "100%",
3376
+ boxSizing: "border-box",
3035
3377
  padding: "14px 10px",
3036
3378
  overflowY: "auto",
3037
3379
  borderRight: "1px solid var(--dshpc-border-faint)",
@@ -3067,7 +3409,7 @@ function DemoPage() {
3067
3409
  ),
3068
3410
  (0, import_react31.createElement)(
3069
3411
  "main",
3070
- { style: { flex: 1, minWidth: 0, overflowY: "auto", padding: "12px 22px 60px" } },
3412
+ { style: { flex: 1, minWidth: 0, minHeight: 0, height: "100%", boxSizing: "border-box", overflowY: "auto", padding: "12px 22px 60px" } },
3071
3413
  (0, import_react31.createElement)(Sections, { active, onNavigate: setActive })
3072
3414
  )
3073
3415
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-core-demo",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
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",