mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 14:20:35 +08:00
feat(notice): add click-to-toggle between compact and detailed display modes
Click anywhere on the notice content area to toggle between compact and detailed (normal) display modes. A subtle hint label '▸ 简洁' / '▸ 详细' appears on hover. CSS transitions animate the layout switch: - Content area: max-width + opacity crossfade (280ms cubic-bezier) - Message text: max-height expand/collapse + opacity fade (280ms) - Actions: max-height + margin collapse + opacity fade (260ms) - Container: grid-template-columns + padding + border-radius morph (260ms) The switch uses a two-phase animation: content fades out (180ms), layout changes via CSS transition, then content fades back in (60ms delay). This prevents jarring content jumps during the layout shift.
This commit is contained in:
172
ui/notice.js
172
ui/notice.js
@@ -58,6 +58,11 @@ function ensureStyle(doc) {
|
||||
font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei UI", sans-serif;
|
||||
backdrop-filter: blur(10px) saturate(125%);
|
||||
-webkit-backdrop-filter: blur(10px) saturate(125%);
|
||||
transition:
|
||||
grid-template-columns 260ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
padding 260ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
border-radius 260ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
width 260ms cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="compact"] {
|
||||
@@ -70,6 +75,40 @@ function ensureStyle(doc) {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.st-bme-notice__content {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
transition: max-width 280ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
opacity 220ms ease;
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="compact"] .st-bme-notice__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.st-bme-notice__message {
|
||||
margin: 4px 0 0;
|
||||
font-size: 14px;
|
||||
line-height: 1.38;
|
||||
color: rgba(240, 246, 255, 0.86);
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
transition: max-height 280ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
opacity 220ms ease,
|
||||
margin 260ms ease;
|
||||
}
|
||||
|
||||
.st-bme-notice__actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 10px;
|
||||
transition: max-height 260ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
opacity 220ms ease,
|
||||
margin 260ms ease;
|
||||
}
|
||||
|
||||
.st-bme-notice::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@@ -104,16 +143,6 @@ function ensureStyle(doc) {
|
||||
animation: stBmeNoticeBusy 900ms linear infinite;
|
||||
}
|
||||
|
||||
.st-bme-notice__content {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="compact"] .st-bme-notice__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.st-bme-notice__title {
|
||||
margin: 0;
|
||||
font-size: 17px;
|
||||
@@ -151,21 +180,6 @@ function ensureStyle(doc) {
|
||||
-webkit-mask-image: linear-gradient(90deg, transparent 0%, black 6%, black 88%, transparent 100%);
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="compact"] .st-bme-notice__message,
|
||||
.st-bme-notice[data-layout="compact"] .st-bme-notice__progress {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="compact"] .st-bme-notice__actions {
|
||||
margin: 0 0 0 8px;
|
||||
}
|
||||
|
||||
.st-bme-notice__actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.st-bme-notice__action {
|
||||
min-height: 30px;
|
||||
padding: 0 12px;
|
||||
@@ -213,6 +227,64 @@ function ensureStyle(doc) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.st-bme-notice__toggle-hint {
|
||||
position: absolute;
|
||||
bottom: 6px;
|
||||
right: 32px;
|
||||
font-size: 10px;
|
||||
color: rgba(240, 246, 255, 0.35);
|
||||
pointer-events: none;
|
||||
transition: opacity 180ms ease;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.st-bme-notice:hover .st-bme-notice__toggle-hint {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="normal"] .st-bme-notice__toggle-hint::after {
|
||||
content: "▸ 简洁";
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="compact"] .st-bme-notice__toggle-hint::after {
|
||||
content: "▸ 详细";
|
||||
}
|
||||
|
||||
.st-bme-notice--switching {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.st-bme-notice--switching .st-bme-notice__content {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="normal"] .st-bme-notice__content {
|
||||
max-width: 360px;
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="compact"] .st-bme-notice__actions {
|
||||
max-height: 0;
|
||||
opacity: 0;
|
||||
margin-top: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="normal"] .st-bme-notice__actions {
|
||||
max-height: 60px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="normal"] .st-bme-notice__message {
|
||||
max-height: 200px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.st-bme-notice[data-layout="compact"] .st-bme-notice__message {
|
||||
max-height: 0;
|
||||
opacity: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.st-bme-notice__progress {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@@ -334,7 +406,7 @@ function applyNoticeState(item, input, progress) {
|
||||
const message = item.querySelector(".st-bme-notice__message");
|
||||
if (message) {
|
||||
message.textContent = input.message || "";
|
||||
message.hidden = isCompact || !String(input.message || "").trim();
|
||||
message.hidden = !String(input.message || "").trim();
|
||||
if (input.marquee) {
|
||||
message.classList.add("st-bme-notice__message--marquee");
|
||||
} else {
|
||||
@@ -346,12 +418,10 @@ function applyNoticeState(item, input, progress) {
|
||||
const actionButton = item.querySelector(".st-bme-notice__action");
|
||||
if (actionWrap && actionButton) {
|
||||
if (input.action?.label) {
|
||||
actionWrap.style.display = "";
|
||||
actionButton.style.display = "";
|
||||
actionButton.textContent = input.action.label;
|
||||
actionButton.dataset.kind = input.action.kind || "neutral";
|
||||
} else {
|
||||
actionWrap.style.display = "none";
|
||||
actionButton.style.display = "none";
|
||||
actionButton.textContent = "";
|
||||
actionButton.dataset.kind = "neutral";
|
||||
@@ -405,6 +475,9 @@ export function showManagedBmeNotice(input) {
|
||||
const progress = doc.createElement("div");
|
||||
progress.className = "st-bme-notice__progress";
|
||||
|
||||
const toggleHint = doc.createElement("span");
|
||||
toggleHint.className = "st-bme-notice__toggle-hint";
|
||||
|
||||
content.appendChild(title);
|
||||
content.appendChild(message);
|
||||
actions.appendChild(actionButton);
|
||||
@@ -412,11 +485,13 @@ export function showManagedBmeNotice(input) {
|
||||
item.appendChild(icon);
|
||||
item.appendChild(content);
|
||||
item.appendChild(closeButton);
|
||||
item.appendChild(toggleHint);
|
||||
item.appendChild(progress);
|
||||
|
||||
let currentInput = input || {};
|
||||
let closed = false;
|
||||
let closeTimer = null;
|
||||
let switching = false;
|
||||
|
||||
const clearCloseTimer = () => {
|
||||
if (!closeTimer) return;
|
||||
@@ -465,6 +540,47 @@ export function showManagedBmeNotice(input) {
|
||||
close();
|
||||
});
|
||||
|
||||
content.addEventListener("click", (event) => {
|
||||
if (closed || switching) return;
|
||||
if (event.target === actionButton || event.target === closeButton) return;
|
||||
if (actionButton.contains(event.target) || closeButton.contains(event.target)) return;
|
||||
|
||||
switching = true;
|
||||
item.classList.add("st-bme-notice--switching");
|
||||
|
||||
const currentLayout = item.dataset.layout || "normal";
|
||||
const nextLayout = currentLayout === "compact" ? "normal" : "compact";
|
||||
|
||||
setTimeout(() => {
|
||||
item.dataset.layout = nextLayout;
|
||||
currentInput.displayMode = nextLayout;
|
||||
|
||||
if (nextLayout === "normal") {
|
||||
const msgEl = item.querySelector(".st-bme-notice__message");
|
||||
if (msgEl) msgEl.hidden = !String(currentInput.message || "").trim();
|
||||
}
|
||||
|
||||
if (nextLayout === "normal" && !currentInput.persist) {
|
||||
clearCloseTimer();
|
||||
const duration = Math.max(1400, currentInput.duration_ms || 3200);
|
||||
closeTimer = setTimeout(close, duration);
|
||||
const progressEl = item.querySelector(".st-bme-notice__progress");
|
||||
if (progressEl) {
|
||||
progressEl.style.display = "";
|
||||
progressEl.style.animationDuration = `${duration}ms`;
|
||||
progressEl.style.animation = "none";
|
||||
void progressEl.offsetHeight;
|
||||
progressEl.style.animation = "";
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
item.classList.remove("st-bme-notice--switching");
|
||||
switching = false;
|
||||
}, 60);
|
||||
}, 180);
|
||||
});
|
||||
|
||||
host.appendChild(item);
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user