Skip to content

Commit 809aead

Browse files
committed
feat(motion): label the ends of the sensitivity scale
1 parent 3cc2ca1 commit 809aead

3 files changed

Lines changed: 64 additions & 29 deletions

File tree

‎frontend/src/components/Motion.tsx‎

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
DARK_THRESHOLD_MAX,
1313
DARK_THRESHOLD_MIN,
1414
formatLux,
15+
sensitivityEnds,
1516
sensitivityLabel,
1617
} from "../hue/motion";
1718
import { mq } from "../mq";
@@ -361,36 +362,52 @@ type LevelsProps = {
361362

362363
const Levels: FC<LevelsProps> = ({ value, max, onChange }) => {
363364
const theme = useTheme();
365+
const [low, high] = sensitivityEnds(max);
364366
return (
365-
<div role="radiogroup" aria-label="herkkyys" css={{ display: "flex", gap: 4 }}>
366-
{Array.from({ length: max + 1 }, (_, level) => {
367-
const selected = level === value;
368-
return (
369-
<button
370-
key={level}
371-
type="button"
372-
role="radio"
373-
aria-checked={selected}
374-
aria-label={sensitivityLabel(level, max)}
375-
onClick={() => {
376-
if (!selected) onChange(level);
377-
}}
378-
css={{
379-
width: 40,
380-
height: 36,
381-
border: `1px solid ${selected ? theme.colors.activity.on : theme.colors.border}`,
382-
borderRadius: theme.border.radiusPill,
383-
backgroundColor: selected ? theme.colors.activity.onSoft : "transparent",
384-
color: selected ? theme.colors.activity.on : theme.colors.text.main,
385-
font: "inherit",
386-
fontVariantNumeric: "tabular-nums",
387-
cursor: "pointer",
388-
}}
389-
>
390-
{level + 1}
391-
</button>
392-
);
393-
})}
367+
<div css={{ display: "flex", flexDirection: "column", gap: 2 }}>
368+
<div role="radiogroup" aria-label="herkkyys" css={{ display: "flex", gap: 4 }}>
369+
{Array.from({ length: max + 1 }, (_, level) => {
370+
const selected = level === value;
371+
return (
372+
<button
373+
key={level}
374+
type="button"
375+
role="radio"
376+
aria-checked={selected}
377+
aria-label={sensitivityLabel(level, max)}
378+
onClick={() => {
379+
if (!selected) onChange(level);
380+
}}
381+
css={{
382+
width: 40,
383+
height: 36,
384+
border: `1px solid ${selected ? theme.colors.activity.on : theme.colors.border}`,
385+
borderRadius: theme.border.radiusPill,
386+
backgroundColor: selected ? theme.colors.activity.onSoft : "transparent",
387+
color: selected ? theme.colors.activity.on : theme.colors.text.main,
388+
font: "inherit",
389+
fontVariantNumeric: "tabular-nums",
390+
cursor: "pointer",
391+
}}
392+
>
393+
{level + 1}
394+
</button>
395+
);
396+
})}
397+
</div>
398+
<div
399+
aria-hidden
400+
css={{
401+
display: "flex",
402+
justifyContent: "space-between",
403+
gap: 8,
404+
...theme.typography.caption,
405+
color: theme.colors.text.muted,
406+
}}
407+
>
408+
<span>{`← ${low}`}</span>
409+
<span>{`${high} →`}</span>
410+
</div>
394411
</div>
395412
);
396413
};

‎frontend/src/hue/motion.test.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
formatLux,
55
levelToLux,
66
luxToLevel,
7+
sensitivityEnds,
78
sensitivityLabel,
89
} from "./motion";
910

@@ -33,3 +34,14 @@ describe("sensitivityLabel", () => {
3334
expect(sensitivityLabel(1, 3)).toBe("2/4");
3435
});
3536
});
37+
38+
describe("sensitivityEnds", () => {
39+
test("names both ends of each scale", () => {
40+
expect(sensitivityEnds(2)).toEqual(["matala", "korkea"]);
41+
expect(sensitivityEnds(4)).toEqual(["hyvin matala", "hyvin korkea"]);
42+
});
43+
44+
test("still shows the direction on an unknown scale", () => {
45+
expect(sensitivityEnds(3)).toEqual(["matala", "korkea"]);
46+
});
47+
});

‎frontend/src/hue/motion.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ const SENSITIVITY_WORDS: Record<number, string[]> = {
2121

2222
export const sensitivityLabel = (value: number, max: number) =>
2323
SENSITIVITY_WORDS[max]?.[value] ?? `${value + 1}/${max + 1}`;
24+
25+
/** The scale's two ends, so the direction shows before a level is picked. */
26+
export const sensitivityEnds = (max: number): [string, string] => {
27+
const words = SENSITIVITY_WORDS[max];
28+
return words ? [words[0], words[words.length - 1]] : ["matala", "korkea"];
29+
};

0 commit comments

Comments
 (0)