admin: group sources and safe search become rac checkboxes
the assigned sources list is a rac checkboxgroup and safe search uses the same drawn checkbox, extracted to a shared ui component with grouped and standalone modes enforced by a discriminated union. the label carries a 44px pointer-target floor on both axes, the focus ring is driven from rac's focus-visible state and guarded by a test, and toggleSource is gone because the group hands back the whole set.
This commit is contained in:
@@ -3,7 +3,8 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import * as stylex from "@stylexjs/stylex";
|
||||
import { groupSourcesPutMutation, groupSourcesQuery } from "@/lib/queries";
|
||||
import type { Blocklist } from "@/lib/types";
|
||||
import { sameSet, toggleSource } from "./sourceSet";
|
||||
import { sameSet } from "./sourceSet";
|
||||
import Checkbox, { CheckboxGroup } from "@/ui/Checkbox";
|
||||
import InlineError from "@/lib/InlineError";
|
||||
import { styles as shared } from "@/ui/styles";
|
||||
import { colors } from "@/ui/tokens.stylex";
|
||||
@@ -28,13 +29,6 @@ const styles = stylex.create({
|
||||
flexDirection: "column",
|
||||
gap: "0.25rem",
|
||||
},
|
||||
checkboxLabel: {
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
gap: "0.5rem",
|
||||
fontSize: "0.875rem",
|
||||
lineHeight: "1.25rem",
|
||||
},
|
||||
buttonRow: {
|
||||
marginTop: "0.75rem",
|
||||
display: "flex",
|
||||
@@ -66,21 +60,22 @@ export default function GroupSourcesEditor({ groupId, blocklists }: Props) {
|
||||
|
||||
return (
|
||||
<div {...stylex.props(styles.root)}>
|
||||
<ul {...stylex.props(styles.list)}>
|
||||
{blocklists.map((blocklist) => (
|
||||
<li key={blocklist.id}>
|
||||
<label {...stylex.props(styles.checkboxLabel)}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={current.includes(blocklist.id)}
|
||||
onChange={() => setSelected(toggleSource(current, blocklist.id))}
|
||||
{...stylex.props(shared.focusRing)}
|
||||
/>
|
||||
{blocklist.name}
|
||||
</label>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{/* The section's own "Assigned sources" heading is the visible label; a
|
||||
Label here would put the same words on screen twice. Ids cross the
|
||||
React Aria boundary as strings, the same convention as Select. */}
|
||||
<CheckboxGroup
|
||||
aria-label="Assigned sources"
|
||||
value={current.map(String)}
|
||||
onChange={(values) => setSelected(values.map(Number).sort((a, b) => a - b))}
|
||||
>
|
||||
<ul {...stylex.props(styles.list)}>
|
||||
{blocklists.map((blocklist) => (
|
||||
<li key={blocklist.id}>
|
||||
<Checkbox value={String(blocklist.id)}>{blocklist.name}</Checkbox>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CheckboxGroup>
|
||||
<InlineError error={mutation.error} />
|
||||
<div {...stylex.props(styles.buttonRow)}>
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user