@api-client/ui 0.5.36 → 0.5.38

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.
@@ -40,6 +40,15 @@ export declare class Fragment extends EventTarget {
40
40
  */
41
41
  pendingActivityResult: Map<number, PendingActivityResult>;
42
42
  get renderer(): FragmentRenderer;
43
+ /**
44
+ * The host to be used by the FragmentRenderer to assign it to the Lit's render root.
45
+ * Whatever is assigned to this property will be used as the root element.
46
+ *
47
+ * Fragments should use this property to manipulate the event's target.
48
+ * If a fragment renders multiple children, but only one is visible,
49
+ * it should assign the host value to the currently rendered child.
50
+ */
51
+ host: Fragment;
43
52
  constructor(options?: FragmentOptions);
44
53
  /**
45
54
  * When implemented, this method returns the class name to be used as a root class for the fragment.
@@ -181,5 +190,19 @@ export declare class Fragment extends EventTarget {
181
190
  * @throws An error if the event type is not recognized.
182
191
  */
183
192
  handleIntentEvent(event: CustomEvent<ActivityDetail | ActivityWithResultDetail>): Promise<void>;
193
+ /**
194
+ * Shows a registered fragment.
195
+ * @param key The fragment's key.
196
+ * @param options Fragment rendering options.
197
+ */
198
+ showFragment(key: string, options?: {
199
+ renderTarget?: HTMLElement;
200
+ isHost?: boolean;
201
+ }): Promise<void>;
202
+ /**
203
+ * Hides a fragment by its key.
204
+ * @param key The fragment's key.
205
+ */
206
+ hideFragment(fragment: Fragment | string): Promise<void>;
184
207
  }
185
208
  //# sourceMappingURL=Fragment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Fragment.d.ts","sourceRoot":"","sources":["../../../src/core/Fragment.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Fragment.d.ts","sourceRoot":"","sources":["../../../src/core/Fragment.ts"],"names":[],"mappings":"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"}
@@ -47,6 +47,15 @@ let Fragment = (() => {
47
47
  get renderer() {
48
48
  return this.#renderer;
49
49
  }
50
+ /**
51
+ * The host to be used by the FragmentRenderer to assign it to the Lit's render root.
52
+ * Whatever is assigned to this property will be used as the root element.
53
+ *
54
+ * Fragments should use this property to manipulate the event's target.
55
+ * If a fragment renders multiple children, but only one is visible,
56
+ * it should assign the host value to the currently rendered child.
57
+ */
58
+ host = this;
50
59
  constructor(options) {
51
60
  super();
52
61
  this.parent = options?.parent;
@@ -323,6 +332,41 @@ let Fragment = (() => {
323
332
  throw new Error(`Unrecognized intent event: ${event.type}`);
324
333
  }
325
334
  }
335
+ /**
336
+ * Shows a registered fragment.
337
+ * @param key The fragment's key.
338
+ * @param options Fragment rendering options.
339
+ */
340
+ async showFragment(key, options = {}) {
341
+ if (options.isHost) {
342
+ const fragment = this.fragmentManager.findFragment(key);
343
+ if (!fragment) {
344
+ throw new Error(`Fragment with key ${key} not found.`);
345
+ }
346
+ this.host = fragment;
347
+ }
348
+ await this.fragmentManager.showFragment(key, options.renderTarget);
349
+ }
350
+ /**
351
+ * Hides a fragment by its key.
352
+ * @param key The fragment's key.
353
+ */
354
+ async hideFragment(fragment) {
355
+ let ref;
356
+ if (typeof fragment === 'string') {
357
+ ref = this.fragmentManager.findFragment(fragment);
358
+ }
359
+ else {
360
+ ref = fragment;
361
+ }
362
+ if (!ref) {
363
+ throw new Error(`Fragment not found`);
364
+ }
365
+ if (this.host === ref) {
366
+ this.host = this;
367
+ }
368
+ await this.fragmentManager.hideFragment(ref);
369
+ }
326
370
  };
327
371
  })();
328
372
  export { Fragment };
@@ -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 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"]}
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 /**\n * The host to be used by the FragmentRenderer to assign it to the Lit's render root.\n * Whatever is assigned to this property will be used as the root element.\n *\n * Fragments should use this property to manipulate the event's target.\n * If a fragment renders multiple children, but only one is visible,\n * it should assign the host value to the currently rendered child.\n */\n host: Fragment = this\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 /**\n * Shows a registered fragment.\n * @param key The fragment's key.\n * @param options Fragment rendering options.\n */\n async showFragment(key: string, options: { renderTarget?: HTMLElement; isHost?: boolean } = {}): Promise<void> {\n if (options.isHost) {\n const fragment = this.fragmentManager.findFragment(key)\n if (!fragment) {\n throw new Error(`Fragment with key ${key} not found.`)\n }\n this.host = fragment\n }\n await this.fragmentManager.showFragment(key, options.renderTarget)\n }\n\n /**\n * Hides a fragment by its key.\n * @param key The fragment's key.\n */\n async hideFragment(fragment: Fragment | string): Promise<void> {\n let ref: Fragment | undefined\n if (typeof fragment === 'string') {\n ref = this.fragmentManager.findFragment(fragment)\n } else {\n ref = fragment as Fragment\n }\n if (!ref) {\n throw new Error(`Fragment not found`)\n }\n if (this.host === ref) {\n this.host = this\n }\n await this.fragmentManager.hideFragment(ref)\n }\n}\n"]}
@@ -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;;;;;;GAMG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;IAChC,SAAS,CAAC,QAAQ,EAAE,QAAQ;gBAAlB,QAAQ,EAAE,QAAQ;IAIxC,SAAS,CAAC,QAAQ,IAAI,IAAI;CAc3B"}
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;CAa3B"}
@@ -18,13 +18,12 @@ export class FragmentRenderer extends Renderer {
18
18
  // return quietly. Fragments can be rendered directly.
19
19
  return;
20
20
  }
