From 8aa002b4853510172ec17f69344690d97e5ffedc Mon Sep 17 00:00:00 2001 From: Pan <503103216@qq.com> Date: Mon, 5 Oct 2026 00:20:59 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(client):=20=E8=BD=BB=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E6=94=B9=E6=88=90=E8=B7=9F=E9=9A=8F=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=E7=9A=84=20DSH=20=E6=B5=AE=E5=B1=82=E5=8D=A1=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client.js | 14 ++++++------- src/client/ui/styles.js | 45 ++++++++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/client.js b/client.js index 6e2ca94..c0eab69 100644 --- a/client.js +++ b/client.js @@ -891,21 +891,21 @@ function seatTranslator(props, fallback) { var CSS = ` .dsn-stack{position:fixed;top:40px;right:24px;z-index:1100;display:flex;flex-direction:column;align-items:flex-end;gap:8px;pointer-events:none} @media (max-width:520px){.dsn-stack{right:12px}} -.dsn-toast{box-sizing:border-box;pointer-events:auto;display:flex;align-items:flex-start;gap:10px;width:max-content;max-width:min(420px,calc(100vw - 48px));padding:12px 12px 12px 16px;border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-toast-bg);color:var(--dsw-alias-toast-label);font-size:14px;line-height:22px;box-shadow:var(--dsw-shadow-lv3);animation:dsn-toast-in 160ms ease-out} +.dsn-toast{box-sizing:border-box;pointer-events:auto;display:flex;align-items:flex-start;gap:10px;width:max-content;max-width:min(420px,calc(100vw - 48px));padding:12px 12px 12px 16px;border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-layer-2);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);font-size:14px;line-height:22px;animation:dsn-toast-in var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-out)} @keyframes dsn-toast-in{from{opacity:0;transform:translateX(8px)}to{opacity:1;transform:translateX(0)}} @media (prefers-reduced-motion: reduce){.dsn-toast{animation:none}} .dsn-toast-icon{display:grid;place-items:center;flex:none;height:22px;color:var(--dsw-alias-state-warn-label)} .dsn-toast-icon.is-completion{color:var(--dsw-alias-state-success-primary)} -.dsn-toast-icon.is-question{color:var(--dsw-alias-brand-primary)} +.dsn-toast-icon.is-question{color:var(--dsw-alias-state-business-primary)} .dsn-toast-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px} -.dsn-toast-title{font-weight:500;font-size:14px;line-height:22px} -.dsn-toast-desc{color:var(--dsw-alias-toast-label);opacity:.8;font-size:13px;line-height:20px;overflow-wrap:break-word} +.dsn-toast-title{color:var(--dsw-alias-label-primary);font-weight:500;font-size:14px;line-height:22px} +.dsn-toast-desc{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px;overflow-wrap:break-word} .dsn-toast-actions{display:flex;align-items:center;gap:2px;flex:none} -.dsn-toast-action{display:inline-flex;align-items:center;height:28px;padding:0 8px;border:0;border-radius:var(--dsw-radius-sm);background:none;color:var(--dsw-static-deepseek-400);font:inherit;font-size:13px;line-height:20px;cursor:pointer} +.dsn-toast-action{display:inline-flex;align-items:center;height:28px;padding:0 8px;border:0;border-radius:var(--dsw-radius-sm);background:none;color:var(--dsw-alias-state-business-primary);font:inherit;font-size:13px;line-height:20px;cursor:pointer} .dsn-toast-action:hover{background:var(--dsw-alias-interactive-bg-hover)} .dsn-toast-action:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:2px} -.dsn-toast-close{flex:none;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:0;border-radius:var(--dsw-radius-sm);background:transparent;color:var(--dsw-alias-toast-label);opacity:.8;cursor:pointer} -.dsn-toast-close:hover{background:var(--dsw-alias-interactive-bg-hover);opacity:1} +.dsn-toast-close{flex:none;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:0;border-radius:var(--dsw-radius-sm);background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer} +.dsn-toast-close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)} .dsn-toast-close:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:2px} .dsn-page{display:flex;flex-direction:column;gap:28px;max-width:560px} .dsn-lede{margin:0;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px} diff --git a/src/client/ui/styles.js b/src/client/ui/styles.js index 67d9527..5e5d872 100644 --- a/src/client/ui/styles.js +++ b/src/client/ui/styles.js @@ -1,20 +1,29 @@ /** * Every style declaration this package owns. * - * The popup copies the shipped toast surface (a fixed entry in the frame-wide - * overlay, the `--dsw-alias-toast-bg` / `--dsw-alias-toast-label` pair, - * `--dsw-radius-lg`, `--dsw-shadow-lv3`) and adds a title line above the text. + * Both surfaces are built out of the theme's own vocabulary and nothing else, so + * they follow the shell's light and dark modes without a branch of their own (the + * theme swaps every `--dsw-alias-*` under `body[data-ds-dark-theme]`): * - * The settings page is a reading order, not a form dump: a lede that says how - * alerts travel, then one group per concern. Inside a group a title introduces a - * list whose rows put the subject on the left and the single control on the - * right, with hairlines only between rows; the status group is a two-column fact - * list, because four sentences stacked in one cell are not scannable. Class - * names are renamed under `dsn-`; only the popup glyphs carry their own artwork - * colors. + * - The popup is a floating card, using the same recipe the shipped menus and + * modals use — `--dsw-alias-bg-layer-2` as the surface, the + * `--dsw-elevation-stroke-color` / `--dsw-elevation-prominent` pair for its + * hairline and shadow, `--dsw-alias-label-*` for text, and the shell's motion + * tokens. It deliberately does NOT use `--dsw-alias-toast-bg`, which is a fixed + * dark slate (#353638 in light mode) and would read as a black slab on a light + * page. + * - The settings page is a reading order, not a form dump: a lede that says how + * alerts travel, then one group per concern. Inside a group a title introduces + * a list whose rows put the subject on the left and the single control on the + * right, with hairlines only between rows; the status group is a two-column + * fact list, because four sentences stacked in one cell are not scannable. + * + * Class names are renamed under `dsn-`; only the popup glyphs carry their own + * artwork colors — and those are theme-aware state tokens too. * * A plugin must not import a Harness Client package, so the declarations are - * this package's own text and reference theme tokens only. + * this package's own text. `tests/unit/styles.test.js` holds both invariants: + * tokens only, and no theme-fixed color. * * @module @dsh-plugin/session-notify/client/ui/styles */ @@ -22,21 +31,21 @@ export const CSS = ` .dsn-stack{position:fixed;top:40px;right:24px;z-index:1100;display:flex;flex-direction:column;align-items:flex-end;gap:8px;pointer-events:none} @media (max-width:520px){.dsn-stack{right:12px}} -.dsn-toast{box-sizing:border-box;pointer-events:auto;display:flex;align-items:flex-start;gap:10px;width:max-content;max-width:min(420px,calc(100vw - 48px));padding:12px 12px 12px 16px;border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-toast-bg);color:var(--dsw-alias-toast-label);font-size:14px;line-height:22px;box-shadow:var(--dsw-shadow-lv3);animation:dsn-toast-in 160ms ease-out} +.dsn-toast{box-sizing:border-box;pointer-events:auto;display:flex;align-items:flex-start;gap:10px;width:max-content;max-width:min(420px,calc(100vw - 48px));padding:12px 12px 12px 16px;border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-layer-2);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);font-size:14px;line-height:22px;animation:dsn-toast-in var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-out)} @keyframes dsn-toast-in{from{opacity:0;transform:translateX(8px)}to{opacity:1;transform:translateX(0)}} @media (prefers-reduced-motion: reduce){.dsn-toast{animation:none}} .dsn-toast-icon{display:grid;place-items:center;flex:none;height:22px;color:var(--dsw-alias-state-warn-label)} .dsn-toast-icon.is-completion{color:var(--dsw-alias-state-success-primary)} -.dsn-toast-icon.is-question{color:var(--dsw-alias-brand-primary)} +.dsn-toast-icon.is-question{color:var(--dsw-alias-state-business-primary)} .dsn-toast-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px} -.dsn-toast-title{font-weight:500;font-size:14px;line-height:22px} -.dsn-toast-desc{color:var(--dsw-alias-toast-label);opacity:.8;font-size:13px;line-height:20px;overflow-wrap:break-word} +.dsn-toast-title{color:var(--dsw-alias-label-primary);font-weight:500;font-size:14px;line-height:22px} +.dsn-toast-desc{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px;overflow-wrap:break-word} .dsn-toast-actions{display:flex;align-items:center;gap:2px;flex:none} -.dsn-toast-action{display:inline-flex;align-items:center;height:28px;padding:0 8px;border:0;border-radius:var(--dsw-radius-sm);background:none;color:var(--dsw-static-deepseek-400);font:inherit;font-size:13px;line-height:20px;cursor:pointer} +.dsn-toast-action{display:inline-flex;align-items:center;height:28px;padding:0 8px;border:0;border-radius:var(--dsw-radius-sm);background:none;color:var(--dsw-alias-state-business-primary);font:inherit;font-size:13px;line-height:20px;cursor:pointer} .dsn-toast-action:hover{background:var(--dsw-alias-interactive-bg-hover)} .dsn-toast-action:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:2px} -.dsn-toast-close{flex:none;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:0;border-radius:var(--dsw-radius-sm);background:transparent;color:var(--dsw-alias-toast-label);opacity:.8;cursor:pointer} -.dsn-toast-close:hover{background:var(--dsw-alias-interactive-bg-hover);opacity:1} +.dsn-toast-close{flex:none;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:0;border-radius:var(--dsw-radius-sm);background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer} +.dsn-toast-close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)} .dsn-toast-close:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:2px} .dsn-page{display:flex;flex-direction:column;gap:28px;max-width:560px} .dsn-lede{margin:0;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px}