Files
multica/packages/views/common/segmented-toggle.tsx
YYClaw 465546b83b feat(autopilots): redesign the autopilot schedule editor (#5457)
Replace the free-form trigger-config form with a structured schedule
editor built on an orthogonal cron model: separate frequency, time, and
day-of-week/day-of-month dimensions map to and from cron expressions via
a dedicated grammar and mapping layer, with validation and a
human-readable describe() summary. The grammar suite drives the editor
against a combinatorially generated corpus of 51,755 distinct cron
expressions - every token form of every field, crossed - each judged
against a reference robfig/cron v3 parser.

Add a server-side /autopilot/cron-preview endpoint (plus schema and
React Query hook) so the editor shows upcoming run times, and echo
wildcard-carrying cron lists correctly instead of collapsing them.

Supporting pieces: timezone-aware formatting helper, segmented-toggle
and debounced-value utilities, a reworked time-input, and refreshed
en/ja/ko/zh-Hans locale strings.
2026-07-17 16:44:31 +08:00

46 lines
1.3 KiB
TypeScript

"use client";
import type { ReactNode } from "react";
import { cn } from "@multica/ui/lib/utils";
/** A pill-button group for picking between mutually exclusive modes: the active
* option lifts to the background, the rest stay muted. One control for every
* either/or, so switching mode always looks and works the same wherever it
* appears. */
export function SegmentedToggle<T extends string>({
value,
options,
onChange,
buttonClassName,
}: {
value: T;
options: ReadonlyArray<readonly [T, ReactNode]>;
onChange: (value: T) => void;
/** Overrides the compact default sizing (text-xs px-2 py-1). */
buttonClassName?: string;
}) {
return (
<div className="grid auto-cols-fr grid-flow-col gap-1 rounded-md bg-muted p-1">
{options.map(([key, label]) => (
<button
key={key}
type="button"
aria-pressed={value === key}
onClick={() => {
if (key !== value) onChange(key);
}}
className={cn(
"rounded-sm font-medium transition-colors",
buttonClassName ?? "px-2 py-1 text-xs",
value === key
? "bg-background text-foreground shadow-sm"
: "text-muted-foreground hover:text-foreground",
)}
>
{label}
</button>
))}
</div>
);
}