flexium
Version:
A lightweight, signals-based UI framework with cross-platform renderers
421 lines (409 loc) • 12.6 kB
text/typescript
import { S as Signal, C as Computed } from './canvas-BarP3tEC.cjs';
export { b as batch, e as effect, r as root, u as untrack } from './canvas-BarP3tEC.cjs';
export { s as state } from './state-EWGQpL70.cjs';
export { A as Arc, q as ArcProps, C as Canvas, r as CanvasProps, c as CanvasText, o as CanvasTextProps, a as Circle, l as CircleProps, i as CommonStyle, I as Image, f as ImageProps, L as Line, p as LineProps, b as Path, m as PathProps, P as Pressable, g as PressableProps, R as Rect, k as RectProps, S as ScrollView, h as ScrollViewProps, T as Text, e as TextProps, j as TextStyle, V as View, d as ViewProps, n as normalizeStyle } from './utils-BMB3Vuxf.cjs';
/**
* Motion Component - Declarative animations using Web Animations API
*
* Provides smooth, performant animations without JavaScript RAF
* Supports transforms, opacity, spring physics, and layout animations
*/
/**
* Animation properties that can be animated
*/
interface AnimatableProps {
x?: number;
y?: number;
scale?: number;
scaleX?: number;
scaleY?: number;
rotate?: number;
opacity?: number;
width?: number | string;
height?: number | string;
}
/**
* Spring physics configuration
*/
interface SpringConfig {
tension?: number;
friction?: number;
mass?: number;
}
/**
* Motion component props
*/
interface MotionProps {
element?: HTMLElement | null;
initial?: AnimatableProps;
animate?: AnimatableProps;
exit?: AnimatableProps;
duration?: number;
spring?: SpringConfig;
easing?: string;
delay?: number;
onAnimationStart?: () => void;
onAnimationComplete?: () => void;
}
/**
* Motion controller class
* Manages animations for a single element using Web Animations API
*/
declare class MotionController {
private element;
private animation;
private resizeObserver;
private previousSize;
constructor(element: HTMLElement);
/**
* Animate from initial to animate props
*/
animate(props: MotionProps): void;
/**
* Animate exit (used when element is being removed)
*/
animateExit(exitProps: AnimatableProps, duration?: number, easing?: string): Promise<void>;
/**
* Enable layout animations (animate size changes automatically)
*/
enableLayoutAnimation(duration?: number, easing?: string): void;
/**
* Disable layout animations
*/
disableLayoutAnimation(): void;
/**
* Cancel current animation
*/
cancel(): void;
/**
* Cleanup all animations and observers
*/
dispose(): void;
}
/**
* Create a motion-enabled element
*
* @example
* const motionDiv = createMotion({
* initial: { opacity: 0, y: 20 },
* animate: { opacity: 1, y: 0 },
* duration: 300,
* });
* document.body.appendChild(motionDiv.element);
*/
declare function createMotion(props: MotionProps & {
tagName?: string;
}): {
element: HTMLElement;
controller: MotionController;
update: (newProps: MotionProps) => void;
dispose: () => void;
};
/**
* Hook-like function to use motion with signals
*
* @example
* const visible = signal(false);
* const motion = useMotion(element, {
* initial: { opacity: 0 },
* animate: visible.value ? { opacity: 1 } : { opacity: 0 },
* });
*/
declare function useMotion(element: HTMLElement, propsSignal: Signal<MotionProps>): {
controller: MotionController;
dispose: () => void;
};
/**
* Form Component - Signal-based forms with built-in validation
*
* Provides reactive form state management without external libraries
* Supports nested fields, async validation, and automatic error tracking
*/
/**
* Field value types
*/
type FieldValue = string | number | boolean | File | null | undefined | FieldValue[] | {
[key: string]: FieldValue;
};
/**
* Validation function type
* Returns true/undefined for valid, or error message string for invalid
*/
type ValidationRule<T = FieldValue> = (value: T, formData: FormData) => string | boolean | undefined | Promise<string | boolean | undefined>;
/**
* Field validation rules
*/
interface FieldValidation {
[fieldName: string]: ValidationRule | ValidationRule[];
}
/**
* Form data type
*/
interface FormData {
[fieldName: string]: FieldValue;
}
/**
* Field state
*/
interface FieldState<T = FieldValue> {
value: Signal<T>;
error: Computed<string | null>;
touched: Signal<boolean>;
dirty: Signal<boolean>;
validating: Signal<boolean>;
}
/**
* Form state
*/
interface FormState {
data: Signal<FormData>;
errors: Computed<{
[key: string]: string | null;
}>;
isValid: Computed<boolean>;
isSubmitting: Signal<boolean>;
isDirty: Computed<boolean>;
touchedFields: Signal<Set<string>>;
dirtyFields: Signal<Set<string>>;
}
/**
* Form configuration
*/
interface FormConfig {
initialValues?: FormData;
validation?: FieldValidation;
validateOnChange?: boolean;
validateOnBlur?: boolean;
onSubmit?: (data: FormData) => void | Promise<void>;
}
/**
* Create a form with reactive state and validation
*/
declare function createForm(config?: FormConfig): {
state: FormState;
fields: Map<string, FieldState>;
getField: <T = FieldValue>(name: string) => FieldState<T>;
setFieldValue: (name: string, value: FieldValue) => void;
setFieldError: (name: string, error: string | null) => void;
setFieldTouched: (name: string, touched: boolean) => void;
validateField: (name: string) => Promise<string | null>;
validateForm: () => Promise<boolean>;
handleSubmit: (e?: Event) => Promise<void>;
reset: (values?: FormData) => void;
dispose: () => void;
};
/**
* Input Component - Controlled input with signal binding and accessibility
*
* Provides reactive input elements with error states and ARIA attributes
* Works seamlessly with the Form component
*/
/**
* Input types
*/
type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' | 'date' | 'time' | 'datetime-local' | 'month' | 'week' | 'color' | 'file';
/**
* Input component props
*/
interface InputProps {
type?: InputType;
name?: string;
value?: Signal<string | number>;
placeholder?: string;
disabled?: boolean;
required?: boolean;
readonly?: boolean;
autoComplete?: string;
autoFocus?: boolean;
maxLength?: number;
minLength?: number;
min?: number | string;
max?: number | string;
step?: number | string;
pattern?: string;
multiple?: boolean;
accept?: string;
error?: Signal<string | null>;
touched?: Signal<boolean>;
className?: string;
style?: Partial<CSSStyleDeclaration>;
id?: string;
ariaLabel?: string;
ariaDescribedby?: string;
ariaInvalid?: boolean;
onInput?: (value: string, event: Event) => void;
onChange?: (value: string, event: Event) => void;
onBlur?: (event: FocusEvent) => void;
onFocus?: (event: FocusEvent) => void;
onKeyDown?: (event: KeyboardEvent) => void;
onKeyUp?: (event: KeyboardEvent) => void;
}
/**
* Create a controlled input element
*/
declare function createInput(props: InputProps): {
element: HTMLInputElement;
update: (newProps: Partial<InputProps>) => void;
dispose: () => void;
};
/**
* Create an input wrapper with label and error message
*/
declare function createInputField(props: InputProps & {
label?: string;
helperText?: string;
showError?: boolean;
}): {
element: HTMLDivElement;
input: HTMLInputElement;
dispose: () => void;
};
/**
* Button Component - Accessible button with unified touch/click handler
*
* Provides onPress handler that works consistently across mouse, touch, and keyboard
* Includes full ARIA support and style props
*/
/**
* Button variants
*/
type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
/**
* Button sizes
*/
type ButtonSize = 'sm' | 'md' | 'lg';
/**
* Button type attribute
*/
type ButtonType = 'button' | 'submit' | 'reset';
/**
* Button component props
*/
interface ButtonProps {
type?: ButtonType;
variant?: ButtonVariant;
size?: ButtonSize;
disabled?: Signal<boolean> | boolean;
loading?: Signal<boolean> | boolean;
fullWidth?: boolean;
children?: string | HTMLElement | HTMLElement[];
leftIcon?: HTMLElement;
rightIcon?: HTMLElement;
loadingText?: string;
className?: string;
style?: Partial<CSSStyleDeclaration>;
id?: string;
role?: string;
ariaLabel?: string;
ariaDescribedby?: string;
ariaExpanded?: boolean;
ariaPressed?: boolean;
ariaControls?: string;
onPress?: (event: Event) => void | Promise<void>;
onPressStart?: (event: PointerEvent) => void;
onPressEnd?: (event: PointerEvent) => void;
onFocus?: (event: FocusEvent) => void;
onBlur?: (event: FocusEvent) => void;
onKeyDown?: (event: KeyboardEvent) => void;
}
/**
* Create a button element with unified press handling
*/
declare function createButton(props: ButtonProps): {
element: HTMLButtonElement;
update: (newProps: Partial<ButtonProps>) => void;
dispose: () => void;
};
/**
* Create an icon button (button with only an icon)
*/
declare function createIconButton(props: ButtonProps & {
icon: HTMLElement;
}): {
element: HTMLButtonElement;
dispose: () => void;
};
/**
* Text Component - Typography with semantic HTML and style props
*
* Automatically selects appropriate HTML element (p, h1-h6, span) based on props
* Supports typography props and accessibility features
*/
/**
* Text variants (determines semantic HTML tag)
*/
type TextVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'label' | 'strong' | 'em' | 'code' | 'pre';
/**
* Text alignment
*/
type TextAlign = 'left' | 'center' | 'right' | 'justify';
/**
* Text decoration
*/
type TextDecoration = 'none' | 'underline' | 'line-through' | 'overline';
/**
* Text transform
*/
type TextTransform = 'none' | 'uppercase' | 'lowercase' | 'capitalize';
/**
* Text component props
*/
interface TextProps {
as?: TextVariant;
children?: string | number | HTMLElement | HTMLElement[] | Signal<string | number>;
fontSize?: number | string;
fontWeight?: number | string;
fontFamily?: string;
lineHeight?: number | string;
letterSpacing?: number | string;
textAlign?: TextAlign;
textDecoration?: TextDecoration;
textTransform?: TextTransform;
color?: string;
whiteSpace?: 'normal' | 'nowrap' | 'pre' | 'pre-wrap' | 'pre-line';
fontSizeBase?: number | string;
fontSizeSm?: number | string;
fontSizeMd?: number | string;
fontSizeLg?: number | string;
fontSizeXl?: number | string;
display?: 'inline' | 'block' | 'inline-block';
margin?: number | string;
marginTop?: number | string;
marginRight?: number | string;
marginBottom?: number | string;
marginLeft?: number | string;
padding?: number | string;
paddingTop?: number | string;
paddingRight?: number | string;
paddingBottom?: number | string;
paddingLeft?: number | string;
maxWidth?: number | string;
truncate?: boolean;
lineClamp?: number;
className?: string;
style?: Partial<CSSStyleDeclaration>;
id?: string;
role?: string;
ariaLabel?: string;
ariaDescribedby?: string;
ariaLive?: 'off' | 'polite' | 'assertive';
onClick?: (event: MouseEvent) => void;
onMouseEnter?: (event: MouseEvent) => void;
onMouseLeave?: (event: MouseEvent) => void;
}
/**
* Create a text element with typography props
*/
declare function createText(props: TextProps): {
element: HTMLElement;
update: (newProps: Partial<TextProps>) => void;
dispose: () => void;
};
/**
* Convenience functions for common text elements
*/
declare function createHeading(level: 1 | 2 | 3 | 4 | 5 | 6, props: Omit<TextProps, 'as'>): ReturnType<typeof createText>;
declare function createParagraph(props: Omit<TextProps, 'as'>): ReturnType<typeof createText>;
declare function createLabel(props: Omit<TextProps, 'as'>): ReturnType<typeof createText>;
declare function createCode(props: Omit<TextProps, 'as'>): ReturnType<typeof createText>;
export { type ButtonProps, type ButtonSize, type ButtonVariant, type FieldState, type FormState, MotionController, type MotionProps, type SpringConfig, type ValidationRule, createButton, createCode, createForm, createHeading, createIconButton, createInput, createInputField, createLabel, createMotion, createParagraph, createText, useMotion };