milestone 23 s3: convert features/groups/GroupSourcesEditor.tsx to stylex

This commit is contained in:
2026-08-12 22:28:01 +02:00
parent 368149a358
commit 38d34453bb
+45 -14
View File
@@ -1,10 +1,12 @@
import { useState } from "react"; import { useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import * as stylex from "@stylexjs/stylex";
import { groupSourcesPutMutation, groupSourcesQuery } from "@/lib/queries"; import { groupSourcesPutMutation, groupSourcesQuery } from "@/lib/queries";
import type { Blocklist } from "@/lib/types"; import type { Blocklist } from "@/lib/types";
import { sameSet, toggleSource } from "./sourceSet"; import { sameSet, toggleSource } from "./sourceSet";
import InlineError from "@/lib/InlineError"; import InlineError from "@/lib/InlineError";
import { buttonClass, focusRing, primaryButtonClass } from "@/ui/classes"; import { styles as shared } from "@/ui/styles";
import { colors } from "@/ui/tokens.stylex";
import { READ_ONLY_HINT, useReadOnlyConfig } from "@/features/settings/authority"; import { READ_ONLY_HINT, useReadOnlyConfig } from "@/features/settings/authority";
interface Props { interface Props {
@@ -12,6 +14,35 @@ interface Props {
blocklists: Blocklist[]; blocklists: Blocklist[];
} }
const styles = stylex.create({
note: {
marginTop: "0.75rem",
fontSize: "0.875rem",
lineHeight: "1.25rem",
color: colors.textMuted,
},
root: {
marginTop: "0.75rem",
},
list: {
display: "flex",
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",
gap: "0.5rem",
},
});
export default function GroupSourcesEditor({ groupId, blocklists }: Props) { export default function GroupSourcesEditor({ groupId, blocklists }: Props) {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const sources = useQuery(groupSourcesQuery(groupId)); const sources = useQuery(groupSourcesQuery(groupId));
@@ -21,7 +52,7 @@ export default function GroupSourcesEditor({ groupId, blocklists }: Props) {
if (sources.isPending) { if (sources.isPending) {
return ( return (
<p role="status" className="mt-3 text-sm text-zinc-500"> <p role="status" {...stylex.props(styles.note)}>
Loading sources Loading sources
</p> </p>
); );
@@ -29,27 +60,23 @@ export default function GroupSourcesEditor({ groupId, blocklists }: Props) {
if (sources.isError) return <InlineError error={sources.error} />; if (sources.isError) return <InlineError error={sources.error} />;
if (blocklists.length === 0) { if (blocklists.length === 0) {
return ( return <p {...stylex.props(styles.note)}>No blocklist sources exist yet add them on the Blocklists page.</p>;
<p className="mt-3 text-sm text-zinc-500">
No blocklist sources exist yet add them on the Blocklists page.
</p>
);
} }
const current = selected ?? sources.data; const current = selected ?? sources.data;
const dirty = !sameSet(current, sources.data); const dirty = !sameSet(current, sources.data);
return ( return (
<div className="mt-3"> <div {...stylex.props(styles.root)}>
<ul className="space-y-1"> <ul {...stylex.props(styles.list)}>
{blocklists.map((blocklist) => ( {blocklists.map((blocklist) => (
<li key={blocklist.id}> <li key={blocklist.id}>
<label className="inline-flex items-center gap-2 text-sm"> <label {...stylex.props(styles.checkboxLabel)}>
<input <input
type="checkbox" type="checkbox"
checked={current.includes(blocklist.id)} checked={current.includes(blocklist.id)}
onChange={() => setSelected(toggleSource(current, blocklist.id))} onChange={() => setSelected(toggleSource(current, blocklist.id))}
className={focusRing} {...stylex.props(shared.focusRing)}
/> />
{blocklist.name} {blocklist.name}
</label> </label>
@@ -57,7 +84,7 @@ export default function GroupSourcesEditor({ groupId, blocklists }: Props) {
))} ))}
</ul> </ul>
<InlineError error={mutation.error} /> <InlineError error={mutation.error} />
<div className="mt-3 flex gap-2"> <div {...stylex.props(styles.buttonRow)}>
<button <button
type="button" type="button"
disabled={!dirty || mutation.isPending || readOnly} disabled={!dirty || mutation.isPending || readOnly}
@@ -65,12 +92,16 @@ export default function GroupSourcesEditor({ groupId, blocklists }: Props) {
onClick={() => onClick={() =>
mutation.mutate({ id: groupId, sourceIds: current }, { onSuccess: () => setSelected(null) }) mutation.mutate({ id: groupId, sourceIds: current }, { onSuccess: () => setSelected(null) })
} }
className={primaryButtonClass} {...stylex.props(shared.primaryButton, shared.focusRing)}
> >
Save sources Save sources
</button> </button>
{dirty && ( {dirty && (
<button type="button" onClick={() => setSelected(null)} className={buttonClass}> <button
type="button"
onClick={() => setSelected(null)}
{...stylex.props(shared.button, shared.focusRing)}
>
Discard Discard
</button> </button>
)} )}