Refine device last-seen text morph animation
Build and Deploy Gateway / build-and-push (push) Successful in 13s
Build and Deploy Gateway / deploy (push) Successful in 7s

This commit is contained in:
2026-08-07 13:52:41 +03:00
parent 76b75624b8
commit 36c8438b7f
4 changed files with 12 additions and 27 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
export const HARBOR_VERSIONS = Object.freeze({
macClient: '0.9.2',
gatewayClient: '0.9.2',
macClient: '0.9.3',
gatewayClient: '0.9.3',
gatewayBackend: '0.9.0',
});
-11
View File
@@ -82,17 +82,6 @@ export function DevicesPanel({ open, panelRef, closeRef, onClose }) {
inert={!open ? true : undefined}
>
<div className="client-instructions-sheet client-devices-sheet">
<svg className="client-text-morph-filter" aria-hidden="true">
<defs>
<filter id="client-text-morph-goo">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 20 -8"
/>
</filter>
</defs>
</svg>
<button
ref={closeRef}
className="client-drawer-close"
+8 -13
View File
@@ -933,16 +933,8 @@ p {
transform: translate(0, 0);
}
.client-text-morph-filter {
position: absolute;
width: 0;
height: 0;
pointer-events: none;
}
.client-text-morph {
display: inline-grid;
filter: url('#client-text-morph-goo');
}
.client-text-morph-anchor,
@@ -958,20 +950,23 @@ p {
.client-text-morph-value {
will-change: opacity, filter, transform;
transition: opacity 240ms ease, filter 280ms cubic-bezier(0.16, 1, 0.3, 1), transform 280ms cubic-bezier(0.16, 1, 0.3, 1);
filter: blur(0);
transform: translateY(0) scale(1);
transform-origin: right center;
transition: opacity 360ms ease, filter 480ms cubic-bezier(0.16, 1, 0.3, 1), transform 480ms cubic-bezier(0.16, 1, 0.3, 1);
}
.client-text-morph-value.is-relative {
opacity: 0;
filter: blur(4px);
transform: scale(0.9);
filter: blur(8px);
transform: translateY(0.18em) scale(0.96);
}
.client-device-last-seen:hover .client-text-morph-value.is-date,
.client-device-last-seen:focus-visible .client-text-morph-value.is-date {
opacity: 0;
filter: blur(4px);
transform: scale(1.08);
filter: blur(8px);
transform: translateY(-0.18em) scale(1.04);
}
.client-device-last-seen:hover .client-text-morph-value.is-relative,
+2 -1
View File
@@ -16,12 +16,13 @@ test('Gateway device inventory uses the existing accessible responsive drawer',
assert.match(panel, /api\.devices\.update\(device\.id, patch, snapshot\.revision\)/);
assert.match(panel, /<Tooltip>Изменить название<\/Tooltip>/);
assert.match(panel, /<TextMorph from=\{seen\.label\} to=\{seen\.relative\} \/>/);
assert.match(panel, /filter id="client-text-morph-goo"/);
assert.doesNotMatch(panel, /client-text-morph-goo/);
assert.match(panel, /client-device-addresses/);
assert.doesNotMatch(panel, /точная MAC|частная MAC|<dt>Источник<\/dt>/);
assert.match(panel, /aria-pressed=\{device\.pinned\}/);
assert.match(panel, /maxLength="64"[\s\S]*autoFocus/);
assert.match(styles, /\.client-devices \{\s*width: min\(560px, 100vw\)/);
assert.match(styles, /\.client-text-morph-value \{[\s\S]*transition: opacity 360ms[\s\S]*filter 480ms/);
assert.match(styles, /\.client-device-last-seen:hover \.client-text-morph-value\.is-relative[\s\S]*opacity: 1/);
assert.match(styles, /@media \(prefers-reduced-motion: reduce\)[\s\S]*\.client-text-morph-value/);
});