/** * @module component-one-file.mts contains all the types, helpers, constants and * classes for the **shell** ui component system. the differentiating factor * between this system and other front end ui frameworks is that this is * ibgib-driven, with especially ibgib addresses driving components' backing * model/data. * * this is not to be confused with "components" that may be dynamically * generated within a blank-canvas environment that the canvas agents will * build. this is for the old-school html shell. * * the ui component system is being built piecemeal as we go. * * ## approach * * there are two basic pieces to a component: the component metadata declaration * and the concrete component instance that that declaration instantiates. these * will be tightly coupled per use-case, with the intention that the meta object * will not need to be a descendant class, whereas the component instance will * most likely be the class that is extended from an abstract base class. * * @see {@link IbGibDynamicComponentMeta} * @see {@link IbGibDynamicComponentInstance} */ import { Gib, Ib, IbGibAddr, TjpIbGibAddr } from "@ibgib/ts-gib/dist/types.mjs"; import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs"; import { MetaspaceService } from "@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs"; import { LiveProxyIbGib } from "../../witness/live-proxy-ibgib/live-proxy-ibgib-one-file.mjs"; import { AgentWitnessAny } from "../../witness/agent/agent-one-file.mjs"; import { ElementsBase, FnHandleRouteType, IbGibDynamicComponentInstance, IbGibDynamicComponentInstanceInitOpts, IbGibDynamicComponentMeta, ChildInfoBase, IbGibDynamicComponentMetaCtorOpts, ComponentMetaspaceScope } from "./component-types.mjs"; import { IbGibSettings, SettingsIbGib_V1, SettingsWithTabs } from "../../common/settings/settings-types.mjs"; import { SettingsType } from "../../common/settings/settings-constants.mjs"; /** * Base class for the ibgib component Meta factory instance. * * @see {@link IbGibDynamicComponentMeta} */ export declare abstract class IbGibDynamicComponentMetaBase implements IbGibDynamicComponentMeta { protected lc: string; componentName: string; routeRegExp?: RegExp | undefined; fnHandleRoute?: FnHandleRouteType | undefined; fnGetMetaspace: () => Promise; bootstrapPromise: Promise; abstract createInstance(arg: { path: string; ibGibAddr: IbGibAddr; }): Promise; /** * ## usage * * I'm planning on creating a single ctor opts instance for this with the * properties exposed on the consuming app's global ibgib object, which * should have references to these properties. * * Then, the component meta initialization can be the same as it is atow * (12/2025), but instead of empty ctors it will just have the `opts` there. * * ``` * const opts = { * fnGetMetaspace: globalIbGib.getGlobalMetaspace, * bootstrapPromise: globalIbGib.bootstrapPromise, * } * * const componentsMeta: IbGibDynamicComponentMeta[] = [ * new MyComponentMeta1(opts), * new MyComponentMeta2(opts), * // other components * ]; * ``` */ constructor({ fnGetMetaspace, bootstrapPromise, }: IbGibDynamicComponentMetaCtorOpts); } /** * Base class for common ibgib component. This is the actual web component * instance. * * ## regarding HTMLElement * * This class extends HTMLElement, so you have access to things, e.g., the * parent element via the normal DOM interface. * * @see {@link IbGibDynamicComponentInstance} */ export declare abstract class IbGibDynamicComponentInstanceBase extends HTMLElement implements IbGibDynamicComponentInstance { protected lc: string; elements: TElements | undefined; createdPromise: Promise | undefined; settings: LiveProxyIbGib | undefined; /** * main agent for this component * * atow (04/2025), this is derived from {@link agents}, being the first one * in that array. So, other agents may exist for this component, but the * first one should be the main one for this component. */ get agent(): AgentWitnessAny | undefined; /** * @see {@link agent} */ agents: AgentWitnessAny[]; get ib(): Ib; get gib(): Gib; ibGibAddr: IbGibAddr; /** * The proxy witness used for updating the backing ibGib. */ ibGibProxy: LiveProxyIbGib | undefined; /** * Backing ibgib getter via {@link ibGibProxy.ibGib} */ get ibGib(): TIbGib | undefined; get tjpAddr(): TjpIbGibAddr | undefined; /** * reference to the meta instance that created this component instance. */ meta: IbGibDynamicComponentMeta | undefined; html: string | undefined; css: string[] | undefined; /** * not really used yet, since we're only testing with web1 which has a * static, primitive ibgib address. */ static get observedAttributes(): string[]; _instanceId: string; get instanceId(): string; /** * we can initialize the agent(s) as soon as we load the ibgib, but we don't * want to await it immediately. */ agentsInitialized: Promise | undefined; /** * @internal number of times {@link connectedCallback} has been called. * * ## notes * * I'm making this because when the component is removed */ protected connectedCount: number; protected _isBusy: boolean; /** * Indicates whether the component is currently performing an asynchronous operation. */ get isBusy(): boolean; /** * Updates the component's busy state, disabling elements and triggering events. * Dispatches `EVENT_IBGIB_UI_BUSY` locally on the component and globally on the window. */ protected showBusy({ isBusy, title, msg, localOnly, animationEmoji, }: { isBusy: boolean; title?: string; msg?: string; localOnly?: boolean; animationEmoji?: string; }): void; /** * Determines which metaspace this component uses. Default is * `execution` (the active mode's metaspace). Mode-agnostic components * (e.g. identity) override with `persistent`. */ protected metaspaceScope: ComponentMetaspaceScope; protected getMetaspace(): Promise; constructor(); initialize(opts: IbGibDynamicComponentInstanceInitOpts): Promise; protected initAgents(): Promise; connectedCallback(): Promise; protected connectedCallback_initComponent(): Promise; protected connectedCallback_reconnectComponent(): Promise; disconnectedCallback(): Promise; /** * untested so far. * * @param name * @param oldValue * @param newValue */ attributeChangedCallback(name: string, oldValue: any, newValue: any): Promise; abstract created(): Promise; abstract disconnected(): Promise; /** * triggers {@link destroyed} handler * * Note there are NO web component lifecycles that trigger this. This must * be called explicitly in code. * @see {@link disconnected} * @see {@link disconnectedCallback} */ destroy(): Promise; destroyed(): Promise; loadIbGib(opts?: { getLatest?: boolean; }): Promise; /** * Determines whether {@link handleContextUpdated} automatically calls {@link renderUI}. * Defaults to true so components automatically react and rerender when their backing * timeline evolves. Override and return false if custom granular DOM updating is desired. */ protected get shouldAutoRenderOnContextUpdated(): boolean; /** * in base class, this sets {@link ibGibAddr} to reflect the {@link nextIbGib}. * If {@link shouldAutoRenderOnContextUpdated} is true, automatically triggers {@link renderUI}. * * override this in child classes to do more when next context happens * * @see {@link handleNewContextChild} */ protected handleContextUpdated(): Promise; /** * does nothing (atow 04/2025) in base class * * override this to handle new children on {@link ibGibProxy} * @see {@link handleContextUpdated} */ protected handleNewContextChild({ childIbGib }: { childIbGib: IbGib_V1; }): Promise; /** * updates and renders the visual part of the component. */ protected renderUI(): Promise; protected renderUI_busy(): Promise; /** * loads the agent(s) coupled to the domain ibgib (this.ibGib), if any. */ protected loadAgentsCoupledToIbGib({ dontThrowIfNone, }?: { /** * most components have an agent. set this to true if the component is small enough to NOT have an agent. */ dontThrowIfNone?: boolean; }): Promise; /** * Gets the settings section. * * NOTE: this.settings and this.settings.ibGib must be initialized before * calling this, else will throw. * * @returns settings section corresponding to type/use case or undefined * * ## notes on settings * * AFAICT I have made this so that there is one single settings ibgib with * individual sections in its data. So use this function to get a section * within that settings ibgib that is based on a given domain ibgib (this.ibGib). * * So a component initializes/activates an ibGib (this.ibGib) and for those * components that use the settings, this.initSettings must be called. Then * you call getSettings or updateSettings (not implemented yet). */ protected getSettings({ settingsType, useCase, }: { settingsType: SettingsType; useCase: "current" | string; }): Promise; protected updateSettings({ settingsType, useCase, newSectionInfo, }: { settingsType: SettingsType; useCase: "current" | string; newSectionInfo: TSettings; }): Promise; /** * if this.ibGib has a coupled settings ibgib indexed in the local space, * then {@link settings} should be loaded with it. This is a convenience * fn to access the current settings section for the {@link settingsType}. */ protected getCurrentSettings({ settingsType }: { settingsType: SettingsType; }): Promise; protected initSettings(): Promise; /** * exports a given ibgib to the default local userspace in the metaspace. */ protected exportIbGib({ ibGib, compress, }: { ibGib: IbGib_V1; compress: boolean; }): Promise; /** * imports a given ibgib into this.ibGib's */ protected importIbGib({ exportIbGibJsonString, rel8nName, force, skipRegisterTimelines, divergentTimelineStrategy, }: { /** * this is the contents of the export save file which should have been created with {@link exportIbGib} */ exportIbGibJsonString: string; /** * named edge that we'll rel8 the ibGib in {@link exportIbGibJsonString} * to {@link ibGib}. */ rel8nName: string; /** * if true, will add rel8n even if already rel8d. */ force?: boolean; /** * if true, will not call metaspace.registerNew on imported timelines. * * ## notes * * may be yagni but meh, i see it as a distinct possibility when * importing that we just want to bring ibgibs in. */ skipRegisterTimelines?: boolean; /** * If */ divergentTimelineStrategy: 'supercede-timeline' | 'keep-existing-timeline' | 'optimistic-merge' | 'throw-error'; }): Promise; } /** * Common plumbing for any component that is meant to contain other ibgib * components as children. */ export declare abstract class IbGibDynamicComponentInstanceBase_Parent = ChildInfoBase> extends IbGibDynamicComponentInstanceBase { /** * @internal * @protected method that gets the project tab info for the given addr. * * creates and loads the child ibgib component, which itself loads the * ibgib internally (or throws) if not already loaded. * * @returns TChildInfo with fully loaded component and ibgib. */ protected abstract getLoadedChildInfo({ addr, ibGib, }: { addr: IbGibAddr; ibGib?: IbGib_V1; }): Promise; childInfos: TChildInfo[]; get activeChildInfo(): TChildInfo | undefined; /** * Drives loading a child component from an {@link ibGibAddr} or {@link ibGib}. * * - If a tab is already created for the ibgib and active, then does nothing. * - If it's already created but inactive, then activates tab and loads content * - if no tab, then creates it, activates it, loads content. * * To do this, creates/hydrates a concrete descendant of {@link ChildInfoBase} * and activates it via {@link getLoadedChildInfo} * * @see {@link ChildInfoBase.active} * @see {@link activeChildInfo} */ activateIbGib({ ibGibAddr, ibGib, }: { ibGibAddr?: IbGibAddr; ibGib?: IbGib_V1; }): Promise; protected abstract addChild({ addr, ibGib, }: { ibGib: IbGib_V1; addr?: IbGibAddr; }): Promise; } export declare abstract class IbGibDynamicComponentInstanceBase_ParentOfTabs = ChildInfoBase> extends IbGibDynamicComponentInstanceBase_Parent { protected lc: string; get isBusy(): boolean; protected abstract get settingsType(): SettingsType; protected _reloadingTabs: boolean; protected get reloadingTabs(): boolean; protected set reloadingTabs(value: boolean); protected closeTab({ ibGib }: { ibGib: IbGib_V1; }): Promise; protected abstract removeTabBtn({ tabInfo, }: { tabInfo: TChildInfo; }): Promise; protected reopenOldTabs(): Promise; } /** * Intermediate abstract base class designed for dynamic interactive form elements. * Provides standard wrappers for constraint validation, busy states, status reporting, * and boundary-crossing shell notification events. */ export declare abstract class IbGibFormInstanceBase extends IbGibDynamicComponentInstanceBase { /** * Updates the form's submit/generate button visual loading state. * Disables the button, sets custom loading text, and marks it with data attributes * during loading; restores the original text and removes attributes when complete. */ protected setLoading(loading: boolean, submitBtnSelector?: string, loadingText?: string): void; protected setStatus(msg: string, type: 'info' | 'success' | 'error', statusAreaId?: string, statusTextId?: string): void; protected dispatchShellMessage(message: string, level: 'info' | 'success' | 'warning' | 'error'): void; protected validateForm(formSelector?: string): boolean; /** * Validates a given input element's value against a RegExp pattern. * Marks the input element with the 'invalid' class and sets a custom validity message if invalid. */ protected validateInputPattern({ input, pattern, errorMessage, required, }: { input: HTMLInputElement | HTMLTextAreaElement | null; pattern: RegExp; errorMessage: string; required?: boolean; }): boolean; /** * Overrides base component showBusy to handle form-specific side-effects * (e.g. disabling form inputs, setting submit button loading state) * before delegating to the base class event dispatchers. */ protected showBusy({ isBusy, title, msg, localOnly, submitBtnSelector, loadingText, animationEmoji, }: { isBusy: boolean; title?: string; msg?: string; localOnly?: boolean; submitBtnSelector?: string; loadingText?: string; animationEmoji?: string; }): void; private toggleAllInputsDisabled; } //# sourceMappingURL=ibgib-dynamic-component-bases.d.mts.map