Refine device last-seen text morph animation
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
export const HARBOR_VERSIONS = Object.freeze({
|
export const HARBOR_VERSIONS = Object.freeze({
|
||||||
macClient: '0.9.2',
|
macClient: '0.9.3',
|
||||||
gatewayClient: '0.9.2',
|
gatewayClient: '0.9.3',
|
||||||
gatewayBackend: '0.9.0',
|
gatewayBackend: '0.9.0',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -82,17 +82,6 @@ export function DevicesPanel({ open, panelRef, closeRef, onClose }) {
|
|||||||
inert={!open ? true : undefined}
|
inert={!open ? true : undefined}
|
||||||
>
|
>
|
||||||
<div className="client-instructions-sheet client-devices-sheet">
|
<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
|
<button
|
||||||
ref={closeRef}
|
ref={closeRef}
|
||||||
className="client-drawer-close"
|
className="client-drawer-close"
|
||||||
|
|||||||
+8
-13
@@ -933,16 +933,8 @@ p {
|
|||||||
transform: translate(0, 0);
|
transform: translate(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.client-text-morph-filter {
|
|
||||||
position: absolute;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.client-text-morph {
|
.client-text-morph {
|
||||||
display: inline-grid;
|
display: inline-grid;
|
||||||
filter: url('#client-text-morph-goo');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.client-text-morph-anchor,
|
.client-text-morph-anchor,
|
||||||
@@ -958,20 +950,23 @@ p {
|
|||||||
|
|
||||||
.client-text-morph-value {
|
.client-text-morph-value {
|
||||||
will-change: opacity, filter, transform;
|
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 {
|
.client-text-morph-value.is-relative {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
filter: blur(4px);
|
filter: blur(8px);
|
||||||
transform: scale(0.9);
|
transform: translateY(0.18em) scale(0.96);
|
||||||
}
|
}
|
||||||
|
|
||||||
.client-device-last-seen:hover .client-text-morph-value.is-date,
|
.client-device-last-seen:hover .client-text-morph-value.is-date,
|
||||||
.client-device-last-seen:focus-visible .client-text-morph-value.is-date {
|
.client-device-last-seen:focus-visible .client-text-morph-value.is-date {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
filter: blur(4px);
|
filter: blur(8px);
|
||||||
transform: scale(1.08);
|
transform: translateY(-0.18em) scale(1.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
.client-device-last-seen:hover .client-text-morph-value.is-relative,
|
.client-device-last-seen:hover .client-text-morph-value.is-relative,
|
||||||
|
|||||||
@@ -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, /api\.devices\.update\(device\.id, patch, snapshot\.revision\)/);
|
||||||
assert.match(panel, /<Tooltip>Изменить название<\/Tooltip>/);
|
assert.match(panel, /<Tooltip>Изменить название<\/Tooltip>/);
|
||||||
assert.match(panel, /<TextMorph from=\{seen\.label\} to=\{seen\.relative\} \/>/);
|
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.match(panel, /client-device-addresses/);
|
||||||
assert.doesNotMatch(panel, /точная MAC|частная MAC|<dt>Источник<\/dt>/);
|
assert.doesNotMatch(panel, /точная MAC|частная MAC|<dt>Источник<\/dt>/);
|
||||||
assert.match(panel, /aria-pressed=\{device\.pinned\}/);
|
assert.match(panel, /aria-pressed=\{device\.pinned\}/);
|
||||||
assert.match(panel, /maxLength="64"[\s\S]*autoFocus/);
|
assert.match(panel, /maxLength="64"[\s\S]*autoFocus/);
|
||||||
assert.match(styles, /\.client-devices \{\s*width: min\(560px, 100vw\)/);
|
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, /\.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/);
|
assert.match(styles, /@media \(prefers-reduced-motion: reduce\)[\s\S]*\.client-text-morph-value/);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user