21
- const host = this.fragment;
22
21
  if (!this.firstRendered) {
23
22
  this.firstRenderedFlag = true;
24
23
  this._clearRoot(root);
25
- queueMicrotask(() => host.onFirstRender());
24
+ queueMicrotask(() => this.fragment.onFirstRender());
26
25
  }
27
- this._render(host.render(), root, host);
26
+ this._render(this.fragment.render(), root, this.fragment.host);
28
27
  }
29
28
  }
30
29
  //# sourceMappingURL=FragmentRenderer.js.map
@@ -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;;;;;;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"]}
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,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,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAA;QACrD,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IAChE,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 if (!this.firstRendered) {\n this.firstRenderedFlag = true\n this._clearRoot(root)\n queueMicrotask(() => this.fragment.onFirstRender())\n }\n this._render(this.fragment.render(), root, this.fragment.host)\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../../../src/md/select/internals/Select.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../../../src/md/select/internals/Select.ts"],"names":[],"mappings":"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"}
@@ -565,6 +565,7 @@ let UiSelect = (() => {
565
565
  const item = e.detail.item;
566
566
  this.selectedOption = item;
567
567
  this.#value = item.value;
568
+ this.#internals.setFormValue(this.value ?? null);
568
569
  this.open = false;
569
570
  // Dispatch change event
570
571
  const changeEvent = new CustomEvent('change', {
@@ -1 +1 @@
1
- {"version":3,"file":"Select.js","sourceRoot":"","sources":["../../../../../src/md/select/internals/Select.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, PropertyValues, TemplateResult } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { setDisabled } from '../../../lib/disabled.js'\nimport type UiOption from './Option.js'\nimport type { UiMenuElement } from '../../menu/ui-menu.js'\nimport { nanoid } from 'nanoid'\n\nimport '../../text-field/ui-outlined-text-field.js'\nimport '../../menu/ui-menu.js'\nimport '../../icons/ui-icon.js'\nimport '@material/web/focus/md-focus-ring.js'\n\nexport interface UiSelectChangeEvent {\n value: string | undefined\n item: UiOption | null\n}\n\n/**\n * Material Design 3 Select component that behaves like an outlined text field with dropdown.\n *\n * @fires change - Dispatched when the selection changes. The event is non-bubbling and non-cancelable.\n * The `event.detail` object contains the `value` and `item` properties.\n * @fires open - Dispatched when the dropdown opens\n * @fires close - Dispatched when the dropdown closes\n */\nexport default class UiSelect extends LitElement {\n static readonly formAssociated = true\n #internals = this.attachInternals()\n\n /**\n * The value has a private member so that we can set the value without triggering\n * the side effects.\n */\n #value: string | undefined\n\n /**\n * The currently selected value. Corresponds to the `value` attribute of the selected `ui-option`.\n * When set programmatically, it will update the selected option if a matching option exists.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select value=\"apple\">\n * <ui-option value=\"apple\">Apple</ui-option>\n * <ui-option value=\"banana\">Banana</ui-option>\n * </ui-select>\n * ```\n */\n get value(): string | undefined {\n return this.#value\n }\n\n @property({ type: String })\n set value(newValue: string | undefined) {\n const oldValue = this.#value\n if (newValue === oldValue) return\n this.#value = newValue\n this.requestUpdate()\n }\n\n /**\n * The name attribute for form submission. This value will be used as the key\n * when the form is submitted.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select name=\"country\" value=\"us\">\n * <ui-option value=\"us\">United States</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: String }) accessor name: string | undefined\n\n /**\n * The label text displayed in the select field. Provides accessible labeling\n * and is shown as the floating label in the outlined text field.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select label=\"Select a country\">\n * <ui-option value=\"us\">United States</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: String }) accessor label: string | undefined\n\n /**\n * Whether the select is required for form validation. When true, the select\n * must have a value selected for the form to be valid.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select required label=\"Required field\">\n * <ui-option value=\"option1\">Option 1</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: Boolean }) accessor required = false\n\n /**\n * Whether the select is in an invalid state. This is typically set automatically\n * during validation, but can be set manually to indicate validation errors.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select invalid invalidText=\"Please select a valid option\">\n * <ui-option value=\"option1\">Option 1</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: Boolean }) accessor invalid: boolean | undefined\n\n /**\n * The error message to display when the select is invalid. This text is shown\n * below the select field when `invalid` is true.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select invalid invalidText=\"This field is required\">\n * <ui-option value=\"option1\">Option 1</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: String }) accessor invalidText: string | undefined\n\n /**\n * @attribute\n */\n @property({ type: String }) accessor supportingText: string | undefined\n\n /**\n * Whether the select is disabled. When disabled, the select cannot be interacted\n * with and will not receive focus or respond to user input.\n *\n * @default false\n * @attribute\n * @example\n * ```html\n * <ui-select disabled label=\"Disabled select\">\n * <ui-option value=\"option1\">Option 1</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: Boolean, reflect: true }) accessor disabled = false\n\n /**\n * Whether the dropdown menu is currently open. This property reflects the\n * current state of the dropdown and can be set programmatically to open/close it.\n *\n * @default false\n * @example\n * ```javascript\n * // Open the dropdown programmatically\n * selectElement.open = true;\n *\n * // Close the dropdown\n * selectElement.open = false;\n * ```\n */\n @property({ type: Boolean, reflect: true }) accessor open = false\n\n @state() accessor selectedOption: UiOption | null = null\n @state() accessor ariaActiveDescendant: string | undefined\n @query('.menu') accessor menu!: UiMenuElement\n\n /**\n * Returns the currently selected option element. This provides access to the\n * full `ui-option` element, not just its value.\n *\n * @readonly\n * @example\n * ```javascript\n * const select = document.querySelector('ui-select');\n * const selectedItem = select.selectedItem;\n * if (selectedItem) {\n * console.log('Selected option:', selectedItem.textContent);\n * }\n * ```\n */\n get selectedItem(): UiOption | null {\n return this.selectedOption\n }\n\n /**\n * Returns the text content that should be displayed in the select field.\n * This is the rendered value of the currently selected option.\n *\n * @readonly\n * @example\n * ```javascript\n * const select = document.querySelector('ui-select');\n * console.log('Display text:', select.renderValue);\n * ```\n */\n get renderValue(): string {\n const item = this.selectedOption\n return item ? item.renderValue : ''\n }\n\n /**\n * Returns the form element that contains this select, if any.\n * Part of the form-associated custom element API.\n *\n * @readonly\n */\n get form(): HTMLFormElement | null {\n return this.#internals.form\n }\n\n /**\n * Returns the validity state of the select element.\n * Part of the form-associated custom element API.\n *\n * @readonly\n */\n get validity(): ValidityState {\n return this.#internals.validity\n }\n\n /**\n * Returns the validation message for the select element.\n * Part of the form-associated custom element API.\n *\n * @readonly\n */\n get validationMessage(): string {\n return this.#internals.validationMessage\n }\n\n /**\n * Returns whether the select element will be validated when the form is submitted.\n * Part of the form-associated custom element API.\n *\n * @readonly\n */\n get willValidate(): boolean {\n return this.#internals.willValidate\n }\n\n /**\n * Checks the validity of the select element and returns true if valid.\n * Part of the form-associated custom element API.\n *\n * @returns {boolean} True if the element is valid, false otherwise\n * @example\n * ```javascript\n * const select = document.querySelector('ui-select');\n * if (!select.checkValidity()) {\n * console.log('Select is invalid:', select.validationMessage);\n * }\n * ```\n */\n checkValidity(): boolean {\n return this.#internals.checkValidity()\n }\n\n constructor() {\n super()\n this.addEventListener('click', this.handleClick.bind(this))\n this.addEventListener('blur', this.handleBlur.bind(this))\n this.addEventListener('keydown', this.handleKeydown.bind(this))\n }\n\n override connectedCallback(): void {\n super.connectedCallback()\n this.setAttribute('role', 'combobox')\n this.setAttribute('aria-haspopup', 'listbox')\n this.setAttribute('aria-controls', 'menu')\n if (!this.disabled) {\n this.setAttribute('tabindex', '0')\n }\n if (!this.id) {\n this.id = `select-${nanoid(6)}`\n }\n }\n\n /**\n * Resets the select to its initial state. Called automatically when the parent\n * form is reset. Part of the form-associated custom element API.\n *\n * @example\n * ```javascript\n * const select = document.querySelector('ui-select');\n * select.formResetCallback(); // Clears the selection\n * ```\n */\n formResetCallback(): void {\n this.value = undefined\n }\n\n /**\n * Restores the select's state from saved form data. Called automatically when\n * the browser restores form state. Part of the form-associated custom element API.\n *\n * @param {string | null} state - The saved state to restore\n */\n formStateRestoreCallback(state: string | null): void {\n this.value = state ?? undefined\n }\n\n /**\n * Validates the select element and updates its validity state. This is called\n * automatically during property changes, but can be called manually to trigger validation.\n *\n * @example\n * ```javascript\n * const select = document.querySelector('ui-select');\n * select.validate();\n * if (select.invalid) {\n * console.log('Validation failed:', select.invalidText);\n * }\n * ```\n */\n validate(): void {\n let message = ''\n if (this.required && !this.value) {\n message = 'Please select an item.'\n this.#internals.setValidity({ valueMissing: true }, message)\n } else {\n this.#internals.setValidity({})\n }\n this.invalid = !this.#internals.validity.valid\n this.invalidText = message\n }\n\n protected override willUpdate(changedProperties: PropertyValues<this>): void {\n super.willUpdate(changedProperties)\n if (changedProperties.has('disabled')) {\n setDisabled(this, this.disabled)\n }\n if (changedProperties.has('open')) {\n this.handleOpenChange()\n }\n if (changedProperties.has('value')) {\n this.setCurrentOption()\n this.#internals.setFormValue(this.value ?? null)\n this.validate()\n }\n if (changedProperties.has('label')) {\n if (this.label) {\n this.setAttribute('aria-label', this.label)\n } else {\n this.removeAttribute('aria-label')\n }\n }\n }\n\n protected override firstUpdated(cp: PropertyValues): void {\n super.firstUpdated(cp)\n this.setCurrentOption()\n this.#internals.setFormValue(this.value ?? null)\n }\n\n protected async setCurrentOption(): Promise<void> {\n await this.updateComplete\n const options = this.querySelectorAll<UiOption>('ui-option')\n if (this.value) {\n this.selectedOption = Array.from(options).find((option) => option.value === this.value) || null\n } else {\n const selected = Array.from(options).find((option) => option.selected)\n if (selected) {\n this.selectedOption = selected\n this.#value = selected.value\n } else {\n this.selectedOption = null\n }\n }\n }\n\n protected handleKeydown(e: KeyboardEvent): void {\n if (this.disabled || e.defaultPrevented) return\n if (this.open) {\n switch (e.key) {\n case 'Tab': {\n // If menu is open and Tab is pressed, close it and allow normal tab navigation\n if (this.open) {\n this.open = false\n }\n break\n }\n case 'Escape': {\n if (this.open) {\n e.preventDefault()\n this.open = false\n this.focus() // Return focus to the select element\n }\n break\n }\n case 'ArrowDown':\n e.preventDefault()\n this.menu.highlightNext()\n return\n case 'ArrowUp':\n e.preventDefault()\n this.menu.highlightPrevious()\n return\n case 'Home':\n e.preventDefault()\n this.menu.highlightFirst()\n return\n case 'End':\n e.preventDefault()\n this.menu.highlightLast()\n return\n case 'Enter':\n case ' ':\n if (this.menu.highlightListItem) {\n e.preventDefault()\n this.menu.notifySelect(this.menu.highlightListItem as UiOption)\n }\n return\n }\n } else {\n switch (e.key) {\n case 'Enter':\n case ' ': {\n if (!this.open) {\n e.preventDefault()\n this.open = true\n }\n break\n }\n case 'ArrowDown':\n case 'ArrowUp': {\n if (!this.open) {\n e.preventDefault()\n this.open = true\n }\n // If menu is open, let the menu handle arrow keys\n break\n }\n }\n }\n }\n\n protected handleBlur(e: FocusEvent): void {\n if (this.disabled) return\n\n // Check if focus is moving to the menu or one of its children\n const relatedTarget = e.relatedTarget as HTMLElement\n\n if (relatedTarget && this.contains(relatedTarget)) {\n // Focus is moving to the menu, keep it open\n return\n }\n\n // Close the menu when focus leaves the component\n this.open = false\n }\n\n protected handleClick(e: Event): void {\n if (this.disabled || e.defaultPrevented) return\n e.preventDefault()\n e.stopPropagation()\n this.open = true\n }\n\n protected async handleOpenChange(): Promise<void> {\n const menu = this.menu\n if (!menu) {\n // The status can be set before the menu is rendered\n return\n }\n this.setAttribute('aria-expanded', String(this.open))\n if (this.open) {\n menu.showPopover()\n // menu.focus()\n if (this.selectedOption) {\n this.menu.highlightItem(this.selectedOption)\n } else {\n this.menu.highlightFirst()\n }\n this.dispatchEvent(new CustomEvent('open', { bubbles: false, composed: true }))\n this.focus()\n } else {\n menu.hidePopover()\n this.dispatchEvent(new CustomEvent('close', { bubbles: false, composed: true }))\n }\n }\n\n handleSelect(e: CustomEvent<{ item: UiOption }>): void {\n e.stopPropagation()\n const item = e.detail.item\n this.selectedOption = item\n this.#value = item.value\n this.open = false\n\n // Dispatch change event\n const changeEvent = new CustomEvent<UiSelectChangeEvent>('change', {\n detail: { value: this.value, item: item },\n bubbles: false,\n composed: true,\n })\n this.dispatchEvent(changeEvent)\n this.focus()\n }\n\n handleHighlightChange(e: CustomEvent<{ item: UiOption | null }>): void {\n this.ariaActiveDescendant = e.detail.item?.id\n }\n\n handleMenuClose(): void {\n this.open = false\n this.focus()\n }\n\n protected renderInput(): TemplateResult {\n const styles = {\n 'anchor-name': `--${this.id}`,\n }\n return html`<ui-outlined-text-field\n .name=${this.name}\n .label=${this.label}\n .value=${this.renderValue}\n .disabled=${this.disabled}\n .required=${this.required}\n readonly\n tabindex=\"-1\"\n .inert=${true}\n aria-hidden=\"true\"\n .invalid=${this.invalid}\n .invalidText=${this.invalidText || ''}\n .supportingText=${this.supportingText || ''}\n class=\"input\"\n style=${styleMap(styles)}\n part=\"input\"\n >\n <ui-icon part=\"icon\" slot=\"suffix\">arrow_drop_down</ui-icon>\n </ui-outlined-text-field>`\n }\n\n protected renderMenu(): TemplateResult {\n const styles = {\n 'position-anchor': `--${this.id}`,\n }\n return html`<ui-menu\n id=\"menu\"\n class=\"menu\"\n part=\"menu\"\n style=${styleMap(styles)}\n popover=\"auto\"\n selector=\"ui-option\"\n @select=\"${this.handleSelect}\"\n @close=\"${this.handleMenuClose}\"\n @highlightchange=\"${this.handleHighlightChange}\"\n >\n <slot @slotchange=\"${this.handleSlotChange}\"></slot>\n </ui-menu>`\n }\n\n protected async handleSlotChange(): Promise<void> {\n // When options change, re-evaluate the current selection\n // only if we don't have an explicit value set\n if (!this.value) {\n await this.setCurrentOption()\n this.requestUpdate()\n }\n }\n\n protected renderFocusRing(): TemplateResult {\n return html`<md-focus-ring part=\"focus-ring\" class=\"focus-ring\" .control=\"${this as HTMLElement}\"></md-focus-ring>`\n }\n\n override render(): TemplateResult {\n const classes = classMap({\n 'ui-select': true,\n 'open': this.open,\n 'disabled': this.disabled,\n })\n return html`${this.renderFocusRing()}\n <div class=\"${classes}\" aria-activedescendant=${this.ariaActiveDescendant || ''}>\n ${this.renderInput()} ${this.renderMenu()}\n </div> `\n }\n}\n"]}
1
+ {"version":3,"file":"Select.js","sourceRoot":"","sources":["../../../../../src/md/select/internals/Select.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, PropertyValues, TemplateResult } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { setDisabled } from '../../../lib/disabled.js'\nimport type UiOption from './Option.js'\nimport type { UiMenuElement } from '../../menu/ui-menu.js'\nimport { nanoid } from 'nanoid'\n\nimport '../../text-field/ui-outlined-text-field.js'\nimport '../../menu/ui-menu.js'\nimport '../../icons/ui-icon.js'\nimport '@material/web/focus/md-focus-ring.js'\n\nexport interface UiSelectChangeEvent {\n value: string | undefined\n item: UiOption | null\n}\n\n/**\n * Material Design 3 Select component that behaves like an outlined text field with dropdown.\n *\n * @fires change - Dispatched when the selection changes. The event is non-bubbling and non-cancelable.\n * The `event.detail` object contains the `value` and `item` properties.\n * @fires open - Dispatched when the dropdown opens\n * @fires close - Dispatched when the dropdown closes\n */\nexport default class UiSelect extends LitElement {\n static readonly formAssociated = true\n #internals = this.attachInternals()\n\n /**\n * The value has a private member so that we can set the value without triggering\n * the side effects.\n */\n #value: string | undefined\n\n /**\n * The currently selected value. Corresponds to the `value` attribute of the selected `ui-option`.\n * When set programmatically, it will update the selected option if a matching option exists.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select value=\"apple\">\n * <ui-option value=\"apple\">Apple</ui-option>\n * <ui-option value=\"banana\">Banana</ui-option>\n * </ui-select>\n * ```\n */\n get value(): string | undefined {\n return this.#value\n }\n\n @property({ type: String })\n set value(newValue: string | undefined) {\n const oldValue = this.#value\n if (newValue === oldValue) return\n this.#value = newValue\n this.requestUpdate()\n }\n\n /**\n * The name attribute for form submission. This value will be used as the key\n * when the form is submitted.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select name=\"country\" value=\"us\">\n * <ui-option value=\"us\">United States</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: String }) accessor name: string | undefined\n\n /**\n * The label text displayed in the select field. Provides accessible labeling\n * and is shown as the floating label in the outlined text field.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select label=\"Select a country\">\n * <ui-option value=\"us\">United States</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: String }) accessor label: string | undefined\n\n /**\n * Whether the select is required for form validation. When true, the select\n * must have a value selected for the form to be valid.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select required label=\"Required field\">\n * <ui-option value=\"option1\">Option 1</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: Boolean }) accessor required = false\n\n /**\n * Whether the select is in an invalid state. This is typically set automatically\n * during validation, but can be set manually to indicate validation errors.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select invalid invalidText=\"Please select a valid option\">\n * <ui-option value=\"option1\">Option 1</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: Boolean }) accessor invalid: boolean | undefined\n\n /**\n * The error message to display when the select is invalid. This text is shown\n * below the select field when `invalid` is true.\n *\n * @attribute\n * @example\n * ```html\n * <ui-select invalid invalidText=\"This field is required\">\n * <ui-option value=\"option1\">Option 1</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: String }) accessor invalidText: string | undefined\n\n /**\n * @attribute\n */\n @property({ type: String }) accessor supportingText: string | undefined\n\n /**\n * Whether the select is disabled. When disabled, the select cannot be interacted\n * with and will not receive focus or respond to user input.\n *\n * @default false\n * @attribute\n * @example\n * ```html\n * <ui-select disabled label=\"Disabled select\">\n * <ui-option value=\"option1\">Option 1</ui-option>\n * </ui-select>\n * ```\n */\n @property({ type: Boolean, reflect: true }) accessor disabled = false\n\n /**\n * Whether the dropdown menu is currently open. This property reflects the\n * current state of the dropdown and can be set programmatically to open/close it.\n *\n * @default false\n * @example\n * ```javascript\n * // Open the dropdown programmatically\n * selectElement.open = true;\n *\n * // Close the dropdown\n * selectElement.open = false;\n * ```\n */\n @property({ type: Boolean, reflect: true }) accessor open = false\n\n @state() accessor selectedOption: UiOption | null = null\n @state() accessor ariaActiveDescendant: string | undefined\n @query('.menu') accessor menu!: UiMenuElement\n\n /**\n * Returns the currently selected option element. This provides access to the\n * full `ui-option` element, not just its value.\n *\n * @readonly\n * @example\n * ```javascript\n * const select = document.querySelector('ui-select');\n * const selectedItem = select.selectedItem;\n * if (selectedItem) {\n * console.log('Selected option:', selectedItem.textContent);\n * }\n * ```\n */\n get selectedItem(): UiOption | null {\n return this.selectedOption\n }\n\n /**\n * Returns the text content that should be displayed in the select field.\n * This is the rendered value of the currently selected option.\n *\n * @readonly\n * @example\n * ```javascript\n * const select = document.querySelector('ui-select');\n * console.log('Display text:', select.renderValue);\n * ```\n */\n get renderValue(): string {\n const item = this.selectedOption\n return item ? item.renderValue : ''\n }\n\n /**\n * Returns the form element that contains this select, if any.\n * Part of the form-associated custom element API.\n *\n * @readonly\n */\n get form(): HTMLFormElement | null {\n return this.#internals.form\n }\n\n /**\n * Returns the validity state of the select element.\n * Part of the form-associated custom element API.\n *\n * @readonly\n */\n get validity(): ValidityState {\n return this.#internals.validity\n }\n\n /**\n * Returns the validation message for the select element.\n * Part of the form-associated custom element API.\n *\n * @readonly\n */\n get validationMessage(): string {\n return this.#internals.validationMessage\n }\n\n /**\n * Returns whether the select element will be validated when the form is submitted.\n * Part of the form-associated custom element API.\n *\n * @readonly\n */\n get willValidate(): boolean {\n return this.#internals.willValidate\n }\n\n /**\n * Checks the validity of the select element and returns true if valid.\n * Part of the form-associated custom element API.\n *\n * @returns {boolean} True if the element is valid, false otherwise\n * @example\n * ```javascript\n * const select = document.querySelector('ui-select');\n * if (!select.checkValidity()) {\n * console.log('Select is invalid:', select.validationMessage);\n * }\n * ```\n */\n checkValidity(): boolean {\n return this.#internals.checkValidity()\n }\n\n constructor() {\n super()\n this.addEventListener('click', this.handleClick.bind(this))\n this.addEventListener('blur', this.handleBlur.bind(this))\n this.addEventListener('keydown', this.handleKeydown.bind(this))\n }\n\n override connectedCallback(): void {\n super.connectedCallback()\n this.setAttribute('role', 'combobox')\n this.setAttribute('aria-haspopup', 'listbox')\n this.setAttribute('aria-controls', 'menu')\n if (!this.disabled) {\n this.setAttribute('tabindex', '0')\n }\n if (!this.id) {\n this.id = `select-${nanoid(6)}`\n }\n }\n\n /**\n * Resets the select to its initial state. Called automatically when the parent\n * form is reset. Part of the form-associated custom element API.\n *\n * @example\n * ```javascript\n * const select = document.querySelector('ui-select');\n * select.formResetCallback(); // Clears the selection\n * ```\n */\n formResetCallback(): void {\n this.value = undefined\n }\n\n /**\n * Restores the select's state from saved form data. Called automatically when\n * the browser restores form state. Part of the form-associated custom element API.\n *\n * @param {string | null} state - The saved state to restore\n */\n formStateRestoreCallback(state: string | null): void {\n this.value = state ?? undefined\n }\n\n /**\n * Validates the select element and updates its validity state. This is called\n * automatically during property changes, but can be called manually to trigger validation.\n *\n * @example\n * ```javascript\n * const select = document.querySelector('ui-select');\n * select.validate();\n * if (select.invalid) {\n * console.log('Validation failed:', select.invalidText);\n * }\n * ```\n */\n validate(): void {\n let message = ''\n if (this.required && !this.value) {\n message = 'Please select an item.'\n this.#internals.setValidity({ valueMissing: true }, message)\n } else {\n this.#internals.setValidity({})\n }\n this.invalid = !this.#internals.validity.valid\n this.invalidText = message\n }\n\n protected override willUpdate(changedProperties: PropertyValues<this>): void {\n super.willUpdate(changedProperties)\n if (changedProperties.has('disabled')) {\n setDisabled(this, this.disabled)\n }\n if (changedProperties.has('open')) {\n this.handleOpenChange()\n }\n if (changedProperties.has('value')) {\n this.setCurrentOption()\n this.#internals.setFormValue(this.value ?? null)\n this.validate()\n }\n if (changedProperties.has('label')) {\n if (this.label) {\n this.setAttribute('aria-label', this.label)\n } else {\n this.removeAttribute('aria-label')\n }\n }\n }\n\n protected override firstUpdated(cp: PropertyValues): void {\n super.firstUpdated(cp)\n this.setCurrentOption()\n this.#internals.setFormValue(this.value ?? null)\n }\n\n protected async setCurrentOption(): Promise<void> {\n await this.updateComplete\n const options = this.querySelectorAll<UiOption>('ui-option')\n if (this.value) {\n this.selectedOption = Array.from(options).find((option) => option.value === this.value) || null\n } else {\n const selected = Array.from(options).find((option) => option.selected)\n if (selected) {\n this.selectedOption = selected\n this.#value = selected.value\n } else {\n this.selectedOption = null\n }\n }\n }\n\n protected handleKeydown(e: KeyboardEvent): void {\n if (this.disabled || e.defaultPrevented) return\n if (this.open) {\n switch (e.key) {\n case 'Tab': {\n // If menu is open and Tab is pressed, close it and allow normal tab navigation\n if (this.open) {\n this.open = false\n }\n break\n }\n case 'Escape': {\n if (this.open) {\n e.preventDefault()\n this.open = false\n this.focus() // Return focus to the select element\n }\n break\n }\n case 'ArrowDown':\n e.preventDefault()\n this.menu.highlightNext()\n return\n case 'ArrowUp':\n e.preventDefault()\n this.menu.highlightPrevious()\n return\n case 'Home':\n e.preventDefault()\n this.menu.highlightFirst()\n return\n case 'End':\n e.preventDefault()\n this.menu.highlightLast()\n return\n case 'Enter':\n case ' ':\n if (this.menu.highlightListItem) {\n e.preventDefault()\n this.menu.notifySelect(this.menu.highlightListItem as UiOption)\n }\n return\n }\n } else {\n switch (e.key) {\n case 'Enter':\n case ' ': {\n if (!this.open) {\n e.preventDefault()\n this.open = true\n }\n break\n }\n case 'ArrowDown':\n case 'ArrowUp': {\n if (!this.open) {\n e.preventDefault()\n this.open = true\n }\n // If menu is open, let the menu handle arrow keys\n break\n }\n }\n }\n }\n\n protected handleBlur(e: FocusEvent): void {\n if (this.disabled) return\n\n // Check if focus is moving to the menu or one of its children\n const relatedTarget = e.relatedTarget as HTMLElement\n\n if (relatedTarget && this.contains(relatedTarget)) {\n // Focus is moving to the menu, keep it open\n return\n }\n\n // Close the menu when focus leaves the component\n this.open = false\n }\n\n protected handleClick(e: Event): void {\n if (this.disabled || e.defaultPrevented) return\n e.preventDefault()\n e.stopPropagation()\n this.open = true\n }\n\n protected async handleOpenChange(): Promise<void> {\n const menu = this.menu\n if (!menu) {\n // The status can be set before the menu is rendered\n return\n }\n this.setAttribute('aria-expanded', String(this.open))\n if (this.open) {\n menu.showPopover()\n // menu.focus()\n if (this.selectedOption) {\n this.menu.highlightItem(this.selectedOption)\n } else {\n this.menu.highlightFirst()\n }\n this.dispatchEvent(new CustomEvent('open', { bubbles: false, composed: true }))\n this.focus()\n } else {\n menu.hidePopover()\n this.dispatchEvent(new CustomEvent('close', { bubbles: false, composed: true }))\n }\n }\n\n handleSelect(e: CustomEvent<{ item: UiOption }>): void {\n e.stopPropagation()\n const item = e.detail.item\n this.selectedOption = item\n this.#value = item.value\n this.#internals.setFormValue(this.value ?? null)\n this.open = false\n\n // Dispatch change event\n const changeEvent = new CustomEvent<UiSelectChangeEvent>('change', {\n detail: { value: this.value, item: item },\n bubbles: false,\n composed: true,\n })\n this.dispatchEvent(changeEvent)\n this.focus()\n }\n\n handleHighlightChange(e: CustomEvent<{ item: UiOption | null }>): void {\n this.ariaActiveDescendant = e.detail.item?.id\n }\n\n handleMenuClose(): void {\n this.open = false\n this.focus()\n }\n\n protected renderInput(): TemplateResult {\n const styles = {\n 'anchor-name': `--${this.id}`,\n }\n return html`<ui-outlined-text-field\n .name=${this.name}\n .label=${this.label}\n .value=${this.renderValue}\n .disabled=${this.disabled}\n .required=${this.required}\n readonly\n tabindex=\"-1\"\n .inert=${true}\n aria-hidden=\"true\"\n .invalid=${this.invalid}\n .invalidText=${this.invalidText || ''}\n .supportingText=${this.supportingText || ''}\n class=\"input\"\n style=${styleMap(styles)}\n part=\"input\"\n >\n <ui-icon part=\"icon\" slot=\"suffix\">arrow_drop_down</ui-icon>\n </ui-outlined-text-field>`\n }\n\n protected renderMenu(): TemplateResult {\n const styles = {\n 'position-anchor': `--${this.id}`,\n }\n return html`<ui-menu\n id=\"menu\"\n class=\"menu\"\n part=\"menu\"\n style=${styleMap(styles)}\n popover=\"auto\"\n selector=\"ui-option\"\n @select=\"${this.handleSelect}\"\n @close=\"${this.handleMenuClose}\"\n @highlightchange=\"${this.handleHighlightChange}\"\n >\n <slot @slotchange=\"${this.handleSlotChange}\"></slot>\n </ui-menu>`\n }\n\n protected async handleSlotChange(): Promise<void> {\n // When options change, re-evaluate the current selection\n // only if we don't have an explicit value set\n if (!this.value) {\n await this.setCurrentOption()\n this.requestUpdate()\n }\n }\n\n protected renderFocusRing(): TemplateResult {\n return html`<md-focus-ring part=\"focus-ring\" class=\"focus-ring\" .control=\"${this as HTMLElement}\"></md-focus-ring>`\n }\n\n override render(): TemplateResult {\n const classes = classMap({\n 'ui-select': true,\n 'open': this.open,\n 'disabled': this.disabled,\n })\n return html`${this.renderFocusRing()}\n <div class=\"${classes}\" aria-activedescendant=${this.ariaActiveDescendant || ''}>\n ${this.renderInput()} ${this.renderMenu()}\n </div> `\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api-client/ui",
3
- "version": "0.5.36",
3
+ "version": "0.5.38",
4
4
  "description": "Internal UI component library for the API Client ecosystem.",
5
5
  "license": "UNLICENSED",
6
6
  "main": "build/src/index.js",
@@ -51,6 +51,16 @@ export class Fragment extends EventTarget {
51
51
  return this.#renderer
52
52
  }
53
53
 
54
+ /**
55
+ * The host to be used by the FragmentRenderer to assign it to the Lit's render root.
56
+ * Whatever is assigned to this property will be used as the root element.
57
+ *
58
+ * Fragments should use this property to manipulate the event's target.
59
+ * If a fragment renders multiple children, but only one is visible,
60
+ * it should assign the host value to the currently rendered child.
61
+ */
62
+ host: Fragment = this
63
+
54
64
  constructor(options?: FragmentOptions) {
55
65
  super()
56
66
  this.parent = options?.parent
@@ -352,4 +362,40 @@ export class Fragment extends EventTarget {
352
362
  throw new Error(`Unrecognized intent event: ${event.type}`)
353
363
  }
354
364
  }
365
+
366
+ /**
367
+ * Shows a registered fragment.
368
+ * @param key The fragment's key.
369
+ * @param options Fragment rendering options.
370
+ */
371
+ async showFragment(key: string, options: { renderTarget?: HTMLElement; isHost?: boolean } = {}): Promise<void> {
372
+ if (options.isHost) {
373
+ const fragment = this.fragmentManager.findFragment(key)
374
+ if (!fragment) {
375
+ throw new Error(`Fragment with key ${key} not found.`)
376
+ }
377
+ this.host = fragment
378
+ }
379
+ await this.fragmentManager.showFragment(key, options.renderTarget)
380
+ }
381
+
382
+ /**
383
+ * Hides a fragment by its key.
384
+ * @param key The fragment's key.
385
+ */
386
+ async hideFragment(fragment: Fragment | string): Promise<void> {
387
+ let ref: Fragment | undefined
388
+ if (typeof fragment === 'string') {
389
+ ref = this.fragmentManager.findFragment(fragment)
390
+ } else {
391
+ ref = fragment as Fragment
392
+ }
393
+ if (!ref) {
394
+ throw new Error(`Fragment not found`)
395
+ }
396
+ if (this.host === ref) {
397
+ this.host = this
398
+ }
399
+ await this.fragmentManager.hideFragment(ref)
400
+ }
355
401
  }
@@ -19,12 +19,11 @@ export class FragmentRenderer extends Renderer {
19
19
  // return quietly. Fragments can be rendered directly.
20
20
  return
21
21
  }
22
- const host = this.fragment
23
22
  if (!this.firstRendered) {
24
23
  this.firstRenderedFlag = true
25
24
  this._clearRoot(root)
26
- queueMicrotask(() => host.onFirstRender())
25
+ queueMicrotask(() => this.fragment.onFirstRender())
27
26
  }
28
- this._render(host.render(), root, host)
27
+ this._render(this.fragment.render(), root, this.fragment.host)
29
28
  }
30
29
  }
@@ -490,6 +490,7 @@ export default class UiSelect extends LitElement {
490
490
  const item = e.detail.item
491
491
  this.selectedOption = item
492
492
  this.#value = item.value
493
+ this.#internals.setFormValue(this.value ?? null)
493
494
  this.open = false
494
495
 
495
496
  // Dispatch change event
@@ -8,8 +8,8 @@ import { FragmentState, FragmentManager } from '../../src/core/FragmentManager.j
8
8
  import { IntentResult, type Intent, ActivityLifecycle } from '../../src/core/ActivityManager.js'
9
9
  import { FragmentRenderer } from '../../src/core/renderer/FragmentRenderer.js'
10
10
  import { EventTypes } from '../../src/events/EventTypes.js'
11
- import { nothing, render } from 'lit'
12
- import type { ActivityDetail } from '../../src/events/IntentEvents.js'
11
+ import { nothing, render, TemplateResult } from 'lit'
12
+ import type { ActivityDetail, ActivityWithResultDetail } from '../../src/events/IntentEvents.js'
13
13
  import { ref } from 'lit/directives/ref.js'
14
14
 
15
15
  class TestActivity extends Activity {
@@ -466,7 +466,7 @@ describe('Fragment', () => {
466
466
  it('throws error if no activity for startActivityForResult', async () => {
467
467
  fragment.parent = undefined
468
468
  const event = new CustomEvent(EventTypes.Intent.startActivityForResult, {
469
- detail: {} as unknown as ActivityDetail,
469
+ detail: {} as unknown as ActivityWithResultDetail,
470
470
  })
471
471
  try {
472
472
  await fragment.handleIntentEvent(event)
@@ -487,6 +487,69 @@ describe('Fragment', () => {
487
487
  })
488
488
  })
489
489
 
490
+ describe('Child Fragment Hosting', () => {
491
+ it('sets the host when showing a child with isHost: true', async () => {
492
+ const parentFragment = new TestFragment({ parent: activity })
493
+ const childFragment = new TestFragment({ parent: parentFragment })
494
+ await parentFragment.addChild('childKey', childFragment)
495
+
496
+ await parentFragment.showFragment('childKey', { isHost: true })
497
+ assert.strictEqual(parentFragment.host, childFragment)
498
+ })
499
+
500
+ it('resets the host when hiding a host fragment', async () => {
501
+ const parentFragment = new TestFragment({ parent: activity })
502
+ const childFragment = new TestFragment({ parent: parentFragment })
503
+
504
+ await parentFragment.addChild('childKey', childFragment)
505
+ await parentFragment.showFragment('childKey', { isHost: true })
506
+
507
+ assert.strictEqual(parentFragment.host, childFragment, 'Pre-condition: host should be child')
508
+
509
+ await parentFragment.hideFragment('childKey')
510
+
511
+ assert.strictEqual(parentFragment.host, parentFragment, 'Host should be reset to the parent fragment itself')
512
+ })
513
+
514
+ it('correctly scopes event handlers to the child fragment when using isHost', async () => {
515
+ // A child fragment that has a template with an event handler.
516
+ class ChildWithHandlerFragment extends TestFragment {
517
+ handlerContext: Fragment | null = null
518
+
519
+ handleButtonClick(): void {
520
+ this.handlerContext = this
521
+ }
522
+
523
+ override render(): TemplateResult {
524
+ super.render() // for the renderSpy
525
+ return html`<button @click=${this.handleButtonClick}></button>`
526
+ }
527
+ }
528
+ const parent = new TestFragment({ parent: activity })
529
+ const child = new ChildWithHandlerFragment({ parent })
530
+ await parent.addChild('childKey', child)
531
+
532
+ // Show with isHost: true
533
+ await parent.showFragment('childKey', { isHost: true })
534
+
535
+ // Render the parent fragment
536
+ const container = await fixture<HTMLElement>(html`<div></div>`)
537
+ parent.setRenderRoot(container)
538
+ parent.requestUpdate()
539
+ await parent.renderer.updateComplete
540
+
541
+ const button = container.querySelector('button')
542
+ assert.isNotNull(button, 'Button from child fragment should be rendered')
543
+ button!.click()
544
+
545
+ assert.strictEqual(
546
+ child.handlerContext,
547
+ child,
548
+ 'Event handler `this` context should be the child fragment instance'
549
+ )
550
+ })
551
+ })
552
+
490
553
  describe('Misc', () => {
491
554
  it('rootClass returns undefined by default', () => {
492
555
  assert.isUndefined(fragment.rootClass())
@@ -274,6 +274,35 @@ describe('md', () => {
274
274
  assert.equal(formData.get('fruit'), 'apple')
275
275
  })
276
276
 
277
+ it('should update form value on selection change', async () => {
278
+ const form = await formFixture()
279
+ const select = form.querySelector('ui-select')!
280
+
281
+ // Simulate selection of 'banana'
282
+ const bananaOption = select.querySelector('ui-option[value="banana"]') as UiOption
283
+ select.handleSelect(new CustomEvent('select', { detail: { item: bananaOption } }))
284
+ await select.updateComplete
285
+
286
+ const formData = new FormData(form)
287
+ assert.equal(formData.get('fruit'), 'banana', 'Form data should be "banana" after selection')
288
+ })
289
+
290
+ it('should clear form value when value is set to undefined', async () => {
291
+ const form = await formFixture()
292
+ const select = form.querySelector('ui-select')!
293
+ select.value = 'apple'
294
+ await select.updateComplete
295
+
296
+ let formData = new FormData(form)
297
+ assert.equal(formData.get('fruit'), 'apple', 'Form data should be "apple" initially')
298
+
299
+ select.value = undefined
300
+ await select.updateComplete
301
+
302
+ formData = new FormData(form)
303
+ assert.isNull(formData.get('fruit'), 'Form data should be null after clearing value')
304
+ })
305
+
277
306
  it('should not submit when no value selected', async () => {
278
307
  const form = await formFixture()
279
308
  const formData = new FormData(form)