@api-client/ui 0.5.35 → 0.5.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -217,12 +217,12 @@ let Fragment = (() => {
217
217
  * Application or parent Fragment will handle rendering.
218
218
  */
219
219
  requestUpdate(opts = {}) {
220
- const { fragment = true } = opts;
221
- if (fragment) {
222
- this.#renderer.requestUpdate();
220
+ if (opts.fragment !== false) {
221
+ this.renderer.requestUpdate();
222
+ }
223
+ if (this.parent && (opts.activity || opts.app)) {
224
+ this.parent.requestUpdate(opts);
223
225
  }
224
- this.parent?.requestUpdate(opts);
225
- // If no parent, do nothing (or maybe throw an error?)
226
226
  }
227
227
  getApplication() {
228
228
  return this.parent?.getApplication();
@@ -1 +1 @@
1
- {"version":3,"file":"Fragment.js","sourceRoot":"","sources":["../../../src/core/Fragment.ts"],"names":[],"mappings":"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","sourcesContent":["import { nothing, TemplateResult } from 'lit'\nimport { Activity } from './Activity.js'\nimport { FragmentState, type FragmentOptions, FragmentManager } from './FragmentManager.js'\nimport type { Application, UpdateRequest } from './Application.js'\nimport { FragmentRenderer } from './renderer/FragmentRenderer.js'\nimport { Intent, IntentResult } from './ActivityManager.js'\nimport { bound } from '../decorators/bound.js'\nimport type { ActivityDetail, ActivityWithResultDetail } from '../events/IntentEvents.js'\nimport { EventTypes } from '../events/EventTypes.js'\nimport { type RefOrCallback } from 'lit/directives/ref.js'\n\nexport interface PendingActivityResult {\n onResult(result: IntentResult, intent: Intent): void\n}\n\n/**\n * Similar to Activity, with lifecycle methods (onCreate, onAttach, onDetach, etc.).\n * The crucial difference is that a Fragment is always hosted by an `Activity` or\n * another `Fragment`.\n *\n * A `Fragment` represents a reusable portion of the app's UI.\n * A fragment defines and manages its own layout, has its own lifecycle,\n * and can handle its own input events.\n * Fragments can't live on their own. They must be hosted by an activity or another\n * fragment. The fragment’s view hierarchy becomes part of, or attaches to,\n * the host’s view hierarchy.\n */\nexport class Fragment extends EventTarget {\n public state: FragmentState = FragmentState.Initialized\n public parent?: Activity | Fragment\n protected children = new Map<string, Fragment>()\n protected fragmentManager: FragmentManager\n\n /**\n * The request code used to start an activity for a result.\n */\n requestCode = -1\n\n /**\n * A list of pending activity results that were requested by the components\n * hosted in this fragment.\n * The key is the request code and the value contains the callback\n * that will be called when the activity result is received.\n * The callback is called with the result code and the resulting intent.\n */\n pendingActivityResult: Map<number, PendingActivityResult> = new Map<number, PendingActivityResult>()\n\n #renderer: FragmentRenderer\n\n get renderer(): FragmentRenderer {\n return this.#renderer\n }\n\n constructor(options?: FragmentOptions) {\n super()\n this.parent = options?.parent\n this.fragmentManager = new FragmentManager(this)\n this.#renderer = new FragmentRenderer(this)\n }\n\n /**\n * When implemented, this method returns the class name to be used as a root class for the fragment.\n * This class name can be used to apply styles or identify the fragment in the DOM.\n * @returns The class name to be used as a root class for the fragment.\n */\n public rootClass(): string | undefined {\n return undefined\n }\n\n /**\n * @see {@link ./Renderer.js}\n */\n public setRenderRoot(renderRoot: HTMLElement | string): void {\n this.#renderer.setRenderRoot(renderRoot)\n }\n\n onData(data: unknown): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:data', { detail: data }))\n }\n\n /**\n * Called once when the fragment is created.\n *\n * In the `onCreate()` method, perform basic fragment startup logic that happens only once\n * for the entire life of the fragment.\n * @param data Optional init data.\n */\n onCreate(data?: unknown): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:create', { detail: data }))\n }\n\n /**\n * Called when the fragment is attached to a parent\n */\n onAttach(data?: unknown): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:attach', { detail: data }))\n }\n\n /**\n * Called when the fragment becomes visible.\n */\n onStart(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:start', { detail: null }))\n }\n\n /**\n * Called when the fragment gains focus.\n */\n onResume(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:resume', { detail: null }))\n }\n\n /**\n * Called when the fragment loses focus.\n */\n onPause(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:pause', { detail: null }))\n }\n\n /**\n * Called when the fragment is no longer visible.\n */\n onStop(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:stop', { detail: null }))\n }\n\n /**\n * Called when the fragment is detached from a parent\n */\n onDetach(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:detach', { detail: null }))\n }\n\n /**\n * Called before the fragment is destroyed.\n */\n onDestroy(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:destroy', { detail: null }))\n this.fragmentManager.onDestroy()\n }\n\n /**\n * Called by the renderer when the fragment is rendered for the first time.\n */\n onFirstRender(): void {\n //\n }\n\n /**\n * A function called when it should render the view.\n * By default it renders a fragment view if the fragment hosts other fragments and only one is visible.\n */\n render(): TemplateResult | typeof nothing {\n const fragment = this.getSingleVisibleFragment()\n if (fragment) {\n // we can manage the default rendering.\n // we make an assumption that by default only one fragment is rendered,\n // otherwise the parent activity or fragment would have to setup render roots.\n return fragment.render()\n }\n return nothing\n }\n\n /**\n * Checks whether there's only one `Fragment` that is in the `Resumed` state\n * and returns it. It returns `null` if there is no `Fragment`s or more than a single\n * visible `Fragment`.\n * @returns A Fragment that is the only fragment that should be visible.\n */\n getSingleVisibleFragment(): Fragment | null {\n const fragments = this.getVisibleFragments()\n return fragments.length === 1 ? fragments[0] : null\n }\n\n /**\n * Checks whether this fragment is a host for other fragments.\n * @returns `true` when this fragment hosts other fragments.\n */\n isRenderingFragments(): boolean {\n return this.children.size > 0\n }\n\n /**\n * @returns The list of all fragments that are in the Resumed state.\n */\n getVisibleFragments(): Fragment[] {\n return this.fragmentManager.getVisible()\n }\n\n /**\n * Adds a child fragment to this fragment.\n * The FragmentManager will handle lifecycle.\n * @param key The name of the fragment.\n * @param fragment The fragment to add.\n */\n async addChild(key: string, fragment: Fragment, data?: unknown): Promise<void> {\n this.children.set(key, fragment)\n await this.fragmentManager.attachFragment(key, fragment, this, data)\n }\n\n /**\n * Removes a fragment from this fragment.\n * @param key The name of the fragment to remove.\n */\n async removeChild(key: string): Promise<void> {\n const child = this.children.get(key)\n if (child) {\n await this.fragmentManager.detachFragment(key)\n this.children.delete(key)\n }\n }\n\n /**\n * Creates a RefCallback that can be used with lit's `ref()` directive\n * to automatically show/hide a child fragment when its container element\n * is added or removed from the DOM.\n *\n * @param key The key of the child fragment to manage.\n * @returns A RefCallback to be used with the `ref()` directive.\n *\n * @example\n * // In your parent fragment's render method:\n * html`<div ${ref(this.createFragmentRef('my-child-fragment'))}></div>`\n */\n createFragmentRef(key: string): RefOrCallback<Element> {\n return (element?: Element) => {\n if (element) {\n this.fragmentManager.showFragment(key, element as HTMLElement)\n } else {\n const fragment = this.fragmentManager.findFragment(key)\n if (fragment) {\n this.fragmentManager.hideFragment(fragment)\n }\n }\n }\n }\n\n /**\n * A helper to request an update.\n * Application or parent Fragment will handle rendering.\n */\n requestUpdate(opts: UpdateRequest = {}): void {\n const { fragment = true } = opts\n if (fragment) {\n this.#renderer.requestUpdate()\n }\n this.parent?.requestUpdate(opts)\n // If no parent, do nothing (or maybe throw an error?)\n }\n\n getApplication(): Application | undefined {\n return this.parent?.getApplication()\n }\n\n getActivity(): Activity | undefined {\n return this.parent?.getActivity()\n }\n\n /**\n * Starts an activity for result.\n * @param intent The intent to start.\n */\n async startActivityForResult(intent: Intent): Promise<void> {\n const activity = this.getActivity()\n if (!activity) {\n throw new Error(`The fragment has no activity. Unable to start an intent.`)\n }\n this.requestCode = await activity.startActivityForResult(intent)\n }\n\n /**\n * Starts another activity.\n * @param intent The intent to start.\n */\n async startActivity(intent: Intent): Promise<void> {\n const activity = this.getActivity()\n if (!activity) {\n throw new Error(`The fragment has no activity. Unable to start an intent.`)\n }\n await activity.startActivity(intent)\n }\n\n /**\n * The callback method that is triggered when another activity that was\n * started for result finishes.\n *\n * @param requestCode The request code that was used to start the activity.\n * @param data The data that was passed back.\n * @param intent The intent that was used to start the activity.\n */\n async onActivityResult(requestCode: number, resultCode: IntentResult, intent: Intent): Promise<void> {\n const { pendingActivityResult, children } = this\n if (pendingActivityResult.has(requestCode)) {\n const { onResult } = pendingActivityResult.get(requestCode) as PendingActivityResult\n pendingActivityResult.delete(requestCode)\n onResult(resultCode, intent)\n return\n }\n for (const fragment of children.values()) {\n if (fragment.hasRequestCode(requestCode)) {\n fragment.onActivityResult(requestCode, resultCode, intent)\n return\n }\n }\n this.requestCode = -1\n if (this.constructor === Fragment) {\n // eslint-disable-next-line no-console\n console.info('Fragment#onActivityResult() not implemented', requestCode, resultCode, intent)\n }\n }\n\n hasRequestCode(requestCode: number): boolean {\n for (const fragment of this.children.values()) {\n if (fragment.hasRequestCode(requestCode)) {\n return true\n }\n }\n return this.requestCode === requestCode\n }\n\n /**\n * A handler for the intent event dispatched by web components hosted by this fragment.\n *\n * **Usage example:**\n *\n * ```ts\n * <custom-element @startactivity=\"${this.handleIntentEvent}\"></custom-element>\n * <custom-element @startactivityforresult=\"${this.handleIntentEvent}\"></custom-element>\n * ```\n *\n * @param event The event that was dispatched.\n * @returns A promise that resolves when the intent is handled.\n * @throws An error if the fragment has no activity.\n * @throws An error if the event type is not recognized.\n */\n @bound\n async handleIntentEvent(event: CustomEvent<ActivityDetail | ActivityWithResultDetail>): Promise<void> {\n const activity = this.getActivity()\n if (!activity) {\n throw new Error(`The fragment has no activity. Unable to start an intent.`)\n }\n if (event.type === EventTypes.Intent.startActivityForResult) {\n const info = event.detail as ActivityWithResultDetail\n const code = await activity.startActivityForResult(info.intent)\n this.requestCode = code\n this.pendingActivityResult.set(code, {\n onResult: info.onResult,\n })\n } else if (event.type === EventTypes.Intent.startActivity) {\n await activity.startActivity(event.detail.intent)\n } else {\n throw new Error(`Unrecognized intent event: ${event.type}`)\n }\n }\n}\n"]}
1
+ {"version":3,"file":"Fragment.js","sourceRoot":"","sources":["../../../src/core/Fragment.ts"],"names":[],"mappings":"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","sourcesContent":["import { nothing, TemplateResult } from 'lit'\nimport { Activity } from './Activity.js'\nimport { FragmentState, type FragmentOptions, FragmentManager } from './FragmentManager.js'\nimport type { Application, UpdateRequest } from './Application.js'\nimport { FragmentRenderer } from './renderer/FragmentRenderer.js'\nimport { Intent, IntentResult } from './ActivityManager.js'\nimport { bound } from '../decorators/bound.js'\nimport type { ActivityDetail, ActivityWithResultDetail } from '../events/IntentEvents.js'\nimport { EventTypes } from '../events/EventTypes.js'\nimport { type RefOrCallback } from 'lit/directives/ref.js'\n\nexport interface PendingActivityResult {\n onResult(result: IntentResult, intent: Intent): void\n}\n\n/**\n * Similar to Activity, with lifecycle methods (onCreate, onAttach, onDetach, etc.).\n * The crucial difference is that a Fragment is always hosted by an `Activity` or\n * another `Fragment`.\n *\n * A `Fragment` represents a reusable portion of the app's UI.\n * A fragment defines and manages its own layout, has its own lifecycle,\n * and can handle its own input events.\n * Fragments can't live on their own. They must be hosted by an activity or another\n * fragment. The fragment’s view hierarchy becomes part of, or attaches to,\n * the host’s view hierarchy.\n */\nexport class Fragment extends EventTarget {\n public state: FragmentState = FragmentState.Initialized\n public parent?: Activity | Fragment\n protected children = new Map<string, Fragment>()\n protected fragmentManager: FragmentManager\n\n /**\n * The request code used to start an activity for a result.\n */\n requestCode = -1\n\n /**\n * A list of pending activity results that were requested by the components\n * hosted in this fragment.\n * The key is the request code and the value contains the callback\n * that will be called when the activity result is received.\n * The callback is called with the result code and the resulting intent.\n */\n pendingActivityResult: Map<number, PendingActivityResult> = new Map<number, PendingActivityResult>()\n\n #renderer: FragmentRenderer\n\n get renderer(): FragmentRenderer {\n return this.#renderer\n }\n\n constructor(options?: FragmentOptions) {\n super()\n this.parent = options?.parent\n this.fragmentManager = new FragmentManager(this)\n this.#renderer = new FragmentRenderer(this)\n }\n\n /**\n * When implemented, this method returns the class name to be used as a root class for the fragment.\n * This class name can be used to apply styles or identify the fragment in the DOM.\n * @returns The class name to be used as a root class for the fragment.\n */\n public rootClass(): string | undefined {\n return undefined\n }\n\n /**\n * @see {@link ./Renderer.js}\n */\n public setRenderRoot(renderRoot: HTMLElement | string): void {\n this.#renderer.setRenderRoot(renderRoot)\n }\n\n onData(data: unknown): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:data', { detail: data }))\n }\n\n /**\n * Called once when the fragment is created.\n *\n * In the `onCreate()` method, perform basic fragment startup logic that happens only once\n * for the entire life of the fragment.\n * @param data Optional init data.\n */\n onCreate(data?: unknown): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:create', { detail: data }))\n }\n\n /**\n * Called when the fragment is attached to a parent\n */\n onAttach(data?: unknown): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:attach', { detail: data }))\n }\n\n /**\n * Called when the fragment becomes visible.\n */\n onStart(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:start', { detail: null }))\n }\n\n /**\n * Called when the fragment gains focus.\n */\n onResume(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:resume', { detail: null }))\n }\n\n /**\n * Called when the fragment loses focus.\n */\n onPause(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:pause', { detail: null }))\n }\n\n /**\n * Called when the fragment is no longer visible.\n */\n onStop(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:stop', { detail: null }))\n }\n\n /**\n * Called when the fragment is detached from a parent\n */\n onDetach(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:detach', { detail: null }))\n }\n\n /**\n * Called before the fragment is destroyed.\n */\n onDestroy(): void | Promise<void> {\n this.dispatchEvent(new CustomEvent('fragment:destroy', { detail: null }))\n this.fragmentManager.onDestroy()\n }\n\n /**\n * Called by the renderer when the fragment is rendered for the first time.\n */\n onFirstRender(): void {\n //\n }\n\n /**\n * A function called when it should render the view.\n * By default it renders a fragment view if the fragment hosts other fragments and only one is visible.\n */\n render(): TemplateResult | typeof nothing {\n const fragment = this.getSingleVisibleFragment()\n if (fragment) {\n // we can manage the default rendering.\n // we make an assumption that by default only one fragment is rendered,\n // otherwise the parent activity or fragment would have to setup render roots.\n return fragment.render()\n }\n return nothing\n }\n\n /**\n * Checks whether there's only one `Fragment` that is in the `Resumed` state\n * and returns it. It returns `null` if there is no `Fragment`s or more than a single\n * visible `Fragment`.\n * @returns A Fragment that is the only fragment that should be visible.\n */\n getSingleVisibleFragment(): Fragment | null {\n const fragments = this.getVisibleFragments()\n return fragments.length === 1 ? fragments[0] : null\n }\n\n /**\n * Checks whether this fragment is a host for other fragments.\n * @returns `true` when this fragment hosts other fragments.\n */\n isRenderingFragments(): boolean {\n return this.children.size > 0\n }\n\n /**\n * @returns The list of all fragments that are in the Resumed state.\n */\n getVisibleFragments(): Fragment[] {\n return this.fragmentManager.getVisible()\n }\n\n /**\n * Adds a child fragment to this fragment.\n * The FragmentManager will handle lifecycle.\n * @param key The name of the fragment.\n * @param fragment The fragment to add.\n */\n async addChild(key: string, fragment: Fragment, data?: unknown): Promise<void> {\n this.children.set(key, fragment)\n await this.fragmentManager.attachFragment(key, fragment, this, data)\n }\n\n /**\n * Removes a fragment from this fragment.\n * @param key The name of the fragment to remove.\n */\n async removeChild(key: string): Promise<void> {\n const child = this.children.get(key)\n if (child) {\n await this.fragmentManager.detachFragment(key)\n this.children.delete(key)\n }\n }\n\n /**\n * Creates a RefCallback that can be used with lit's `ref()` directive\n * to automatically show/hide a child fragment when its container element\n * is added or removed from the DOM.\n *\n * @param key The key of the child fragment to manage.\n * @returns A RefCallback to be used with the `ref()` directive.\n *\n * @example\n * // In your parent fragment's render method:\n * html`<div ${ref(this.createFragmentRef('my-child-fragment'))}></div>`\n */\n createFragmentRef(key: string): RefOrCallback<Element> {\n return (element?: Element) => {\n if (element) {\n this.fragmentManager.showFragment(key, element as HTMLElement)\n } else {\n const fragment = this.fragmentManager.findFragment(key)\n if (fragment) {\n this.fragmentManager.hideFragment(fragment)\n }\n }\n }\n }\n\n /**\n * A helper to request an update.\n * Application or parent Fragment will handle rendering.\n */\n requestUpdate(opts: UpdateRequest = {}): void {\n if (opts.fragment !== false) {\n this.renderer.requestUpdate()\n }\n if (this.parent && (opts.activity || opts.app)) {\n this.parent.requestUpdate(opts)\n }\n }\n\n getApplication(): Application | undefined {\n return this.parent?.getApplication()\n }\n\n getActivity(): Activity | undefined {\n return this.parent?.getActivity()\n }\n\n /**\n * Starts an activity for result.\n * @param intent The intent to start.\n */\n async startActivityForResult(intent: Intent): Promise<void> {\n const activity = this.getActivity()\n if (!activity) {\n throw new Error(`The fragment has no activity. Unable to start an intent.`)\n }\n this.requestCode = await activity.startActivityForResult(intent)\n }\n\n /**\n * Starts another activity.\n * @param intent The intent to start.\n */\n async startActivity(intent: Intent): Promise<void> {\n const activity = this.getActivity()\n if (!activity) {\n throw new Error(`The fragment has no activity. Unable to start an intent.`)\n }\n await activity.startActivity(intent)\n }\n\n /**\n * The callback method that is triggered when another activity that was\n * started for result finishes.\n *\n * @param requestCode The request code that was used to start the activity.\n * @param data The data that was passed back.\n * @param intent The intent that was used to start the activity.\n */\n async onActivityResult(requestCode: number, resultCode: IntentResult, intent: Intent): Promise<void> {\n const { pendingActivityResult, children } = this\n if (pendingActivityResult.has(requestCode)) {\n const { onResult } = pendingActivityResult.get(requestCode) as PendingActivityResult\n pendingActivityResult.delete(requestCode)\n onResult(resultCode, intent)\n return\n }\n for (const fragment of children.values()) {\n if (fragment.hasRequestCode(requestCode)) {\n fragment.onActivityResult(requestCode, resultCode, intent)\n return\n }\n }\n this.requestCode = -1\n if (this.constructor === Fragment) {\n // eslint-disable-next-line no-console\n console.info('Fragment#onActivityResult() not implemented', requestCode, resultCode, intent)\n }\n }\n\n hasRequestCode(requestCode: number): boolean {\n for (const fragment of this.children.values()) {\n if (fragment.hasRequestCode(requestCode)) {\n return true\n }\n }\n return this.requestCode === requestCode\n }\n\n /**\n * A handler for the intent event dispatched by web components hosted by this fragment.\n *\n * **Usage example:**\n *\n * ```ts\n * <custom-element @startactivity=\"${this.handleIntentEvent}\"></custom-element>\n * <custom-element @startactivityforresult=\"${this.handleIntentEvent}\"></custom-element>\n * ```\n *\n * @param event The event that was dispatched.\n * @returns A promise that resolves when the intent is handled.\n * @throws An error if the fragment has no activity.\n * @throws An error if the event type is not recognized.\n */\n @bound\n async handleIntentEvent(event: CustomEvent<ActivityDetail | ActivityWithResultDetail>): Promise<void> {\n const activity = this.getActivity()\n if (!activity) {\n throw new Error(`The fragment has no activity. Unable to start an intent.`)\n }\n if (event.type === EventTypes.Intent.startActivityForResult) {\n const info = event.detail as ActivityWithResultDetail\n const code = await activity.startActivityForResult(info.intent)\n this.requestCode = code\n this.pendingActivityResult.set(code, {\n onResult: info.onResult,\n })\n } else if (event.type === EventTypes.Intent.startActivity) {\n await activity.startActivity(event.detail.intent)\n } else {\n throw new Error(`Unrecognized intent event: ${event.type}`)\n }\n }\n}\n"]}
@@ -76,7 +76,7 @@ export declare class FragmentManager {
76
76
  /**
77
77
  * Hides a Fragment (calls lifecycle methods and removes from DOM if necessary)
78
78
  */
79
- hideFragment(fragment: Fragment): Promise<void>;
79
+ hideFragment(fragment: Fragment | string): Promise<void>;
80
80
  findFragment(key: string): Fragment | undefined;
81
81
  renderFragment(key: string): TemplateResult | typeof nothing;
82
82
  updateActiveFragments(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"FragmentManager.d.ts","sourceRoot":"","sources":["../../../src/core/FragmentManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,oBAAY,aAAa;IACvB,WAAW,IAAA;IACX,OAAO,IAAA;IACP,QAAQ,IAAA,CAAE,mCAAmC;IAC7C,OAAO,IAAA,CAAE,UAAU;IACnB,OAAO,IAAA,CAAE,YAAY;IACrB,MAAM,IAAA;IACN,OAAO,IAAA,CAAE,oBAAoB;IAC7B,QAAQ,IAAA,CAAE,uCAAuC;IACjD,SAAS,IAAA;CACV;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;CAC7B;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,OAAO,CAAC,SAAS,CAA8B;IAC/C;;OAEG;IACH,OAAO,CAAC,IAAI,CAAqB;gBAErB,IAAI,EAAE,QAAQ,GAAG,QAAQ;IAI/B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAShC;;;;;;;OAOG;IACG,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjH;;;;OAIG;IACG,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBhD;;;;OAIG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB1E;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAiB3C;;;;;;OAMG;IACH,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAiB9C;;;OAGG;IACH,UAAU,IAAI,QAAQ,EAAE;IAIxB;;OAEG;IACG,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrD,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAI/C,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,OAAO;IAQ5D,qBAAqB,IAAI,IAAI;IAQ7B;;;;OAIG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;CAQxD"}
1
+ {"version":3,"file":"FragmentManager.d.ts","sourceRoot":"","sources":["../../../src/core/FragmentManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,oBAAY,aAAa;IACvB,WAAW,IAAA;IACX,OAAO,IAAA;IACP,QAAQ,IAAA,CAAE,mCAAmC;IAC7C,OAAO,IAAA,CAAE,UAAU;IACnB,OAAO,IAAA,CAAE,YAAY;IACrB,MAAM,IAAA;IACN,OAAO,IAAA,CAAE,oBAAoB;IAC7B,QAAQ,IAAA,CAAE,uCAAuC;IACjD,SAAS,IAAA;CACV;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;CAC7B;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,OAAO,CAAC,SAAS,CAA8B;IAC/C;;OAEG;IACH,OAAO,CAAC,IAAI,CAAqB;gBAErB,IAAI,EAAE,QAAQ,GAAG,QAAQ;IAI/B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAShC;;;;;;;OAOG;IACG,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjH;;;;OAIG;IACG,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBhD;;;;OAIG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB1E;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAiB3C;;;;;;OAMG;IACH,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAiB9C;;;OAGG;IACH,UAAU,IAAI,QAAQ,EAAE;IAIxB;;OAEG;IACG,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB9D,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAI/C,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,OAAO;IAQ5D,qBAAqB,IAAI,IAAI;IAQ7B;;;;OAIG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;CAQxD"}
@@ -156,11 +156,21 @@ export class FragmentManager {
156
156
  * Hides a Fragment (calls lifecycle methods and removes from DOM if necessary)
157
157
  */
158
158
  async hideFragment(fragment) {
159
- await fragment.onPause();
160
- fragment.state = FragmentState.Paused;
161
- await fragment.onStop();
162
- fragment.state = FragmentState.Stopped;
163
- this.removeFragmentStyles(fragment);
159
+ let ref;
160
+ if (typeof fragment === 'string') {
161
+ ref = this.findFragment(fragment);
162
+ }
163
+ else {
164
+ ref = fragment;
165
+ }
166
+ if (!ref) {
167
+ throw new Error(`Fragment not found`);
168
+ }
169
+ await ref.onPause();
170
+ ref.state = FragmentState.Paused;
171
+ await ref.onStop();
172
+ ref.state = FragmentState.Stopped;
173
+ this.removeFragmentStyles(ref);
164
174
  // if necessary, you would remove its template content from the DOM
165
175
  // however, with rendering logic encapsulated in Fragment, this isn't needed here
166
176
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FragmentManager.js","sourceRoot":"","sources":["../../../src/core/FragmentManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { type TemplateResult, nothing } from 'lit'\nimport type { Activity } from './Activity.js'\nimport type { Fragment } from './Fragment.js'\n\nexport enum FragmentState {\n Initialized,\n Created,\n Attached, // Added to an Activity or Fragment\n Started, // Visible\n Resumed, // Has focus\n Paused,\n Stopped, // No longer visible\n Detached, // Removed from an Activity or Fragment\n Destroyed,\n}\n\nexport interface FragmentOptions {\n parent?: Activity | Fragment\n}\n\n/**\n * `FragmentManager` is the class responsible for performing actions\n * on the app's fragments, such as adding, removing, or replacing them\n * and adding them to the back stack.\n */\nexport class FragmentManager {\n /**\n * Stores fragments by I\n */\n private fragments = new Map<string, Fragment>()\n /**\n * The reference to the host activity or fragment.\n */\n private host: Activity | Fragment\n\n constructor(host: Activity | Fragment) {\n this.host = host\n }\n\n async onDestroy(): Promise<void> {\n // Clean up all fragments when the host is destroyed\n for (const [key, fragment] of this.fragments) {\n await fragment.onDestroy()\n this.removeFragmentStyles(fragment)\n this.fragments.delete(key)\n }\n }\n\n /**\n * Attaches a fragment to a parent Activity or Fragment\n *\n * @param fragment The fragment to add.\n * @param parent The parent fragment or activity.\n * @param renderTarget Optional DOM target to render to.\n * @param data Optional data to pass to the `onCreate()` method.\n */\n async attachFragment(key: string, fragment: Fragment, parent: Activity | Fragment, data?: unknown): Promise<void> {\n // Ensure fragment has correct parent\n fragment.parent = parent\n\n this.fragments.set(key, fragment)\n await fragment.onCreate(data)\n fragment.state = FragmentState.Created\n await fragment.onAttach(data)\n fragment.state = FragmentState.Attached\n }\n\n /**\n * Detaches a fragment from its parent.\n * @param fragment\n * @returns\n */\n async detachFragment(key: string): Promise<void> {\n const fragment = this.findFragment(key)\n if (!fragment) {\n throw new Error(`Fragment with key ${key} not found.`)\n }\n\n this.hideFragment(fragment)\n await fragment.onDetach()\n fragment.state = FragmentState.Detached\n await fragment.onDestroy()\n fragment.state = FragmentState.Destroyed\n this.fragments.delete(key)\n // Clear parent reference\n fragment.parent = undefined\n }\n\n /**\n * Shows a Fragment (calls lifecycle methods and renders)\n * @param fragment The fragment to render.\n * @param renderTarget Optional render target, if any.\n */\n async showFragment(key: string, renderTarget?: HTMLElement): Promise<void> {\n const fragment = this.findFragment(key)\n if (!fragment) {\n throw new Error(`Fragment with key ${key} not found.`)\n }\n if (fragment.state === FragmentState.Resumed) {\n return\n }\n // Tell the fragment it is now started.\n await fragment.onStart()\n fragment.state = FragmentState.Started\n await fragment.onResume()\n fragment.state = FragmentState.Resumed\n if (renderTarget) {\n fragment.setRenderRoot(renderTarget)\n fragment.requestUpdate({ app: false, activity: false })\n } else {\n this.host.requestUpdate({ app: false, activity: true })\n }\n this.setFragmentStyles(fragment)\n }\n\n /**\n * Sets styles for a fragment by adding a class to the root element.\n * This is useful for applying specific styles to fragments.\n *\n * The root element is either fragment's render root or the document element.\n * @param fragment The fragment to set styles for.\n */\n setFragmentStyles(fragment: Fragment): void {\n const root = fragment.renderer.renderRoot ?? document?.documentElement\n if (!root) {\n return\n }\n const classes: string[] = []\n const ctor = fragment.constructor\n classes.push(ctor.name.toLowerCase())\n if (typeof fragment.rootClass === 'function') {\n const className = fragment.rootClass()\n if (className) {\n classes.push(className)\n }\n }\n root.classList.add(...classes)\n }\n\n /**\n * Removes styles for a fragment by removing a class from the root element.\n * This is useful for cleaning up styles when a fragment is no longer visible.\n *\n * The root element is either fragment's render root or the document element.\n * @param fragment The fragment to remove styles for.\n */\n removeFragmentStyles(fragment: Fragment): void {\n const root = fragment.renderer.renderRoot ?? document?.documentElement\n if (!root) {\n return\n }\n const classes: string[] = []\n const ctor = fragment.constructor\n classes.push(ctor.name.toLowerCase())\n if (typeof fragment.rootClass === 'function') {\n const className = fragment.rootClass()\n if (className) {\n classes.push(className)\n }\n }\n root.classList.remove(...classes)\n }\n\n /**\n * Lists all visible fragments, that is in the fragments with the `FragmentState.Resumed` state.\n * @returns The list of visible fragments\n */\n getVisible(): Fragment[] {\n return Array.from(this.fragments.values()).filter((fragment) => fragment.state === FragmentState.Resumed)\n }\n\n /**\n * Hides a Fragment (calls lifecycle methods and removes from DOM if necessary)\n */\n async hideFragment(fragment: Fragment): Promise<void> {\n await fragment.onPause()\n fragment.state = FragmentState.Paused\n await fragment.onStop()\n fragment.state = FragmentState.Stopped\n this.removeFragmentStyles(fragment)\n // if necessary, you would remove its template content from the DOM\n // however, with rendering logic encapsulated in Fragment, this isn't needed here\n }\n\n findFragment(key: string): Fragment | undefined {\n return this.fragments.get(key)\n }\n\n renderFragment(key: string): TemplateResult | typeof nothing {\n const fragment = this.findFragment(key)\n if (!fragment || fragment.state !== FragmentState.Resumed) {\n return nothing\n }\n return fragment.render() || nothing\n }\n\n updateActiveFragments(): void {\n for (const [, fragment] of this.fragments) {\n if ([FragmentState.Started, FragmentState.Resumed].includes(fragment.state)) {\n fragment.requestUpdate({ app: false, activity: false })\n }\n }\n }\n\n /**\n * Finds a fragment by activity request code.\n * @param requestCode The request code to find the fragment by.\n * @returns The corresponding fragment or `null`.\n */\n findByRequestCode(requestCode: number): Fragment | null {\n for (const [, fragment] of this.fragments) {\n if (fragment.hasRequestCode(requestCode)) {\n return fragment\n }\n }\n return null\n }\n}\n"]}
1
+ {"version":3,"file":"FragmentManager.js","sourceRoot":"","sources":["../../../src/core/FragmentManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { type TemplateResult, nothing } from 'lit'\nimport type { Activity } from './Activity.js'\nimport type { Fragment } from './Fragment.js'\n\nexport enum FragmentState {\n Initialized,\n Created,\n Attached, // Added to an Activity or Fragment\n Started, // Visible\n Resumed, // Has focus\n Paused,\n Stopped, // No longer visible\n Detached, // Removed from an Activity or Fragment\n Destroyed,\n}\n\nexport interface FragmentOptions {\n parent?: Activity | Fragment\n}\n\n/**\n * `FragmentManager` is the class responsible for performing actions\n * on the app's fragments, such as adding, removing, or replacing them\n * and adding them to the back stack.\n */\nexport class FragmentManager {\n /**\n * Stores fragments by I\n */\n private fragments = new Map<string, Fragment>()\n /**\n * The reference to the host activity or fragment.\n */\n private host: Activity | Fragment\n\n constructor(host: Activity | Fragment) {\n this.host = host\n }\n\n async onDestroy(): Promise<void> {\n // Clean up all fragments when the host is destroyed\n for (const [key, fragment] of this.fragments) {\n await fragment.onDestroy()\n this.removeFragmentStyles(fragment)\n this.fragments.delete(key)\n }\n }\n\n /**\n * Attaches a fragment to a parent Activity or Fragment\n *\n * @param fragment The fragment to add.\n * @param parent The parent fragment or activity.\n * @param renderTarget Optional DOM target to render to.\n * @param data Optional data to pass to the `onCreate()` method.\n */\n async attachFragment(key: string, fragment: Fragment, parent: Activity | Fragment, data?: unknown): Promise<void> {\n // Ensure fragment has correct parent\n fragment.parent = parent\n\n this.fragments.set(key, fragment)\n await fragment.onCreate(data)\n fragment.state = FragmentState.Created\n await fragment.onAttach(data)\n fragment.state = FragmentState.Attached\n }\n\n /**\n * Detaches a fragment from its parent.\n * @param fragment\n * @returns\n */\n async detachFragment(key: string): Promise<void> {\n const fragment = this.findFragment(key)\n if (!fragment) {\n throw new Error(`Fragment with key ${key} not found.`)\n }\n\n this.hideFragment(fragment)\n await fragment.onDetach()\n fragment.state = FragmentState.Detached\n await fragment.onDestroy()\n fragment.state = FragmentState.Destroyed\n this.fragments.delete(key)\n // Clear parent reference\n fragment.parent = undefined\n }\n\n /**\n * Shows a Fragment (calls lifecycle methods and renders)\n * @param fragment The fragment to render.\n * @param renderTarget Optional render target, if any.\n */\n async showFragment(key: string, renderTarget?: HTMLElement): Promise<void> {\n const fragment = this.findFragment(key)\n if (!fragment) {\n throw new Error(`Fragment with key ${key} not found.`)\n }\n if (fragment.state === FragmentState.Resumed) {\n return\n }\n // Tell the fragment it is now started.\n await fragment.onStart()\n fragment.state = FragmentState.Started\n await fragment.onResume()\n fragment.state = FragmentState.Resumed\n if (renderTarget) {\n fragment.setRenderRoot(renderTarget)\n fragment.requestUpdate({ app: false, activity: false })\n } else {\n this.host.requestUpdate({ app: false, activity: true })\n }\n this.setFragmentStyles(fragment)\n }\n\n /**\n * Sets styles for a fragment by adding a class to the root element.\n * This is useful for applying specific styles to fragments.\n *\n * The root element is either fragment's render root or the document element.\n * @param fragment The fragment to set styles for.\n */\n setFragmentStyles(fragment: Fragment): void {\n const root = fragment.renderer.renderRoot ?? document?.documentElement\n if (!root) {\n return\n }\n const classes: string[] = []\n const ctor = fragment.constructor\n classes.push(ctor.name.toLowerCase())\n if (typeof fragment.rootClass === 'function') {\n const className = fragment.rootClass()\n if (className) {\n classes.push(className)\n }\n }\n root.classList.add(...classes)\n }\n\n /**\n * Removes styles for a fragment by removing a class from the root element.\n * This is useful for cleaning up styles when a fragment is no longer visible.\n *\n * The root element is either fragment's render root or the document element.\n * @param fragment The fragment to remove styles for.\n */\n removeFragmentStyles(fragment: Fragment): void {\n const root = fragment.renderer.renderRoot ?? document?.documentElement\n if (!root) {\n return\n }\n const classes: string[] = []\n const ctor = fragment.constructor\n classes.push(ctor.name.toLowerCase())\n if (typeof fragment.rootClass === 'function') {\n const className = fragment.rootClass()\n if (className) {\n classes.push(className)\n }\n }\n root.classList.remove(...classes)\n }\n\n /**\n * Lists all visible fragments, that is in the fragments with the `FragmentState.Resumed` state.\n * @returns The list of visible fragments\n */\n getVisible(): Fragment[] {\n return Array.from(this.fragments.values()).filter((fragment) => fragment.state === FragmentState.Resumed)\n }\n\n /**\n * Hides a Fragment (calls lifecycle methods and removes from DOM if necessary)\n */\n async hideFragment(fragment: Fragment | string): Promise<void> {\n let ref: Fragment | undefined\n if (typeof fragment === 'string') {\n ref = this.findFragment(fragment)\n } else {\n ref = fragment as Fragment\n }\n if (!ref) {\n throw new Error(`Fragment not found`)\n }\n await ref.onPause()\n ref.state = FragmentState.Paused\n await ref.onStop()\n ref.state = FragmentState.Stopped\n this.removeFragmentStyles(ref)\n // if necessary, you would remove its template content from the DOM\n // however, with rendering logic encapsulated in Fragment, this isn't needed here\n }\n\n findFragment(key: string): Fragment | undefined {\n return this.fragments.get(key)\n }\n\n renderFragment(key: string): TemplateResult | typeof nothing {\n const fragment = this.findFragment(key)\n if (!fragment || fragment.state !== FragmentState.Resumed) {\n return nothing\n }\n return fragment.render() || nothing\n }\n\n updateActiveFragments(): void {\n for (const [, fragment] of this.fragments) {\n if ([FragmentState.Started, FragmentState.Resumed].includes(fragment.state)) {\n fragment.requestUpdate({ app: false, activity: false })\n }\n }\n }\n\n /**\n * Finds a fragment by activity request code.\n * @param requestCode The request code to find the fragment by.\n * @returns The corresponding fragment or `null`.\n */\n findByRequestCode(requestCode: number): Fragment | null {\n for (const [, fragment] of this.fragments) {\n if (fragment.hasRequestCode(requestCode)) {\n return fragment\n }\n }\n return null\n }\n}\n"]}
@@ -1,5 +1,12 @@
1
1
  import type { Fragment } from '../Fragment.js';
2
2
  import { Renderer } from './Renderer.js';
3
+ /**
4
+ * FragmentRenderer is responsible for rendering a Fragment instance.
5
+ * It extends the Renderer class and implements the rendering logic specific to Fragments.
6
+ *
7
+ * The fragment must decide how to render itself. Event when a fragment is a host
8
+ * and it only shows a single child, it still needs to render that child.
9
+ */
3
10
  export declare class FragmentRenderer extends Renderer {
4
11
  protected fragment: Fragment;
5
12
  constructor(fragment: Fragment);
@@ -1 +1 @@
1
- {"version":3,"file":"FragmentRenderer.d.ts","sourceRoot":"","sources":["../../../../src/core/renderer/FragmentRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,qBAAa,gBAAiB,SAAQ,QAAQ;IAChC,SAAS,CAAC,QAAQ,EAAE,QAAQ;gBAAlB,QAAQ,EAAE,QAAQ;IAIxC,SAAS,CAAC,QAAQ,IAAI,IAAI;CAe3B"}
1
+ {"version":3,"file":"FragmentRenderer.d.ts","sourceRoot":"","sources":["../../../../src/core/renderer/FragmentRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC;;;;;;GAMG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;IAChC,SAAS,CAAC,QAAQ,EAAE,QAAQ;gBAAlB,QAAQ,EAAE,QAAQ;IAIxC,SAAS,CAAC,QAAQ,IAAI,IAAI;CAc3B"}
@@ -1,4 +1,11 @@
1
1
  import { Renderer } from './Renderer.js';
2
+ /**
3
+ * FragmentRenderer is responsible for rendering a Fragment instance.
4
+ * It extends the Renderer class and implements the rendering logic specific to Fragments.
5
+ *
6
+ * The fragment must decide how to render itself. Event when a fragment is a host
7
+ * and it only shows a single child, it still needs to render that child.
8
+ */
2
9
  export class FragmentRenderer extends Renderer {
3
10
  fragment;
4
11
  constructor(fragment) {
@@ -11,10 +18,9 @@ export class FragmentRenderer extends Renderer {
11
18
  // return quietly. Fragments can be rendered directly.
12
19
  return;
13
20
  }
14
- const host = this.fragment.getSingleVisibleFragment() ?? this.fragment;
21
+ const host = this.fragment;
15
22
  if (!this.firstRendered) {
16
23
  this.firstRenderedFlag = true;
17
- // cleanup any pre-existing content.
18
24
  this._clearRoot(root);
19
25
  queueMicrotask(() => host.onFirstRender());
20
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FragmentRenderer.js","sourceRoot":"","sources":["../../../../src/core/renderer/FragmentRenderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IACtB;IAAtB,YAAsB,QAAkB;QACtC,KAAK,EAAE,CAAA;QADa,aAAQ,GAAR,QAAQ,CAAU;IAExC,CAAC;IAES,QAAQ;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAA;QAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,sDAAsD;YACtD,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,wBAAwB,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAA;QACtE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAA;YAC7B,oCAAoC;YACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;YACrB,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAA;QAC5C,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IACzC,CAAC;CACF","sourcesContent":["import type { Fragment } from '../Fragment.js'\nimport { Renderer } from './Renderer.js'\n\nexport class FragmentRenderer extends Renderer {\n constructor(protected fragment: Fragment) {\n super()\n }\n\n protected renderer(): void {\n const root = this.renderRoot\n if (!root) {\n // return quietly. Fragments can be rendered directly.\n return\n }\n const host = this.fragment.getSingleVisibleFragment() ?? this.fragment\n if (!this.firstRendered) {\n this.firstRenderedFlag = true\n // cleanup any pre-existing content.\n this._clearRoot(root)\n queueMicrotask(() => host.onFirstRender())\n }\n this._render(host.render(), root, host)\n }\n}\n"]}
1
+ {"version":3,"file":"FragmentRenderer.js","sourceRoot":"","sources":["../../../../src/core/renderer/FragmentRenderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC;;;;;;GAMG;AACH,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IACtB;IAAtB,YAAsB,QAAkB;QACtC,KAAK,EAAE,CAAA;QADa,aAAQ,GAAR,QAAQ,CAAU;IAExC,CAAC;IAES,QAAQ;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAA;QAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,sDAAsD;YACtD,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC1B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAA;YAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;YACrB,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAA;QAC5C,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IACzC,CAAC;CACF","sourcesContent":["import type { Fragment } from '../Fragment.js'\nimport { Renderer } from './Renderer.js'\n\n/**\n * FragmentRenderer is responsible for rendering a Fragment instance.\n * It extends the Renderer class and implements the rendering logic specific to Fragments.\n *\n * The fragment must decide how to render itself. Event when a fragment is a host\n * and it only shows a single child, it still needs to render that child.\n */\nexport class FragmentRenderer extends Renderer {\n constructor(protected fragment: Fragment) {\n super()\n }\n\n protected renderer(): void {\n const root = this.renderRoot\n if (!root) {\n // return quietly. Fragments can be rendered directly.\n return\n }\n const host = this.fragment\n if (!this.firstRendered) {\n this.firstRenderedFlag = true\n this._clearRoot(root)\n queueMicrotask(() => host.onFirstRender())\n }\n this._render(host.render(), root, host)\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api-client/ui",
3
- "version": "0.5.35",
3
+ "version": "0.5.36",
4
4
  "description": "Internal UI component library for the API Client ecosystem.",
5
5
  "license": "UNLICENSED",
6
6
  "main": "build/src/index.js",
@@ -240,12 +240,12 @@ export class Fragment extends EventTarget {
240
240
  * Application or parent Fragment will handle rendering.
241
241
  */
242
242
  requestUpdate(opts: UpdateRequest = {}): void {
243
- const { fragment = true } = opts
244
- if (fragment) {
245
- this.#renderer.requestUpdate()
243
+ if (opts.fragment !== false) {
244
+ this.renderer.requestUpdate()
245
+ }
246
+ if (this.parent && (opts.activity || opts.app)) {
247
+ this.parent.requestUpdate(opts)
246
248
  }
247
- this.parent?.requestUpdate(opts)
248
- // If no parent, do nothing (or maybe throw an error?)
249
249
  }
250
250
 
251
251
  getApplication(): Application | undefined {
@@ -172,12 +172,21 @@ export class FragmentManager {
172
172
  /**
173
173
  * Hides a Fragment (calls lifecycle methods and removes from DOM if necessary)
174
174
  */
175
- async hideFragment(fragment: Fragment): Promise<void> {
176
- await fragment.onPause()
177
- fragment.state = FragmentState.Paused
178
- await fragment.onStop()
179
- fragment.state = FragmentState.Stopped
180
- this.removeFragmentStyles(fragment)
175
+ async hideFragment(fragment: Fragment | string): Promise<void> {
176
+ let ref: Fragment | undefined
177
+ if (typeof fragment === 'string') {
178
+ ref = this.findFragment(fragment)
179
+ } else {
180
+ ref = fragment as Fragment
181
+ }
182
+ if (!ref) {
183
+ throw new Error(`Fragment not found`)
184
+ }
185
+ await ref.onPause()
186
+ ref.state = FragmentState.Paused
187
+ await ref.onStop()
188
+ ref.state = FragmentState.Stopped
189
+ this.removeFragmentStyles(ref)
181
190
  // if necessary, you would remove its template content from the DOM
182
191
  // however, with rendering logic encapsulated in Fragment, this isn't needed here
183
192
  }
@@ -1,6 +1,13 @@
1
1
  import type { Fragment } from '../Fragment.js'
2
2
  import { Renderer } from './Renderer.js'
3
3
 
4
+ /**
5
+ * FragmentRenderer is responsible for rendering a Fragment instance.
6
+ * It extends the Renderer class and implements the rendering logic specific to Fragments.
7
+ *
8
+ * The fragment must decide how to render itself. Event when a fragment is a host
9
+ * and it only shows a single child, it still needs to render that child.
10
+ */
4
11
  export class FragmentRenderer extends Renderer {
5
12
  constructor(protected fragment: Fragment) {
6
13
  super()
@@ -12,10 +19,9 @@ export class FragmentRenderer extends Renderer {
12
19
  // return quietly. Fragments can be rendered directly.
13
20
  return
14
21
  }
15
- const host = this.fragment.getSingleVisibleFragment() ?? this.fragment
22
+ const host = this.fragment
16
23
  if (!this.firstRendered) {
17
24
  this.firstRenderedFlag = true
18
- // cleanup any pre-existing content.
19
25
  this._clearRoot(root)
20
26
  queueMicrotask(() => host.onFirstRender())
21
27
  }
@@ -318,7 +318,7 @@ describe('Fragment', () => {
318
318
 
319
319
  it('calls parent.requestUpdate', () => {
320
320
  const parentRequestUpdateSpy = sinon.spy(fragment.parent!, 'requestUpdate')
321
- const opts = { app: false }
321
+ const opts = { app: false, activity: true }
322
322
  fragment.requestUpdate(opts)
323
323
  assert.isTrue(parentRequestUpdateSpy.calledOnceWith(opts))
324
324
  })