Comprehensive collection of 40+ custom hooks and 50+ utility functions providing enhanced development experience for data processing, state management, form handling, and UI interactions.
Core utility functions for data manipulation, object processing, and value transformation.
/**
* Enhanced JSON stringify with better handling of complex objects
* @param obj - Object to stringify
* @param replacer - Optional replacer function
* @param space - Optional spacing
* @returns JSON string
*/
function stringify(obj: any, replacer?: (key: string, value: any) => any, space?: number): string;
/**
* Deep object merging with array handling
* @param target - Target object
* @param sources - Source objects to merge
* @returns Merged object
*/
function merge<T>(target: T, ...sources: Partial<T>[]): T;
/**
* Remove undefined properties from object
* @param obj - Source object
* @returns Object without undefined values
*/
function omitUndefined<T extends Record<string, any>>(obj: T): T;
/**
* Remove undefined and empty array properties
* @param obj - Source object
* @returns Object without undefined values and empty arrays
*/
function omitUndefinedAndEmptyArr<T extends Record<string, any>>(obj: T): T;
/**
* Remove boolean properties from object
* @param obj - Source object
* @param keys - Keys to check for boolean values
* @returns Object without specified boolean properties
*/
function omitBoolean<T extends Record<string, any>>(obj: T, keys?: string[]): T;
/**
* Safely execute function with error handling
* @param fn - Function to execute
* @param args - Function arguments
* @returns Function result or undefined if error
*/
function runFunction<T extends (...args: any[]) => any>(fn?: T, ...args: Parameters<T>): ReturnType<T> | undefined;
/**
* Generate unique identifier
* @param size - Length of generated ID
* @returns Unique string ID
*/
function nanoid(size?: number): string;
/**
* Convert object to Map
* @param obj - Source object
* @returns Map representation
*/
function objectToMap<T>(obj: Record<string, T>): Map<string, T>;Usage Examples:
import {
stringify,
merge,
omitUndefined,
runFunction,
nanoid
} from "@ant-design/pro-components";
// Enhanced JSON stringify
const data = {
name: "John",
age: undefined,
created: new Date(),
fn: () => console.log("Hello")
};
const jsonStr = stringify(data); // Handles functions and dates
// Deep object merging
const config = merge(
{ api: { timeout: 5000 } },
{ api: { retries: 3 } },
{ ui: { theme: 'dark' } }
);
// Result: { api: { timeout: 5000, retries: 3 }, ui: { theme: 'dark' } }
// Remove undefined values
const cleanData = omitUndefined({
name: "John",
age: undefined,
email: "john@example.com",
phone: null
});
// Result: { name: "John", email: "john@example.com", phone: null }
// Safe function execution
const result = runFunction(someFunction, arg1, arg2);
// Generate unique IDs
const id = nanoid(); // "V1StGXR8_Z5jdHi6B-myT"
const shortId = nanoid(8); // "V1StGXR8"Utility functions for validation and type checking.
/**
* Check if string is a valid URL
* @param string - String to validate
* @returns Boolean indicating if string is URL
*/
function isUrl(string: string): boolean;
/**
* Check if URL points to an image
* @param path - URL path to check
* @returns Boolean indicating if URL is image
*/
function isImg(path: string): boolean;
/**
* Check if value is null or undefined
* @param value - Value to check
* @returns Boolean indicating if value is nil
*/
function isNil(value: any): value is null | undefined;
/**
* Check if running in browser environment
* @returns Boolean indicating browser environment
*/
function isBrowser(): boolean;
/**
* Deep equality comparison for React components
* @param a - First value
* @param b - Second value
* @returns Boolean indicating equality
*/
function isDeepEqualReact(a: any, b: any): boolean;
/**
* Check if value type supports dropdown rendering
* @param valueType - Value type to check
* @returns Boolean indicating dropdown support
*/
function isDropdownValueType(valueType?: string): boolean;Usage Examples:
import { isUrl, isImg, isNil, isBrowser } from "@ant-design/pro-components";
// URL validation
const validUrl = isUrl("https://example.com"); // true
const invalidUrl = isUrl("not-a-url"); // false
// Image detection
const imageUrl = isImg("https://example.com/image.jpg"); // true
const notImage = isImg("https://example.com/document.pdf"); // false
// Nil checking
const hasValue = !isNil(someValue);
// Browser detection
if (isBrowser()) {
// Safe to access window, document, etc.
localStorage.setItem('key', 'value');
}Functions for date/time processing and formatting with Moment.js and Day.js support.
/**
* Convert moment values for form submission
* @param value - Value to convert
* @param dateFormatter - Date format configuration
* @returns Converted value
*/
function conversionMomentValue(value: any, dateFormatter?: 'string' | 'number' | false): any;
/**
* Alternative name for conversionMomentValue
* @param value - Value to convert
* @param dateFormatter - Date format configuration
* @returns Converted value
*/
function conversionSubmitValue(value: any, dateFormatter?: 'string' | 'number' | false): any;
/**
* Convert moment instances in object
* @param value - Value containing moment instances
* @param format - Target format
* @returns Converted value
*/
function convertMoment(value: any, format?: string): any;
/**
* Date formatter mapping for different types
*/
const dateFormatterMap: Record<string, (value: any, format?: string) => any>;
/**
* Format date arrays
* @param value - Date array to format
* @param format - Date format
* @returns Formatted date array
*/
function dateArrayFormatter(value: any[], format?: string): string[];
/**
* Parse value to Day.js instance
* @param value - Value to parse
* @param format - Date format
* @returns Day.js instance or original value
*/
function parseValueToDay(value: any, format?: string): any;Usage Examples:
import {
conversionMomentValue,
convertMoment,
dateArrayFormatter,
parseValueToDay
} from "@ant-design/pro-components";
// Convert form values with dates
const formData = {
name: "John",
birthday: moment("1990-01-01"),
dateRange: [moment("2023-01-01"), moment("2023-12-31")]
};
const submissionData = conversionMomentValue(formData, 'string');
// Converts moment instances to ISO strings
// Convert single moment
const dateStr = convertMoment(moment(), 'YYYY-MM-DD');
// Format date arrays
const dateRange = dateArrayFormatter([
new Date("2023-01-01"),
new Date("2023-12-31")
], 'YYYY-MM-DD');
// Result: ["2023-01-01", "2023-12-31"]Specialized utilities for form handling and field processing.
/**
* Extract field props or form item props from component props
* @param props - Component props
* @returns Extracted props object
*/
function getFieldPropsOrFormItemProps(props: any): {
fieldProps: any;
formItemProps: any;
};
/**
* Pick Pro-specific props from component props
* @param props - Component props
* @returns Pro-specific props
*/
function pickProProps(props: any): any;
/**
* Pick form item props from component props
* @param props - Component props
* @returns Form item props
*/
function pickProFormItemProps(props: any): any;
/**
* Transform key submission values for nested forms
* @param values - Form values
* @param dataIndex - Data index configuration
* @param map - Transform map function
* @returns Transformed values
*/
function transformKeySubmitValue<T>(
values: T,
dataIndex: string | string[],
map?: (value: any, nameList: string[]) => any
): T;
/**
* Generate copyable content configuration
* @param text - Text to copy
* @param props - Copyable props
* @returns Copyable configuration
*/
function genCopyable(text: any, props?: any): any;Usage Examples:
import {
getFieldPropsOrFormItemProps,
pickProFormItemProps,
transformKeySubmitValue
} from "@ant-design/pro-components";
// Extract props for form components
const componentProps = {
name: "username",
label: "Username",
rules: [{ required: true }],
placeholder: "Enter username",
disabled: false
};
const { fieldProps, formItemProps } = getFieldPropsOrFormItemProps(componentProps);
// Transform nested form values
const formValues = {
user: {
profile: {
name: "John",
age: 30
}
}
};
const transformedValues = transformKeySubmitValue(
formValues,
['user', 'profile'],
(value) => ({ ...value, updatedAt: new Date() })
);Functions for text parsing and processing in Pro components.
/**
* Parse field text values for ProField components
* @param text - Text to parse
* @param valueType - Value type for parsing
* @returns Parsed text result
*/
function proFieldParsingText(text: any, valueType?: string): any;Functions for handling version comparison and compatibility.
/**
* Compare version strings
* @param version1 - First version string
* @param version2 - Second version string
* @returns Comparison result (-1, 0, 1)
*/
function compareVersions(version1: string, version2: string): number;
/**
* Convert legacy tokens to new token format
* @param token - Legacy token object
* @returns Converted token object
*/
function coverToNewToken(token: any): any;
/**
* Handle menu overlay compatibility between versions
* @param overlay - Overlay configuration
* @returns Compatible overlay configuration
*/
function menuOverlayCompatible(overlay: any): any;
/**
* Handle open/visible prop compatibility
* @param props - Component props
* @returns Compatible props
*/
function openVisibleCompatible(props: any): any;
/**
* Handle compatible border configuration
* @param bordered - Border configuration
* @returns Compatible border configuration
*/
function compatibleBorder(bordered?: boolean): any;Advanced hooks for state management and data handling.
/**
* Data fetching hook with caching and loading states
* @param request - Request function
* @param options - Fetch options
* @returns Fetch result with loading state and controls
*/
function useFetchData<T>(
request: () => Promise<T>,
options?: {
defaultData?: T;
manual?: boolean;
refreshDeps?: any[];
}
): [T | undefined, boolean, () => void];
/**
* Editable array management hook
* @param defaultValue - Default array value
* @returns Array state and utility functions
*/
function useEditableArray<T>(defaultValue?: T[]): [T[], UseEditableUtilType<T>];
/**
* Editable map management hook
* @param defaultValue - Default map value
* @returns Map state and utility functions
*/
function useEditableMap<T>(defaultValue?: Record<string, T>): [Record<string, T>, UseEditableMapUtilType<T>];
/**
* Mount-aware state merging hook
* @param defaultValue - Default state value
* @param props - Additional props
* @returns State and setter
*/
function useMountMergeState<T>(
defaultValue: T | (() => T),
props?: {
value?: T;
onChange?: (value: T) => void;
}
): [T, (value: T | ((prevValue: T) => T)) => void];
/**
* Get latest value reference hook
* @param value - Value to reference
* @returns Latest value ref
*/
function useLatest<T>(value: T): React.MutableRefObject<T>;
/**
* Get previous value hook
* @param value - Current value
* @returns Previous value
*/
function usePrevious<T>(value: T): T | undefined;
/**
* Stable function reference hook
* @param fn - Function to stabilize
* @returns Stable function reference
*/
function useRefFunction<T extends (...args: any[]) => any>(fn: T): T;
/**
* Ref-based callback hook
* @param callback - Callback function
* @returns Ref-based callback
*/
function useRefCallback<T extends (...args: any[]) => any>(callback: T): T;
/**
* Reactive ref values hook
* @param value - Value to make reactive
* @returns Reactive ref
*/
function useReactiveRef<T>(value: T): React.MutableRefObject<T>;Usage Examples:
import {
useFetchData,
useEditableArray,
useMountMergeState,
useLatest,
usePrevious
} from "@ant-design/pro-components";
// Data fetching with loading state
const UserList = () => {
const [users, loading, reload] = useFetchData(async () => {
const response = await fetch('/api/users');
return response.json();
});
if (loading) return <div>Loading...</div>;
return (
<div>
<button onClick={reload}>Reload</button>
{users?.map(user => <div key={user.id}>{user.name}</div>)}
</div>
);
};
// Editable array management
const EditableList = () => {
const [items, { add, remove, update, reset }] = useEditableArray([
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
]);
return (
<div>
{items.map((item, index) => (
<div key={item.id}>
<input
value={item.name}
onChange={(e) => update(index, { ...item, name: e.target.value })}
/>
<button onClick={() => remove(index)}>Remove</button>
</div>
))}
<button onClick={() => add({ id: Date.now(), name: 'New Item' })}>
Add Item
</button>
</div>
);
};
// Controlled/uncontrolled state
const ControlledComponent = ({ value, onChange }) => {
const [internalValue, setInternalValue] = useMountMergeState('', {
value,
onChange
});
return (
<input
value={internalValue}
onChange={(e) => setInternalValue(e.target.value)}
/>
);
};Hooks for performance optimization and enhanced effects.
/**
* Debounced value hook
* @param value - Value to debounce
* @param delay - Debounce delay in milliseconds
* @returns Debounced value
*/
function useDebounceValue<T>(value: T, delay: number): T;
/**
* Debounced function hook
* @param fn - Function to debounce
* @param delay - Debounce delay
* @returns Debounced function
*/
function useDebounceFn<T extends (...args: any[]) => any>(fn: T, delay: number): T;
/**
* Deep comparison memoization hook
* @param factory - Memoization factory function
* @param deps - Dependencies for deep comparison
* @returns Memoized value
*/
function useDeepCompareMemo<T>(factory: () => T, deps: any[]): T;
/**
* Deep comparison effect hook
* @param effect - Effect function
* @param deps - Dependencies for deep comparison
*/
function useDeepCompareEffect(effect: React.EffectCallback, deps: any[]): void;
/**
* Debounced deep comparison effect hook
* @param effect - Effect function
* @param deps - Dependencies
* @param delay - Debounce delay
*/
function useDeepCompareEffectDebounce(
effect: React.EffectCallback,
deps: any[],
delay: number
): void;
/**
* Document title management hook
* @param title - Page title
* @param restoreOnUnmount - Restore previous title on unmount
*/
function useDocumentTitle(title: string, restoreOnUnmount?: boolean): void;
/**
* Responsive breakpoint detection hook
* @returns Object with current breakpoint states
*/
function useBreakpoint(): Record<string, boolean>;Usage Examples:
import {
useDebounceValue,
useDebounceFn,
useDeepCompareMemo,
useDocumentTitle,
useBreakpoint
} from "@ant-design/pro-components";
// Debounced search
const SearchComponent = () => {
const [searchText, setSearchText] = useState('');
const debouncedSearchText = useDebounceValue(searchText, 300);
useEffect(() => {
if (debouncedSearchText) {
// Perform search
console.log('Searching for:', debouncedSearchText);
}
}, [debouncedSearchText]);
return (
<input
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
placeholder="Search..."
/>
);
};
// Debounced function
const ApiComponent = () => {
const debouncedSave = useDebounceFn(async (data) => {
await fetch('/api/save', {
method: 'POST',
body: JSON.stringify(data)
});
}, 1000);
return (
<button onClick={() => debouncedSave({ key: 'value' })}>
Save (Debounced)
</button>
);
};
// Deep comparison memo
const ExpensiveComponent = ({ complexObject }) => {
const processedData = useDeepCompareMemo(() => {
return complexCalculation(complexObject);
}, [complexObject]);
return <div>{processedData}</div>;
};
// Document title management
const PageComponent = () => {
useDocumentTitle('My Page Title');
return <div>Page content</div>;
};
// Responsive breakpoints
const ResponsiveComponent = () => {
const screens = useBreakpoint();
return (
<div>
{screens.xs && <div>Extra small screen</div>}
{screens.sm && <div>Small screen</div>}
{screens.md && <div>Medium screen</div>}
{screens.lg && <div>Large screen</div>}
{screens.xl && <div>Extra large screen</div>}
</div>
);
};Functions for component styling and color manipulation.
/**
* Component styling hook
* @param componentName - Component name
* @param styleFn - Style function
* @returns Style utilities
*/
function useStyle(componentName: string, styleFn?: (token: any) => any): {
wrapSSR: (node: React.ReactNode) => React.ReactNode;
hashId: string;
};
/**
* Lighten color utility
* @param color - Color to lighten
* @param amount - Amount to lighten (0-1)
* @returns Lightened color
*/
function lighten(color: string, amount: number): string;
/**
* Set color alpha/opacity
* @param color - Color to modify
* @param alpha - Alpha value (0-1)
* @returns Color with alpha
*/
function setAlpha(color: string, alpha: number): string;
/**
* Reset component styles to default
* @param token - Design token
* @returns Reset styles
*/
function resetComponent(token: any): any;
/**
* Calculate operation unit for spacing
* @param token - Design token
* @returns Operation unit value
*/
function operationUnit(token: any): number;Helper components for enhanced functionality.
/**
* Error boundary wrapper component
* @param props - ErrorBoundary props
* @returns JSX.Element
*/
function ErrorBoundary(props: ErrorBoundaryProps): JSX.Element;
/**
* Inline error display for forms
* @param props - InlineErrorFormItem props
* @returns JSX.Element
*/
function InlineErrorFormItem(props: InlineErrorFormItemProps): JSX.Element;
/**
* Label with icon and tooltip
* @param props - LabelIconTip props
* @returns JSX.Element
*/
function LabelIconTip(props: LabelIconTipProps): JSX.Element;
/**
* Enhanced field label component
* @param props - FieldLabel props
* @returns JSX.Element
*/
function FieldLabel(props: FieldLabelProps): JSX.Element;
/**
* Filter dropdown component
* @param props - FilterDropdown props
* @returns JSX.Element
*/
function FilterDropdown(props: FilterDropdownProps): JSX.Element;
/**
* Dropdown footer component
* @param props - DropdownFooter props
* @returns JSX.Element
*/
function DropdownFooter(props: DropdownFooterProps): JSX.Element;
interface ErrorBoundaryProps {
/** Error fallback render function */
fallback?: (error: Error, errorInfo: any) => React.ReactNode;
/** Error handler */
onError?: (error: Error, errorInfo: any) => void;
/** Children to wrap */
children?: React.ReactNode;
}
interface LabelIconTipProps {
/** Label text */
label?: React.ReactNode;
/** Tooltip content */
tooltip?: React.ReactNode | string;
/** Icon element */
icon?: React.ReactNode;
/** Sub title */
subTitle?: React.ReactNode;
}
interface FieldLabelProps {
/** Label content */
label?: React.ReactNode;
/** Tooltip */
tooltip?: React.ReactNode;
/** Ellipsis */
ellipsis?: boolean;
}Utilities for editable components and row management.
/**
* Get editable row by key
* @param key - Row key
* @param editableKeys - Editable keys array
* @returns Editable row configuration
*/
function editableRowByKey(key: any, editableKeys?: any[]): any;
/**
* Convert record key to string
* @param key - Record key
* @returns String representation of key
*/
function recordKeyToString(key: any): string;// Editable array utilities type
interface UseEditableUtilType<T> {
/** Add new item */
add: (item: T, index?: number) => void;
/** Remove item by index */
remove: (index: number) => void;
/** Update item by index */
update: (index: number, item: T) => void;
/** Move item from one index to another */
move: (fromIndex: number, toIndex: number) => void;
/** Reset to default value */
reset: () => void;
/** Get item by index */
get: (index: number) => T | undefined;
/** Clear all items */
clear: () => void;
}
// Editable map utilities type
interface UseEditableMapUtilType<T> {
/** Set value by key */
set: (key: string, value: T) => void;
/** Remove value by key */
remove: (key: string) => void;
/** Get value by key */
get: (key: string) => T | undefined;
/** Check if key exists */
has: (key: string) => boolean;
/** Clear all values */
clear: () => void;
/** Reset to default value */
reset: () => void;
}
// Hook configuration types
type UseEditableType<T> = [T[], UseEditableUtilType<T>];
type UseEditableMapType<T> = [Record<string, T>, UseEditableMapUtilType<T>];
// Row editable configuration
interface RowEditableConfig<T> {
/** Edit type */
type?: 'single' | 'multiple';
/** Editable keys */
editableKeys?: string[];
/** Change handler */
onChange?: (editableKeys: string[], editableRows: T[]) => void;
/** Save handler */
onSave?: (key: string, record: T, originRow: T, newLine?: boolean) => Promise<boolean | void>;
/** Delete handler */
onDelete?: (key: string, record: T) => Promise<boolean | void>;
/** Cancel handler */
onCancel?: (key: string, record: T, originRow: T, newLine?: boolean) => Promise<boolean | void>;
}
type RowEditableType = 'single' | 'multiple';