import {RHS, ToTransformer} from './types'; export type matchTypes = 'parts'| 'part' | 'id' | 'classes' | 'class' | 'attribs' | 'attrib' | 'elements' | 'element' | 'names' | 'name' | 'props' | 'placeholders'; export interface QueryInfo{ query: string; match: string; attrib?: string; lhsProp?: string; first?: boolean; verb?: string; havingAlso?: QueryInfo[]; havingInner?: QueryInfo; } export type PropSettings = HTMLElement, HostProps = any> = { [P in keyof T]?: keyof HostProps; }; export type EventSettings = {[key: string] : ((e: Event) => void) | string | INotify}; export interface IMinimalNotify{ nudge?: boolean; debug?: boolean; eventListenerOptions?: boolean | AddEventListenerOptions | undefined; doInit?: boolean; } export interface IDIYNotify extends IMinimalNotify{ doOnly?: (target: Element, key: string, mn: IMinimalNotify, e?: Event) => void; } export interface IValFromEventInstructions { /** * Hardcoded value to set on recipient element. */ val?: any /** * path to get value from target */ valFromTarget?: keyof TSelf; /** * path to get value from target */ vft?: keyof TSelf | `${keyof TSelf & string}.${string}`; /** * path to get value from event */ valFromEvent?: string; /** * path to get value from event */ vfe?: string; propName?: string; clone?: boolean; parseValAs?: 'int' | 'float' | 'bool' | 'date' | 'truthy' | 'falsy' | undefined | 'string' | 'object'; trueVal?: any; falseVal?: any; } export interface INotify extends IMinimalNotify, IValFromEventInstructions{ navTo?: string; /** * Pass property or invoke fn onto custom or built-in element hosting the contents of p-u element. */ //toHost: boolean; /** * Id of Dom Element. Uses import-like syntax: * ./my-id searches for #my-id within ShadowDOM realm of instance. * ../my-id searches for #my-id one ShadowDOM level up. * /my-id searches from outside any ShadowDOM. * @attr */ toUpShadow?: string; /** * abbrev of toUpShadow */ to?: string /** * Pass property or invoke fn onto itself */ toSelf?: boolean; /** * Pass property to the nearest previous sibling / ancestor element matching this css pattern, using .previousElement(s)/.parentElement.matches method. * Does not pass outside ShadowDOM realm. */ toNearestUpMatch?: string; toClosest?: string; /** * to closest or host ("itemscope" attribute or shadow DOM boundary) */ tocoho?: boolean | string; //to closest or host /** * Name of property to set on matching (upstream) element. * @attr */ prop?: keyof TProps & string; /** * Name of method or property arrow function to invoke on matching (upstream) element. */ fn?: keyof TActions & string; dispatch?: string; withArgs?: ('self' | 'val' | 'event')[]; plusEq?: boolean | string | number; eqConst?: any; toggleProp?: boolean; as?: 'str-attr' | 'bool-attr' | 'obj-attr', thenDo?: (target: Element, key: string, n: INotify, e?: Event) => void; } export interface INotifyHookupInfo{ controller: AbortController; } export interface IConditional = HTMLElement>{ /** * Name of property to check if truthy */ if?: keyof MCProps; /** * If condition value */ ifVal?: boolean; lhs?: string; lhsVal?: any; rhs?: string; rhsVal?: any; op?: '==' | '!=' | '>' | '<' | '>=' | '<=' | '===' | '!==' | undefined; } export type AttribsSettings = { [key: string]: string | boolean | number | undefined | null | string[]}; export type PSettings = HTMLElement, HostProps = any> = [PropSettings | undefined]; export type PESettings = HTMLElement> = [props: PropSettings | undefined, on: EventSettings | undefined]; export type PEUnionSettings = HTMLElement> = PSettings | PESettings; export type PEASettings = HTMLElement> = [props: PropSettings | undefined, events: EventSettings | undefined, attribs: AttribsSettings | undefined]; export type PEAUnionSettings = HTMLElement> = PEUnionSettings | PEASettings; export type ConditionalSettings = HTMLElement> = [boolean, IConditional, ...any] export interface TRElementProps { propChangeQueue?: Set; inReflectMode?: boolean; } export interface TRElementActions{ attachQR(): void; detachQR(): void; attributeChangedCallback?(n: string, ov: string, nv: string): void; } // export interface Transform extends LogicOp{ // match: {[key: string]: MatchRHS} // } export type MatchRHS = string; export interface HasPropChangeQueue{ propChangeQueue: Set | undefined; QR: undefined | ((name: string, self: HasPropChangeQueue) => void); } export interface ProxyPropChangeInfo{ oldVal: any, newVal: any, prop: string } export interface ITSChecker{ notChanged(host: Element, fragment: Element | DocumentFragment): boolean; } export type TargetTuple = /** * Use the native .closest() function to get the target */ | ['closest', string] /** * abbrev for closet */ | ['c', string] /** * Find nearest previous sibling, parent, previous sibling of parent, etc that matches this string. */ | ['upSearch', string] /** * abbrev for upSearch */ | ['us', string] /** * Tries .closest([string value]). * If that comes out to null, do .getRootNode().host */ | ['closestOrHost', string] /** * abbrev for closestOrHost */ | ['coh', string] /** * Find nearest previous element sibling that matches this string */ | ['previous', string] /** * Find first element matching string within root node. */ | ['withinRootNode', string] /** * abbrev for withinRootNode */ | ['wrn', string] /** * hostish */ | ['h', (boolean | string)?, boolean?] | ['hostish', (boolean | string)?, boolean?] /** * Find first element matching string within itemscope. */ | ['withinItemScope', string, boolean?] /** * abbrev for within item scope */ | ['wis', string, boolean?] | ['within', string, string] | ['wi', string, string] /** * First first element matching string within form. */ | ['withinForm', string] /** * abbrev for within form */ | ['wf', string] ; /** * Target selector in upward direction. */ export type Target = | TargetTuple /** * Use the parent element as the target */ | 'parent' /** * abbrev for parent */ | 'p' /** * Use the previous element sibling as the target. */ | 'previousElementSibling' /** * abbrev for previous element sibling. */ | 'pes' /** * Search previous element siblings for target that matches the query. */ | `previous${camelQry}` | /** * Use the parent as the target. If no parent, use root node. */ 'parentOrRootNode' | /** * abbrev for parent or root node */ 'porn' | /** * Do "closest" for element with "-"" in the name. If non found, get host of getRootNode() */ 'hostish' | /** * Use the element itself as the target */ 'self' | /** * abbrev for self */ 's' | `closest${camelQry}` | /** * [TODO] * do upsearch for matching itemref */ 'nearestScope' | /** * Find nearest previous sibling, parent, previous sibling of parent, etc that matches this string. */ `upSearchFor${camelQry}` | /** * Tries .closest matching string. If that's null, does .getRootNode().host */ `closest${camelQry}OrHost` | /** * Searches for first element within the rootNode that matches the camelQry. */ `${camelQry}WithinRootNode` | /** * get host */ 'host' | /** * abbrev for host */ 'h' ; export type ScopeTuple = TargetTuple /** * Similar to closestOrHost, but just get the root fragment via getRootNode() */ | ['closestOrRootNode', string] /** * abbrev for closestOrRootNode */ | ['corn', string] ; /** * Outer boundary for transformation */ export type Scope = Target | ScopeTuple | /** * use native function getRootNode() to set the target * */ 'rootNode' | /** * abbrev for rootNode */ 'rn' | `closest${camelQry}OrRootNode` | 'shadowDOM' | /** * abbrev for shadow DOM */ 'sd' ; //https://stackoverflow.com/questions/38123222/proper-way-to-declare-json-object-in-typescript type JSONValue = | string | number | boolean | null | JSONValue[] | {[key: string]: JSONValue} interface JSONObject { [k: string]: JSONValue } interface JSONArray extends Array {} export interface getValArg { host?: any; } export type keyOfCtxNavElement = keyof ICTXNavElement & string; export type keyofICTXCamelQryPrompt = `${keyof ICTXCamelQryPrompt & string}.${camelQry}`; export type keyofCTXNavRecursive = (keyof ICTXNavRecursive & string) | keyofICTXCamelQryPrompt; export type AffectOptions = `${keyOfCtxNavElement}` | `${keyofCTXNavRecursive}` | `${keyofCTXNavRecursive}.${keyofCTXNavRecursive}` //| `${keyofCTXNavRecursive}.${keyofCTXNavRecursive}.${keyofCTXNavRecursive}` // | `${keyofCTXNavRecursive}.${keyofCTXNavRecursive}.${keyofCTXNavRecursive}.${keyofCTXNavRecursive}` ; export interface ICTXNavRecursive{ $?: T; hostCtx?: T; } /** * E = element * P = part * C = class * I = itemscope * A = attribute * N = name */ export type camelQry = `${string}E` | `${string}P` | `${string}C` | `${string}Id` | `${string}I` | `${string}A` | `${string}N` | `${string}M`; export interface ExpectedCamelQry{ [key: camelQry] : ICtxNav } export interface ICTXNavElement{ self?: Element; host?: Element; } export interface ICTXCamelQryPrompt{ ancestor?: ExpectedCamelQry; elder?: ExpectedCamelQry; } export interface ICtxNav extends ICTXNavRecursive, ICTXNavElement, ICTXCamelQryPrompt { beScoped?: EventTarget; xtalState(): Promise; } export type ConvertOptions = 'bool' | 'int' | 'float' | 'date' | 'truthy' | 'falsy' | 'string' | 'object' | 'regExp' | 'number';