import { CSSProperties, InputHTMLAttributes, ReactNode } from 'react';
import { WidgetProps } from '@rjsf/utils';
import { TitleProps } from 'antd/es/typography/Title';
import { TextProps } from 'antd/es/typography/Text';
import { ParagraphProps } from 'antd/es/typography/Paragraph';
import { DividerProps } from 'antd/es/divider';
type MarkdownToJSXOptions = import('markdown-to-jsx').MarkdownToJSX.Options;
/**
* Base interface for all enhanced widgets
*/
export interface EnhancedWidgetProps extends WidgetProps {
}
/**
* Ant Design Input component options that can be configured through uiSchema
*/
export interface AntInputOptions {
size?: 'large' | 'middle' | 'small';
placeholder?: string;
autoFocus?: boolean;
autoComplete?: string;
inputMode?: InputHTMLAttributes['inputMode'];
prefix?: ReactNode;
suffix?: ReactNode;
prefixIconName?: string;
suffixIconName?: string;
allowClear?: boolean;
bordered?: boolean;
variant?: 'outlined' | 'borderless' | 'filled';
defaultValue?: string;
maxLength?: number;
showCount?: boolean | {
formatter: (info: {
value: string;
count: number;
maxLength?: number;
}) => ReactNode;
};
status?: 'error' | 'warning';
style?: CSSProperties;
className?: string;
addonBefore?: ReactNode;
addonBeforePosition?: 'inside' | 'outside';
addonAfter?: ReactNode;
addonAfterPosition?: 'inside' | 'outside';
addonBeforeIconName?: string;
addonAfterIconName?: string;
emptyValue?: any;
}
/**
* Ant Design TextArea component options
*/
export interface AntTextAreaOptions extends AntInputOptions {
rows?: number;
autoSize?: boolean | {
minRows?: number;
maxRows?: number;
};
showCount?: boolean | {
formatter: (info: {
value: string;
count: number;
maxLength?: number;
}) => ReactNode;
};
}
/**
* Ant Design DatePicker component options
*/
export interface AntDatePickerOptions {
format?: string | string[];
picker?: 'date' | 'week' | 'month' | 'quarter' | 'year';
placeholder?: string | [string, string];
placement?: 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';
range?: boolean;
disablePastDates?: boolean;
disableFutureDates?: boolean;
disableWeekends?: boolean;
showTime?: boolean | object;
showNow?: boolean;
showToday?: boolean;
disabledDate?: (currentDate: any) => boolean;
size?: 'large' | 'middle' | 'small';
bordered?: boolean;
variant?: 'outlined' | 'borderless' | 'filled';
suffixIcon?: ReactNode;
suffixIconName?: string;
style?: CSSProperties;
className?: string;
status?: 'error' | 'warning';
emptyValue?: any;
[key: string]: any;
}
/**
* Ant Design InputNumber component options
*/
export interface AntInputNumberOptions {
size?: 'large' | 'middle' | 'small';
placeholder?: string;
prefix?: ReactNode;
suffix?: ReactNode;
prefixIconName?: string;
suffixIconName?: string;
addonBeforeIconName?: string;
addonAfterIconName?: string;
/** Emit exact decimal strings. Requires schema.type = 'string' to avoid RJSF numeric coercion. */
stringMode?: boolean;
min?: number;
max?: number;
step?: number;
precision?: number;
decimalSeparator?: string;
formatter?: (value: number | string | undefined, info: {
userTyping: boolean;
input: string;
}) => string;
parser?: (value: string | undefined) => number;
keyboard?: boolean;
controls?: boolean | {
upIcon?: ReactNode;
downIcon?: ReactNode;
};
bordered?: boolean;
variant?: 'outlined' | 'borderless' | 'filled';
style?: CSSProperties;
className?: string;
status?: 'error' | 'warning';
addonBefore?: ReactNode;
addonAfter?: ReactNode;
emptyValue?: any;
}
/**
* Ant Design Slider component options
*/
export interface AntSliderOptions {
min?: number;
max?: number;
step?: number | null;
range?: boolean | {
draggableTrack?: boolean;
};
dots?: boolean;
marks?: Record | boolean;
included?: boolean;
vertical?: boolean;
reverse?: boolean;
tooltip?: any;
trackStyle?: CSSProperties | CSSProperties[];
handleStyle?: CSSProperties | CSSProperties[];
railStyle?: CSSProperties;
style?: CSSProperties;
className?: string;
keyboard?: boolean;
disabled?: boolean;
}
/**
* Ant Design Rate component options
*/
export interface AntRateOptions {
allowHalf?: boolean;
allowClear?: boolean;
autoFocus?: boolean;
character?: ReactNode | ((props: {
index: number;
}) => ReactNode);
count?: number;
tooltips?: string[];
iconName?: string;
style?: CSSProperties;
className?: string;
}
/**
* Ant Design TimePicker component options
*/
export interface AntTimePickerOptions {
format?: string;
use12Hours?: boolean;
hourStep?: number;
minuteStep?: number;
secondStep?: number;
showNow?: boolean;
placement?: 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';
size?: 'large' | 'middle' | 'small';
bordered?: boolean;
variant?: 'outlined' | 'borderless' | 'filled';
status?: 'error' | 'warning';
suffixIconName?: string;
style?: CSSProperties;
className?: string;
[key: string]: any;
}
/**
* Ant Design ColorPicker component options
*/
export interface AntColorPickerOptions {
format?: 'hex' | 'hsb' | 'rgb';
onFormatChange?: (format: string) => void;
disabledAlpha?: boolean;
presets?: any[];
showText?: boolean | ((color: any) => ReactNode);
placement?: 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';
size?: 'large' | 'middle' | 'small';
allowClear?: boolean;
style?: CSSProperties;
className?: string;
[key: string]: any;
}
/**
* Ant Design Switch component options
*/
export interface AntSwitchOptions {
checkedChildren?: ReactNode;
unCheckedChildren?: ReactNode;
checkedIconName?: string;
unCheckedIconName?: string;
size?: 'small' | 'default';
loading?: boolean;
autoFocus?: boolean;
style?: CSSProperties;
className?: string;
[key: string]: any;
}
/**
* Ant Design Image component options
*/
export interface AntImageOptions {
src?: string;
alt?: string;
width?: number | string;
height?: number | string;
fallback?: string;
preview?: boolean | {
visible?: boolean;
onVisibleChange?: (visible: boolean) => void;
};
placeholder?: ReactNode;
crossOrigin?: '' | 'anonymous' | 'use-credentials';
decoding?: 'async' | 'auto' | 'sync';
loading?: 'eager' | 'lazy';
referrerPolicy?: string;
sizes?: string;
srcSet?: string;
draggable?: boolean;
previewMask?: ReactNode;
rootClassName?: string;
wrapperClassName?: string;
wrapperStyle?: CSSProperties;
onClick?: (e: any) => void;
onLoad?: () => void;
onError?: (e: any) => void;
style?: CSSProperties;
className?: string;
[key: string]: any;
}
/**
* Ant Design Alert component options
*/
export interface AntAlertOptions {
message?: ReactNode;
description?: ReactNode;
type?: 'success' | 'info' | 'warning' | 'error';
showIcon?: boolean;
iconName?: string;
banner?: boolean;
closable?: boolean;
closeText?: ReactNode;
action?: ReactNode;
icon?: ReactNode;
style?: CSSProperties;
className?: string;
afterClose?: () => void;
[key: string]: any;
}
/**
* Typography-based heading/title options
*/
export interface TitleWidgetOptions {
text?: string;
renderAs?: 'title' | 'text' | 'paragraph';
align?: 'left' | 'center' | 'right' | 'justify';
prefix?: ReactNode;
suffix?: ReactNode;
prefixIconName?: string;
suffixIconName?: string;
level?: TitleProps['level'];
type?: TextProps['type'];
mark?: TextProps['mark'];
code?: TextProps['code'];
keyboard?: TextProps['keyboard'];
underline?: TextProps['underline'];
delete?: TextProps['delete'];
strong?: TextProps['strong'];
italic?: TextProps['italic'];
disabled?: TextProps['disabled'];
copyable?: TextProps['copyable'];
editable?: TextProps['editable'];
ellipsis?: ParagraphProps['ellipsis'];
style?: CSSProperties;
className?: string;
}
/**
* Rich-content display options (HTML/Markdown)
*/
export interface HtmlWidgetOptions {
content?: string;
format?: 'html' | 'markdown' | 'text';
sanitizeHtml?: boolean;
markdownOptions?: MarkdownToJSXOptions;
renderAs?: 'paragraph' | 'text';
align?: 'left' | 'center' | 'right' | 'justify';
preserveWhitespace?: boolean;
type?: TextProps['type'];
strong?: TextProps['strong'];
underline?: TextProps['underline'];
code?: TextProps['code'];
ellipsis?: boolean;
style?: CSSProperties;
className?: string;
}
/**
* Spacer widget visual configuration
*/
export interface SpacerWidgetOptions {
size?: 'small' | 'middle' | 'large' | number;
sizeToken?: 'small' | 'middle' | 'large';
sizePx?: number;
direction?: 'vertical' | 'horizontal';
fullWidth?: boolean;
fullHeight?: boolean;
inline?: boolean;
className?: string;
style?: CSSProperties;
ariaLabel?: string;
}
/**
* Ant Design Divider options with icon support
*/
export interface AntDividerOptions extends Partial {
text?: ReactNode;
iconName?: string;
icon?: ReactNode;
}
/**
* Type mapping for widget options
*/
export type WidgetOptionsMap = {
text: AntInputOptions;
textarea: AntTextAreaOptions;
password: AntInputOptions;
email: AntInputOptions;
tel: AntInputOptions;
url: AntInputOptions;
number: AntInputNumberOptions;
date: AntDatePickerOptions;
'datetime-local': AntDatePickerOptions;
time?: AntTimePickerOptions;
range?: AntSliderOptions;
rating?: AntRateOptions;
color?: AntColorPickerOptions;
switch?: AntSwitchOptions;
image?: AntImageOptions;
alert?: AntAlertOptions;
title?: TitleWidgetOptions;
heading?: TitleWidgetOptions;
html?: HtmlWidgetOptions;
markdown?: HtmlWidgetOptions;
spacer?: SpacerWidgetOptions;
divider?: AntDividerOptions;
file: any;
};
/**
* Common props passed to widgets from RJSF that we use frequently
*/
export interface CommonWidgetProps {
id: string;
value: any;
disabled?: boolean;
readonly?: boolean;
required?: boolean;
placeholder?: string;
onChange: (value: any) => void;
onBlur?: (id: string, value: any) => void;
onFocus?: (id: string, value: any) => void;
options?: any;
rawErrors?: string[];
schema: any;
}
export {};