import classNames from "classnames"; import type { ReactNode } from "react"; import { Checkbox } from "../Checkbox"; import { CopyIconButton as BaseCopyIconButton, type CopyIconButtonProps } from "../CopyIconButton"; import { useEditorHost } from "../EditorHost"; import { Icon } from "../Icon"; import { IconButton, type IconButtonProps } from "../IconButton"; import { PlainInput } from "../PlainInput"; import type { RadioDropdownItem } from "../RadioDropdown"; import { Select } from "../Select"; /** Copies through the host, quietly, as the rows' values do */ function CopyIconButton(props: Omit) { const host = useEditorHost(); return ; } export type SettingRowBaseProps = { className?: string; controlClassName?: string; description?: ReactNode; disabled?: boolean; title: ReactNode; }; export function SettingsList({ children, className }: { children: ReactNode; className?: string }) { return
{children}
; } export function SettingsSection({ children, className, description, title, }: { children: ReactNode; className?: string; description?: ReactNode; title: ReactNode | null; }) { const showHeader = title != null || description != null; return (
{showHeader && (
{title != null &&
{title}
} {description != null &&

{description}

}
)}
{children}
); } export function SettingRow({ children, className, controlClassName, description, disabled, title, }: { children: ReactNode; } & SettingRowBaseProps) { return (
{title}
{description != null && (
{description}
)}
{children}
); } export function SettingValue({ actions, className, copyText, enableCopy = true, value, }: { actions?: SettingValueAction[]; className?: string; copyText?: string; enableCopy?: boolean; value: ReactNode; }) { const textValue = typeof value === "string" || typeof value === "number" ? `${value}` : null; const textToCopy = copyText ?? textValue; return ( <> {value} {actions?.map((action) => ( ))} {enableCopy && textToCopy != null && ( )} ); } /** * A command or config to copy, set as a block: its title, an optional line * saying which file it goes in, then the snippet at full width with the copy * button on it. One-line shell commands and multi-line JSON get the same block. */ export function SettingCommand({ className, description, disabled, done, language, snippet, title, }: { description?: ReactNode; disabled?: boolean; /** A short word shown with a check beside the title once the step is detected as done */ done?: ReactNode; language: SettingSnippetLanguage; snippet: string; title: ReactNode; } & Pick) { return (
{title} {done != null && done !== false && ( {done} )}
{description != null && (
{description}
)}
); } export type SettingSnippetLanguage = "shell" | "json" | "text"; /** The snippet half of a `SettingCommand`, for places with their own title, like a banner. */ export function SettingSnippet({ className, language, snippet, }: { className?: string; language: SettingSnippetLanguage; snippet: string; }) { const prompt = language === "shell"; return (
{prompt && ( $ )} {snippet}
); } type SettingValueAction = { icon: IconButtonProps["icon"]; onClick: () => void; title: string; }; export function SettingRowBoolean({ checked, checkboxSize = "md", onChange, title, ...props }: { checked: boolean; checkboxSize?: "sm" | "md"; onChange: (checked: boolean) => void; } & SettingRowBaseProps) { return ( ); } export function SettingRowNumber({ inputClassName, inputWidthClassName = "w-48!", name, onChange, placeholder, required, title, type = "number", validate, value, ...props }: { inputClassName?: string; inputWidthClassName?: string; name: string; onChange: (value: number) => void; placeholder?: string; required?: boolean; type?: "number"; validate?: (value: string) => boolean; value: number; } & SettingRowBaseProps) { return ( onChange(Number.parseInt(value, 10) || 0)} type={type} className={inputClassName} containerClassName={inputWidthClassName} disabled={props.disabled} /> ); } export function SettingRowText({ inputClassName, inputWidthClassName = "w-80!", name, onChange, placeholder, required, title, type = "text", value, ...props }: { inputClassName?: string; inputWidthClassName?: string; name: string; onChange: (value: string) => void; placeholder?: string; required?: boolean; type?: "text" | "password"; value: string; } & SettingRowBaseProps) { return ( ); } export function SettingRowSelect({ defaultValue, name, onChange, options, selectClassName = "w-48!", title, value, ...props }: { defaultValue?: T; name: string; onChange: (value: T) => void; options: RadioDropdownItem[]; selectClassName?: string; value: T; } & SettingRowBaseProps) { return ( ); } export function SettingSelectControl({ defaultValue, disabled, label, name, onChange, options, selectClassName = "w-48!", value, }: { defaultValue?: T; disabled?: boolean; label: string; name: string; onChange: (value: T) => void; options: RadioDropdownItem[]; selectClassName?: string; value: T; }) { return (