mirror of
https://github.com/vector-im/element-call.git
synced 2026-09-22 22:29:30 +00:00
- Draws the level as lit bars, and each failure state as its own message with a next action rather than as a meter that has stopped. - A bar and the space beside it keep one size wherever the meter is drawn; what the width decides is how many bars there are. Bars spread to fill would be a different shape in every place, and would close into one block where the space ran short. - Announces the level on a fixed scale, so it does not rest on hue or on how many bars happened to fit. - The hook is a bridge and nothing more: the capture belongs to the state layer. - The capture is held by a component of its own, so a level that does change redraws the meter rather than whatever is rendered beside it. A level arrives many times a second; held by the menu it would reconcile every device row on the way to the bars. A test counts those renders, because nothing else would notice the hook moving back. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
88 lines
3.4 KiB
CSS
88 lines
3.4 KiB
CSS
/*
|
|
Copyright 2026 Element Creations Ltd.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
.meter {
|
|
/* The icon column, the same width as a device row's, so the bars start where
|
|
the device names start. */
|
|
--meter-icon-size: 24px;
|
|
|
|
/* Compound's radio control, which the icon has to share a centre line with. */
|
|
--device-control-size: 20px;
|
|
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--cpd-space-3x);
|
|
padding-block: var(--cpd-space-2x);
|
|
/* The icon shares a centre with the radio controls in the device rows above,
|
|
which sit one 4x padding in from the menu's edge. Two things pull this row
|
|
out of line with them, and both come off the padding: the row is inset by a
|
|
border width so that the menu's frame stays visible behind it (see
|
|
`.stickyMeter`), and the icon is wider than a radio control, so it starts
|
|
half that difference further left for the two to share a centre. Both are
|
|
measured in the MeterAlignsWithTheDeviceRows story rather than trusted:
|
|
jsdom lays nothing out, so only a real browser can hold this. */
|
|
padding-inline-start: calc(
|
|
var(--cpd-space-4x) - var(--cpd-border-width-1) -
|
|
(var(--meter-icon-size) - var(--device-control-size)) / 2
|
|
);
|
|
padding-inline-end: calc(var(--cpd-space-4x) * 2 + var(--cpd-space-2x));
|
|
}
|
|
|
|
.icon {
|
|
color: var(--cpd-color-icon-secondary);
|
|
flex-shrink: 0;
|
|
inline-size: var(--meter-icon-size);
|
|
block-size: var(--meter-icon-size);
|
|
}
|
|
|
|
.segments {
|
|
/* A bar and the space beside it are always the same size; what changes with
|
|
the width available is how many bars there are. Spreading a fixed number of
|
|
bars instead would make the meter a different shape in every place it is
|
|
used, and close them up into one solid block wherever the space ran short —
|
|
and a meter whose bars touch stops reading as a count, which is what
|
|
carries the level for anyone who cannot rely on the colour.
|
|
|
|
Both sizes are set here and nowhere else: the component reads them back off
|
|
the rendered bars to work out how many fit. */
|
|
flex: 1;
|
|
/* The width decides the count, never the other way round. Containment is
|
|
what enforces that: without it the bars are both a floor under the width
|
|
and the widest thing in the menu, so the meter would set the menu's width
|
|
and the device names — which are what a person is reading — would have to
|
|
fit around it. */
|
|
contain: inline-size;
|
|
min-inline-size: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
/* Half again as wide as a bar, as the design has it: bars set as close as
|
|
their own width read as a solid block long before they touch. */
|
|
gap: var(--cpd-space-1-5x);
|
|
}
|
|
|
|
.segment {
|
|
flex: none;
|
|
inline-size: var(--cpd-space-1x);
|
|
block-size: var(--cpd-space-4x);
|
|
border-radius: var(--cpd-space-1x);
|
|
background: var(--cpd-color-bg-subtle-primary);
|
|
}
|
|
|
|
/* Filled segments carry the level by count as well as by colour, so the meter
|
|
stays readable without relying on hue. */
|
|
.segmentLit {
|
|
background: var(--cpd-color-bg-accent-rest);
|
|
}
|
|
|
|
.message {
|
|
color: var(--cpd-color-text-secondary);
|
|
/* A paragraph brings a margin below it, which in a centred row does not push
|
|
the text down but lifts it: the margin box is what gets centred, so the
|
|
words end up above the middle and the icon beside them looks low. */
|
|
margin-block: 0;
|
|
}
|