@muban/muban
Version:
Writing components for server-rendered HTML
109 lines (108 loc) • 5.26 kB
TypeScript
import type { Ref } from '@vue/reactivity';
import type { ComponentFactory, InternalComponentInstance } from '../Component.types';
import type { CollectionBinding, ElementBinding, ComponentBinding, ComponentCollectionBinding } from '../bindings/bindingDefinitions';
import type { BindProps } from '../bindings/bindings.types';
export declare type RefOptions<T extends Record<string, any>> = T & {
ignoreGuard?: boolean;
};
export declare type RefElementType = HTMLElement | SVGElement;
export declare type ComponentRefItemElement<T extends RefElementType = HTMLElement> = {
type: 'element';
ref: string;
queryRef: (parent: HTMLElement) => T | null;
createRef: (instance: InternalComponentInstance) => ElementRef<T, BindProps>;
isRequired?: boolean;
};
export declare type ComponentRefItemCollection<T extends RefElementType = HTMLElement> = {
type: 'collection';
ref: string;
queryRef: (parent: HTMLElement) => Array<T>;
createRef: (instance: InternalComponentInstance) => CollectionRef<T, BindProps>;
};
export declare type ComponentRefItemComponent<T extends ComponentFactory<Record<string, any>>> = {
type: 'component';
ref?: string;
componentRef: string;
queryRef: (parent: HTMLElement) => HTMLElement | null;
createRef: (instance: InternalComponentInstance) => ComponentRef<T>;
isRequired?: boolean;
};
export declare type ComponentRefItemComponentCollection<T extends ComponentFactory<Record<string, any>>> = {
type: 'componentCollection';
ref?: string;
componentRef: string;
queryRef: (parent: HTMLElement) => Array<HTMLElement>;
createRef: (instance: InternalComponentInstance) => ComponentsRef<T>;
};
export declare type ComponentRefItemShortcuts = string | ComponentRefItemElement<RefElementType>['queryRef'];
export declare type ResolvedComponentRefItem = ComponentRefItemElement<RefElementType> | ComponentRefItemCollection<RefElementType> | ComponentRefItemComponent<ComponentFactory<any>> | ComponentRefItemComponentCollection<ComponentFactory<any>>;
export declare type ComponentRefItem = ComponentRefItemShortcuts | ResolvedComponentRefItem;
/**
* These are the types that are returned from the refDefinition selector function,
* and passed to the component's setup function, and is used for:
* - applying bindings
* - get access to the elements/components related to the ref
*/
export declare type ElementRef<T extends RefElementType = HTMLElement, P extends BindProps = BindProps> = {
type: 'element';
getBindingDefinition: (props: P) => ElementBinding<T, P>;
element: T | undefined;
refreshRefs: () => void;
};
export declare type CollectionRef<T extends RefElementType = HTMLElement, P extends BindProps = BindProps> = {
type: 'collection';
getBindingDefinition: (props: BindProps) => CollectionBinding<T, P>;
getElements: () => Array<T>;
getRefs: () => Array<Omit<ElementRef<T, P>, 'refreshRefs'>>;
refreshRefs: () => void;
};
export declare type ComponentRef<T extends ComponentFactory<any>> = {
type: 'component';
getBindingDefinition: (props: ComponentParams<ReturnType<T>>) => ComponentBinding<ReturnType<T>>;
component: ReturnType<T> | undefined;
refreshRefs: () => void;
};
export declare type ComponentsRef<T extends ComponentFactory<any>> = {
type: 'componentCollection';
getBindingDefinition: (props: ComponentParams<ReturnType<T>>) => ComponentCollectionBinding<ReturnType<T>>;
getComponents: () => Array<ReturnType<T>>;
getRefs: () => Array<Omit<ComponentRef<T>, 'refreshRefs'>>;
refreshRefs: () => void;
};
export declare type AnyRef<T extends RefElementType> = ElementRef<T> | CollectionRef<T> | ComponentRef<ComponentFactory<any>> | ComponentsRef<ComponentFactory<any>>;
export declare type RefOrValue<T extends Record<string, any>> = {
[P in keyof T]: Exclude<T[P], undefined> extends Function ? T[P] | Ref<T[P]> : Ref<T[P]>;
};
declare type ComponentElementParams = {
$element?: Pick<BindProps, 'css' | 'style' | 'attr' | 'event'>;
};
export declare type ComponentParams<T> = ComponentSetPropsParam<T> & ComponentElementParams;
/**
* Extracts the props from a component if it is one
* Otherwise just return the type itself.
*
* Partial is added because bindings are only meant to CHANGE things, not to SET things,
* so all props that are REQUIRED are set by the TEMPLATE already
*/
export declare type ComponentSetPropsParam<T> = T extends {
setProps(props: infer R): void;
} ? Partial<RefOrValue<R>> : Partial<RefOrValue<Record<string, any>>>;
/**
* Extract the type of ref it is based on the return type of the selector function from the definition
* Fall back to just a normal Element ref if a string is passed
*/
export declare type TypedRef<T extends ComponentRefItem> = T extends {
createRef: (instance: InternalComponentInstance) => infer R;
} ? Exclude<R, undefined> : ElementRef;
/**
* Extract typings out of the refDefinition input,
* so they can be used to type the refs passed in the setup function
*
* Attaches the 'self' ref to it, since it's always present
*/
export declare type TypedRefs<T extends Record<string, ComponentRefItem>> = {
[P in keyof T]: TypedRef<T[P]>;
} & {
self: ElementRef;
};
export {};