react-vite-themes
Version:
A test/experimental React theme system created for learning purposes. Features atomic design components, SCSS variables, and dark/light theme support. Not intended for production use.
537 lines • 16.4 kB
TypeScript
import type { ReactNode, ButtonHTMLAttributes, InputHTMLAttributes } from 'react';
import type { Variant } from './colors';
import type { ValidationRule } from '../utils/validation';
import type { IconName } from '../components/atoms/Icon';
export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
export type ColorScheme = 'solid' | 'outline' | 'ghost' | 'link' | 'gradient' | 'glass';
export interface BaseComponentProps {
className?: string;
children?: ReactNode;
id?: string;
}
export type ComponentProps = BaseComponentProps;
export interface ButtonProps extends BaseComponentProps, Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'size'> {
variant?: Variant;
size?: Size;
colorScheme?: ColorScheme;
isLoading?: boolean;
isDisabled?: boolean;
leftIcon?: ReactNode | string;
rightIcon?: ReactNode | string;
centerIcon?: ReactNode | string;
isFullWidth?: boolean;
textNoWrap?: boolean;
responsive?: boolean;
}
export interface LoadingSpinnerProps extends BaseComponentProps {
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
variant?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'neutral';
colorScheme?: 'solid' | 'outline' | 'ghost';
isAnimated?: boolean;
}
export interface InputProps extends BaseComponentProps, Omit<InputHTMLAttributes<HTMLInputElement | HTMLTextAreaElement>, 'size' | 'value' | 'defaultValue'> {
as?: 'input' | 'textarea';
size?: 'sm' | 'md' | 'lg';
isRounded?: boolean;
leftIcon?: ReactNode | IconName;
leftIconSize?: 'sm' | 'md' | 'lg';
rightIcon?: ReactNode | IconName;
rightIconSize?: 'sm' | 'md' | 'lg';
accept?: string;
multiple?: boolean;
showDateIcon?: boolean;
minDate?: string;
maxDate?: string;
showPasswordToggle?: boolean;
rows?: number;
value?: string | number;
defaultValue?: string | number;
isInvalid?: boolean;
errorMessage?: string;
}
export interface CardProps extends BaseComponentProps, Omit<React.HTMLAttributes<HTMLDivElement>, 'size' | 'style'> {
variant?: Variant;
style?: 'elevated' | 'outline' | 'filled' | 'glass' | 'bordered';
padding?: Size;
isHoverable?: boolean;
isAnimated?: boolean;
image?: {
src: string | File | undefined;
alt?: string;
height?: string | number;
objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
containFit?: boolean;
fallback?: ReactNode | string;
};
isVideoOnImage?: boolean;
onVideoClick?: () => void;
imageTopLeftBadge?: {
text: string;
variant?: Variant;
size?: Size;
className?: string;
} | null;
imageTopRightBadge?: {
text: string;
variant?: Variant;
size?: Size;
className?: string;
} | null;
imageBottomLeftBadge?: {
text: string;
variant?: Variant;
size?: Size;
className?: string;
} | null;
imageBottomRightBadge?: {
text: string;
variant?: Variant;
size?: Size;
className?: string;
} | null;
}
export interface CardHeaderProps extends BaseComponentProps {
colorVariant?: Variant;
}
export interface CardBodyProps extends BaseComponentProps {
colorVariant?: Variant;
}
export interface TableColumn<T = Record<string, unknown>> {
key: string;
label: string;
width?: string | number;
render?: (value: unknown, row: T) => ReactNode;
justifyContent?: 'flex-start' | 'center' | 'flex-end';
alignItems?: 'flex-start' | 'center' | 'flex-end';
}
export interface TableRow {
id?: string | number;
[key: string]: unknown;
}
export interface TableProps extends BaseComponentProps {
columns: TableColumn[];
data: TableRow[];
variant?: Variant;
size?: Size;
isStriped?: boolean;
isHoverable?: boolean;
isBordered?: boolean;
isClickable?: boolean;
onRowClick?: (row: TableRow, rowIndex: number) => void;
}
export interface CardFooterProps extends BaseComponentProps {
colorVariant?: Variant;
}
export interface IconProps extends BaseComponentProps {
name: string;
size?: Size | number;
color?: string;
variant?: Variant;
isHoverable?: boolean;
}
export interface UserMenuItem {
label?: string;
icon?: string;
path?: string;
onClick?: () => void;
isDivider?: boolean;
}
export interface UserMenuProps {
user?: {
name?: string;
email?: string;
avatar?: string;
};
menuItems?: UserMenuItem[];
showUserInfo?: boolean;
}
export interface NavbarProps extends BaseComponentProps {
variant?: 'default' | 'elevated' | 'glass' | 'bordered' | Variant;
size?: Size;
brand?: ReactNode;
isSticky?: boolean;
isTransparent?: boolean;
mobileUserButton?: 'header' | 'sidebar' | 'both' | 'none';
onUserClick?: () => void;
userButtonText?: string;
userButtonIcon?: string;
userButtonElement?: ReactNode;
userButtonNavigateTo?: string;
userMenu?: UserMenuProps;
navigationLinks?: Array<{
path: string;
label: string;
}>;
childrenPosition?: 'start' | 'center' | 'end';
containerSize?: 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | '2xl' | 'full' | 'auto';
accountLanguage?: 'en' | 'fr' | 'es' | 'de' | 'it' | 'pt';
}
export interface SearchBarProps extends BaseComponentProps {
variant?: 'default' | 'filled' | 'outline' | 'glass';
size?: Size;
placeholder?: string;
isDisabled?: boolean;
onSearch?: (query: string) => void;
}
export interface AlertProps extends BaseComponentProps {
variant?: Variant;
size?: Size;
title?: ReactNode;
icon?: string;
showIcon?: boolean;
isClosable?: boolean;
autoDismiss?: boolean;
dismissDelay?: number;
onClose?: () => void;
onDismiss?: () => void;
}
export interface ModalProps extends BaseComponentProps {
isOpen: boolean;
onClose?: () => void;
title?: ReactNode;
size?: Size | 'full';
variant?: 'default' | 'elevated' | 'glass' | 'bordered' | Variant;
showCloseButton?: boolean;
closeOnBackdrop?: boolean;
closeOnEscape?: boolean;
preventScroll?: boolean;
}
export interface FormProps extends BaseComponentProps {
variant?: 'default' | 'elevated' | 'glass' | 'bordered';
onSubmit?: (data: Record<string, unknown>) => void | Promise<void>;
onError?: (error: unknown) => void;
isDisabled?: boolean;
isLoading?: boolean;
initialValues?: Record<string, unknown>;
submitButton?: {
text?: string;
variant?: Variant;
size?: Size;
isFullWidth?: boolean;
leftIcon?: string;
rightIcon?: string;
isDisabled?: boolean;
isLoading?: boolean;
} | boolean;
cancelButton?: {
text?: string;
variant?: Variant;
size?: Size;
isFullWidth?: boolean;
leftIcon?: string;
rightIcon?: string;
isDisabled?: boolean;
onClick?: () => void;
} | boolean;
resetButton?: {
text?: string;
variant?: Variant;
size?: Size;
isFullWidth?: boolean;
leftIcon?: string;
rightIcon?: string;
isDisabled?: boolean;
} | boolean;
showActions?: boolean;
validationSchema?: Record<string, ValidationRule>;
validateOnChange?: boolean;
validateOnBlur?: boolean;
showValidationErrors?: boolean;
onStateChange?: (state: {
values: Record<string, unknown>;
errors: Record<string, string[]>;
touched: Record<string, boolean>;
isDirty: boolean;
isSubmitting: boolean;
isValid: boolean;
}) => void;
showFormError?: boolean;
formErrorVariant?: Variant;
showFormSuccess?: boolean;
formSuccessVariant?: Variant;
formMessagePosition?: 'top' | 'bottom';
formSuccessMessage?: string;
triggerValidation?: boolean;
}
export interface SidebarProps extends BaseComponentProps {
isOpen: boolean;
onClose?: () => void;
direction?: 'left' | 'right' | 'top' | 'bottom';
showHeader?: boolean;
headerContent?: ReactNode;
size?: Size | 'full';
variant?: 'default' | 'elevated' | 'glass' | 'bordered';
}
export interface FooterProps extends BaseComponentProps {
sections?: Array<{
title: string;
links: Array<{
label: string;
href: string;
external?: boolean;
}>;
}>;
companyName?: string;
companyDescription?: string;
socialLinks?: Array<{
label: string;
href: string;
external?: boolean;
}>;
copyrightText?: string;
showBackToTop?: boolean;
onBackToTop?: () => void;
}
export interface StatCardProps extends BaseComponentProps {
title?: ReactNode;
value: ReactNode;
subtitle?: ReactNode;
icon?: ReactNode | string;
trend?: 'up' | 'down' | 'neutral';
trendValue?: ReactNode;
variant?: Variant;
style?: 'elevated' | 'outline' | 'filled' | 'glass' | 'bordered';
size?: Size;
isHoverable?: boolean;
}
export interface BadgeProps extends BaseComponentProps {
variant?: Variant;
size?: Size;
isRounded?: boolean;
isOutlined?: boolean;
}
export interface ProgressBarProps extends BaseComponentProps {
value: number;
max?: number;
variant?: Variant;
size?: Size;
showLabel?: boolean;
labelPosition?: 'top' | 'bottom';
isAnimated?: boolean;
}
export interface ProgressCircleProps extends BaseComponentProps {
value: number;
max?: number;
variant?: Variant;
size?: Size;
style?: 'filled' | 'border';
showLabel?: boolean;
showPercentage?: boolean;
label?: string;
isAnimated?: boolean;
strokeWidth?: number;
textColor?: string;
}
export interface ImageProps extends BaseComponentProps {
src: string;
alt?: string;
variant?: 'default' | 'elevated' | 'glass' | 'bordered' | Variant;
size?: Size;
style?: 'natural' | 'square' | 'rectangle' | 'circle' | 'landscape' | 'portrait' | 'glass';
isRounded?: boolean;
isResponsive?: boolean;
isLoading?: boolean;
isError?: boolean;
isHoverable?: boolean;
noBorder?: boolean;
fallback?: ReactNode | string;
overlay?: 'none' | 'black' | 'white' | 'gradient' | string;
overlayOpacity?: number;
label?: string;
labelPosition?: 'top' | 'bottom' | 'center';
labelColor?: string;
labelBackground?: string;
labelPadding?: string;
onClick?: () => void;
}
export interface FormWizardStep {
title: string;
description?: string;
icon?: string;
component: React.ReactNode;
validationSchema?: Record<string, ValidationRule>;
}
export interface FormWizardProps extends BaseComponentProps {
steps: FormWizardStep[];
onComplete?: (data: Record<string, unknown>) => void | Promise<void>;
onStepChange?: (currentStep: number, direction: 'next' | 'prev') => void;
showStepIndicator?: boolean;
showStepDescription?: boolean;
variant?: 'default' | 'numbered' | 'icons';
layout?: 'horizontal' | 'vertical' | 'sidebar';
prevButton?: {
text?: string;
variant?: Variant;
size?: Size;
leftIcon?: string;
rightIcon?: string;
} | boolean;
nextButton?: {
text?: string;
variant?: Variant;
size?: Size;
leftIcon?: string;
rightIcon?: string;
} | boolean;
submitButton?: {
text?: string;
variant?: Variant;
size?: Size;
leftIcon?: string;
rightIcon?: string;
} | boolean;
initialStep?: number;
allowSkipSteps?: boolean;
showProgressBar?: boolean;
}
export interface MultiStepFormStep {
id: string;
title: string;
description?: string;
content: React.ReactNode;
validationSchema?: Record<string, ValidationRule>;
icon?: string;
}
export interface MultiStepFormProps extends BaseComponentProps {
steps: MultiStepFormStep[];
initialData?: Record<string, unknown>;
onSubmit?: (data: Record<string, unknown>) => void | Promise<void>;
onComplete?: (data: Record<string, unknown>) => void | Promise<void>;
onStepChange?: (currentStep: number, direction: 'next' | 'prev') => void;
showProgress?: boolean;
showStepNumbers?: boolean;
variant?: 'default' | 'numbered' | 'icons';
design?: 'default' | 'circles' | 'dots' | 'tabs' | 'timeline' | 'cards' | 'sidebar';
style?: 'default' | 'elevated' | 'glass' | 'bordered' | 'minimal' | 'modern';
useCard?: boolean;
prevButton?: {
text?: string;
variant?: Variant;
size?: Size;
leftIcon?: string;
rightIcon?: string;
} | boolean;
nextButton?: {
text?: string;
variant?: Variant;
size?: Size;
leftIcon?: string;
rightIcon?: string;
} | boolean;
submitButton?: {
text?: string;
variant?: Variant;
size?: Size;
leftIcon?: string;
rightIcon?: string;
} | boolean;
initialStep?: number;
allowSkipSteps?: boolean;
validateOnChange?: boolean;
validateOnBlur?: boolean;
showValidationErrors?: boolean;
showStepValidation?: boolean;
showStepCompletion?: boolean;
}
export interface TabsProps extends BaseComponentProps {
tabs?: Array<{
id: string;
label: string;
icon?: string;
content?: ReactNode;
targetId?: string;
disabled?: boolean;
}>;
children?: ReactNode;
defaultActiveTab?: string;
variant?: 'default' | 'elevated' | 'pills' | 'underline';
size?: Size;
isFullWidth?: boolean;
isVertical?: boolean;
showIcons?: boolean;
onTabChange?: (tabId: string) => void;
}
export interface AccordionProps extends BaseComponentProps {
variant?: Variant | 'default' | 'bordered' | 'elevated' | 'glass';
size?: Size;
isMultiple?: boolean;
defaultOpenItems?: string[];
openItems?: string[];
onOpenChange?: (openItems: string[]) => void;
gap?: Size | 'none';
}
export interface AccordionItemProps extends BaseComponentProps {
id: string;
title: ReactNode;
icon?: string;
isDisabled?: boolean;
isOpen?: boolean;
onToggle?: () => void;
variant?: Variant | 'default' | 'bordered' | 'elevated' | 'glass';
size?: Size;
}
export interface BreadcrumbItem {
id?: string;
label: string;
href?: string;
icon?: string;
onClick?: () => void;
}
export interface BreadcrumbProps extends BaseComponentProps, Omit<React.HTMLAttributes<HTMLElement>, 'size'> {
items: BreadcrumbItem[];
separator?: string;
size?: Size;
variant?: Variant | 'default' | 'elevated' | 'glass' | 'bordered';
isRounded?: boolean;
}
export interface RichTextEditorProps extends BaseComponentProps {
className?: string;
size?: 'sm' | 'md' | 'lg';
isRounded?: boolean;
value?: string;
defaultValue?: string;
placeholder?: string;
showToolbar?: boolean;
toolbarPosition?: 'top' | 'bottom';
allowedFormats?: ('bold' | 'italic' | 'underline' | 'bullet' | 'number' | 'indent' | 'outdent')[];
rows?: number;
minHeight?: string;
maxHeight?: string;
onChange?: (value: string) => void;
onFocus?: (event: React.FocusEvent<HTMLDivElement>) => void;
onBlur?: (event: React.FocusEvent<HTMLDivElement>) => void;
disabled?: boolean;
required?: boolean;
readOnly?: boolean;
autoFocus?: boolean;
name?: string;
id?: string;
isInvalid?: boolean;
errorMessage?: string;
}
export interface RadioGroupProps extends BaseComponentProps {
value?: string;
onChange?: (value: string) => void;
options: Array<{
value: string;
label: string;
icon?: string;
}>;
variant?: 'default' | 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
disabled?: boolean;
}
export interface PaginationProps extends BaseComponentProps {
currentPage: number;
totalPages: number;
totalItems: number;
pageSize: number;
pageSizeOptions?: number[];
showPageSizeSelector?: boolean;
showPageInfo?: boolean;
variant?: Variant;
size?: Size;
onPageChange?: (page: number) => void;
onPageSizeChange?: (pageSize: number) => void;
}
//# sourceMappingURL=components.d.ts.map