/** * The dshloader BASE CONTROLS. * * A small, deliberately unopinionated control set so every plugin in this family * renders the same design language instead of each hand-rolling inline styles * (dsh-network-settings alone carries ~40 inline style objects today, and * dsh-auxiliary / dsh-code-review each maintain their own button and input * looks). * * Design rules: * - Styling is ONE injected stylesheet with `dshl-` prefixed classes, tagged * with the DSH `data-plugin` / `data-plugin-css` ownership attributes so HMR * can reclaim it. No CSS Modules, so consumers need no build-time CSS setup. * - Every colour is a DSH token with a fallback (see `./style.js`), so controls * follow the shell's theme, including dark mode, with no JS theme plumbing. * - Icons come from the curated set and inherit `currentColor`. * - Every control forwards native props and `className`, so a plugin can always * escape the defaults without forking the component. * * @module @dsh-plugin/dsh-loader/ui/components */ import * as React from 'react'; import { type IconName } from './icons.js'; /** Inject the control stylesheet once (idempotent, safe to call from any component). */ export declare function ensureStyles(): void; /** Visual weight of a {@link Button}. */ export type ButtonVariant = 'default' | 'primary' | 'ghost' | 'danger'; /** {@link Button} props. */ export interface ButtonProps extends React.ButtonHTMLAttributes { variant?: ButtonVariant; /** Compact height. */ small?: boolean; /** Leading icon from the curated set. */ icon?: IconName; /** Replace the label with a spinner and disable interaction. */ loading?: boolean; } /** A button in the DSH design language. */ export declare const Button: React.ForwardRefExoticComponent>; /** {@link IconButton} props. */ export interface IconButtonProps extends React.ButtonHTMLAttributes { /** Icon from the curated set. */ icon: IconName; /** Accessible name — required, since the button has no visible text. */ label: string; } /** A square icon-only button. `label` becomes its accessible name. */ export declare const IconButton: React.ForwardRefExoticComponent>; /** {@link TextInput} props. */ export interface TextInputProps extends React.InputHTMLAttributes { /** Render with the monospace stack (paths, commands, tokens). */ mono?: boolean; /** Mark the field as failing validation. */ invalid?: boolean; } /** A single-line text input. */ export declare const TextInput: React.ForwardRefExoticComponent>; /** {@link Textarea} props. */ export interface TextareaProps extends React.TextareaHTMLAttributes { mono?: boolean; invalid?: boolean; } /** A multi-line text area. */ export declare const Textarea: React.ForwardRefExoticComponent>; /** One option of a {@link Select}. */ export interface SelectOption { value: string; label: string; disabled?: boolean; } /** {@link Select} props. */ export interface SelectProps extends Omit, 'children'> { options: readonly SelectOption[]; /** Optional leading placeholder rendered as a disabled empty option. */ placeholder?: string; } /** * A dropdown built on the native `` * popup is OS-styled and cannot follow the shell theme, which is exactly the * visual drift this component removes. `Select` remains for dense/inline forms * where the native control's compactness matters. */ export declare function MenuSelect({ options, value, placeholder, disabled, onChange, id, label, className, }: MenuSelectProps): React.ReactElement; /** {@link Checkbox} props. */ export interface CheckboxProps extends Omit, 'type'> { /** Text beside the box. */ label?: React.ReactNode; } /** A checkbox with an optional label. Native input styled via `accent-color`, * matching the shell's own settings pages. */ export declare const Checkbox: React.ForwardRefExoticComponent>; /** {@link Switch} props. */ export interface SwitchProps extends Omit, 'type'> { label?: React.ReactNode; } /** A toggle switch — use for "applies immediately" settings. */ export declare const Switch: React.ForwardRefExoticComponent>; /** {@link Field} props. */ export interface FieldProps { label?: React.ReactNode; /** Supporting description under the control. */ description?: React.ReactNode; /** Validation message; renders in the danger colour. */ error?: React.ReactNode; /** Associates the label with the control. */ htmlFor?: string; children?: React.ReactNode; className?: string; } /** Label + control + description/error, the standard settings row. */ export declare function Field({ label, description, error, htmlFor, children, className }: FieldProps): React.ReactElement; /** {@link Card} props. */ export interface CardProps { title?: React.ReactNode; children?: React.ReactNode; className?: string; } /** A bordered section container — the settings-page card look. */ export declare function Card({ title, children, className }: CardProps): React.ReactElement; /** A horizontal flex row with the standard gap. */ export declare function Row({ children, className }: { children?: React.ReactNode; className?: string; }): React.ReactElement; /** A vertical flex column with the standard gap. */ export declare function Col({ children, className }: { children?: React.ReactNode; className?: string; }): React.ReactElement; /** An inline spinner. */ export declare function Spinner({ size }: { size?: number; }): React.ReactElement;