milestone 23 s3: convert features/groups/GroupSourcesEditor.tsx to stylex
This commit is contained in:
@@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user