export interface ComponentProps { /** * Additional CSS classes to apply */ class?: string } export interface ComponentEmits { // Base component events can be added here } export interface SubheaderProps extends ComponentProps { /** * The heading text to display */ text: string } export interface ButtonProps extends ComponentProps { /** * Button variant */ variant?: 'default' | 'outline' /** * Button size */ size?: 'sm' | 'md' | 'lg' /** * Whether the button is disabled */ disabled?: boolean /** * Button type attribute */ type?: 'button' | 'submit' | 'reset' } export interface ButtonEmits extends ComponentEmits { /** * Emitted when button is clicked */ click: [event: MouseEvent] } export interface InputProps extends ComponentProps { /** * The input's current value (v-model) */ modelValue?: string | number /** * Input type attribute */ type?: 'text' | 'email' | 'password' | 'tel' | 'url' | 'search' | 'number' /** * Input name attribute */ name?: string /** * Label text for floating label */ label?: string /** * Placeholder text (shown when no floating label or as fallback) */ placeholder?: string /** * Whether the input is disabled */ disabled?: boolean /** * Whether the input is readonly */ readonly?: boolean /** * Whether the input is required */ required?: boolean /** * Whether the input has an error state */ error?: boolean /** * Error message to display */ errorMessage?: string /** * Input size variant */ size?: 'sm' | 'md' | 'lg' /** * Input visual variant */ variant?: 'default' | 'outlined' } export interface InputEmits extends ComponentEmits { /** * Emitted when the input value changes (v-model) */ 'update:modelValue': [value: string | number] /** * Emitted on input event */ input: [event: Event] /** * Emitted on change event */ change: [event: Event] /** * Emitted when input gains focus */ focus: [event: FocusEvent] /** * Emitted when input loses focus */ blur: [event: FocusEvent] } export interface DatePickerProps extends ComponentProps { /** * The date picker's current value (v-model) */ modelValue?: string /** * Input name attribute */ name?: string /** * Label text for floating label */ label?: string /** * Placeholder text (shown when no floating label or as fallback) */ placeholder?: string /** * Whether the input is disabled */ disabled?: boolean /** * Whether the input is readonly */ readonly?: boolean /** * Whether the input is required */ required?: boolean /** * Whether the input has an error state */ error?: boolean /** * Error message to display */ errorMessage?: string /** * Input size variant */ size?: 'sm' | 'md' | 'lg' /** * Input visual variant */ variant?: 'default' | 'outlined' /** * Minimum date (ISO string format) */ min?: string /** * Maximum date (ISO string format) */ max?: string } export interface DatePickerEmits extends ComponentEmits { /** * Emitted when the date value changes (v-model) */ 'update:modelValue': [value: string] /** * Emitted on input event */ input: [event: Event] /** * Emitted on change event */ change: [event: Event] /** * Emitted when input gains focus */ focus: [event: FocusEvent] /** * Emitted when input loses focus */ blur: [event: FocusEvent] } export interface TextareaProps extends ComponentProps { /** * The textarea's current value (v-model) */ modelValue?: string /** * Textarea name attribute */ name?: string /** * Label text for floating label */ label?: string /** * Placeholder text (shown when no floating label or as fallback) */ placeholder?: string /** * Whether the textarea is disabled */ disabled?: boolean /** * Whether the textarea is readonly */ readonly?: boolean /** * Whether the textarea is required */ required?: boolean /** * Whether the textarea has an error state */ error?: boolean /** * Error message to display */ errorMessage?: string /** * Textarea size variant */ size?: 'sm' | 'md' | 'lg' /** * Textarea visual variant */ variant?: 'default' | 'outlined' /** * Number of visible text lines (rows) */ rows?: number /** * Number of visible text columns (cols) */ cols?: number /** * Maximum number of characters allowed */ maxlength?: number /** * Minimum number of characters required */ minlength?: number /** * How the text should wrap */ wrap?: 'soft' | 'hard' | 'off' /** * Whether to enable automatic resizing */ autoResize?: boolean } export interface TextareaEmits extends ComponentEmits { /** * Emitted when the textarea value changes (v-model) */ 'update:modelValue': [value: string] /** * Emitted on input event */ input: [event: Event] /** * Emitted on change event */ change: [event: Event] /** * Emitted when textarea gains focus */ focus: [event: FocusEvent] /** * Emitted when textarea loses focus */ blur: [event: FocusEvent] } export interface SelectOption { /** * Display label for the option */ label: string /** * Value for the option (used in v-model) */ value: string | number /** * Whether this option is disabled */ disabled?: boolean /** * Internal flag for custom value trigger */ isCustomTrigger?: boolean } // Icon select option (for icon variant) export interface IconSelectOption extends SelectOption {} // Stacked select option (extends base with title + description) export interface StackedSelectOption extends SelectOption { title: string description: string } export interface SelectProps extends ComponentProps { /** * The select's current value (v-model) * String/number for single-select, array for multi-select */ modelValue?: string | number | (string | number)[] /** * Array of options (strings or objects with label/value) */ options: string[] | SelectOption[] /** * Enable multi-select mode */ multiple?: boolean /** * Input name attribute */ name?: string /** * Label text displayed above options */ label?: string /** * Whether the select is disabled */ disabled?: boolean /** * Whether the select is required */ required?: boolean /** * Whether the select has an error state */ error?: boolean /** * Error message to display */ errorMessage?: string /** * Enable custom value entry via text input * When true, the last option becomes a trigger that shows an input field */ allowCustom?: boolean } export interface SelectEmits extends ComponentEmits { /** * Emitted when the select value changes (v-model) */ 'update:modelValue': [value: string | number | (string | number)[]] /** * Emitted when selection changes */ change: [value: string | number | (string | number)[]] } // Container props using discriminated union for type safety type SelectContainerBaseProps = { modelValue?: string | number | (string | number)[] multiple?: boolean allowCustom?: boolean customInputVariant?: 'input' | 'textarea' disabled?: boolean required?: boolean error?: boolean errorMessage?: string label?: string name?: string fullWidth?: boolean } export type SelectContainerProps = SelectContainerBaseProps & ( | { variant: 'inline' options: string[] | SelectOption[] showCheckmark?: boolean } | { variant: 'icon' options: IconSelectOption[] showCheckmark?: boolean } | { variant: 'stacked' options: StackedSelectOption[] showCheckmark?: never } | { variant?: undefined options: string[] | SelectOption[] showCheckmark?: boolean } ) // Container emits export interface SelectContainerEmits extends ComponentEmits { 'update:modelValue': [value: string | number | (string | number)[]] 'change': [value: string | number | (string | number)[]] } // Renderer props (internal components) export interface SelectRendererProps { options: T[] isSelected: (option: T) => boolean handleSelect: (option: T) => void getStateClasses: (option: T) => { base: string state: string disabled: string } getOptionAriaAttributes: (option: T) => Record label?: string disabled?: boolean error?: boolean errorMessage?: string showCheckmark?: boolean multiple?: boolean } // Custom input props export interface SelectCustomInputProps { modelValue: string placeholder?: string variant?: 'input' | 'textarea' mode?: 'append' | 'replace' } export interface SelectCustomInputEmits { 'update:modelValue': [value: string] 'submit': [] 'cancel': [] } export interface ImageUploadProps extends ComponentProps { /** * The uploaded file (v-model) */ modelValue?: File | null /** * Accepted file types (MIME types) */ accept?: string /** * Maximum file size in bytes */ maxSize?: number /** * Maximum image width in pixels */ maxWidth?: number /** * Maximum image height in pixels */ maxHeight?: number /** * Whether the upload is disabled */ disabled?: boolean /** * Whether the upload is required */ required?: boolean /** * Whether the upload has an error state */ error?: boolean /** * Error message to display */ errorMessage?: string /** * Heading text above the upload area */ label?: string /** * Text shown in the drag area */ dragText?: string /** * Text shown on the select file button */ buttonText?: string /** * Alt text for the preview image */ previewAlt?: string } export interface ImageUploadEmits extends ComponentEmits { /** * Emitted when the file value changes (v-model) */ 'update:modelValue': [file: File | null] /** * Emitted when file selection changes */ change: [file: File | null] /** * Emitted when a validation error occurs */ error: [error: string] /** * Emitted when the user removes the file */ remove: [] } export interface CardProps extends ComponentProps { /** * Card variant style */ variant?: 'default' | 'system' /** * Heading text displayed in the card header */ title?: string /** * Whether to show the Titan logo in the top right */ logo?: boolean } export interface CardEmits extends ComponentEmits { // Card components typically don't emit events, but interface is here for consistency } export interface StepperOption { /** * Display label for the step */ label: string /** * Value for the step (used in v-model) */ value: string | number } export interface StepperProps extends ComponentProps { /** * The current active step value (v-model) */ modelValue: string | number /** * Array of step objects with label and value */ steps: StepperOption[] /** * Layout direction for the stepper */ direction?: 'horizontal' | 'vertical' /** * Size variant for the step pills */ size?: 'sm' | 'md' | 'lg' } export interface StepperEmits extends ComponentEmits { /** * Emitted when the active step value changes (v-model) */ 'update:modelValue': [value: string | number] /** * Emitted when the active step changes */ change: [value: string | number] } /** * Schema element for dynamic form rendering */ export interface FormSchemaElement { /** * Component name to render (e.g., 'TitanInput', 'TitanTextarea', 'TitanSubheader') */ component: string /** * Props to pass to the component */ props?: Record /** * Key in the form data object for v-model binding * Omit for non-form elements like TitanSubheader */ model?: string } /** * Array of form schema elements */ export type FormSchema = FormSchemaElement[] export interface FormSectionProps extends ComponentProps { /** * Array of form schema elements defining the form structure */ schema: FormSchema /** * Form data object (v-model) */ modelValue: Record } export interface FormSectionEmits extends ComponentEmits { /** * Emitted when form data changes (v-model) */ 'update:modelValue': [value: Record] }