diff --git a/apps/website/content/docs/chat/api/api-docs.json b/apps/website/content/docs/chat/api/api-docs.json index 3a3e7f46..ecc3b6e9 100644 --- a/apps/website/content/docs/chat/api/api-docs.json +++ b/apps/website/content/docs/chat/api/api-docs.json @@ -273,7 +273,7 @@ }, { "name": "distribution", - "type": "InputSignal<\"center\" | \"start\" | \"end\" | \"spaceBetween\" | \"spaceAround\" | \"spaceEvenly\">", + "type": "InputSignal<\"start\" | \"center\" | \"end\" | \"spaceBetween\" | \"spaceAround\" | \"spaceEvenly\">", "description": "", "optional": false }, @@ -632,7 +632,7 @@ "properties": [ { "name": "alignment", - "type": "InputSignal<\"center\" | \"start\" | \"end\" | \"stretch\" | undefined>", + "type": "InputSignal<\"start\" | \"center\" | \"end\" | \"stretch\" | undefined>", "description": "v1 canonical prop: cross-axis alignment.", "optional": false }, @@ -2199,6 +2199,58 @@ } ] }, + { + "name": "ChatConnectedOverlayDirective", + "kind": "class", + "description": "Applied to an ``. When `chatOverlayOpen` is true, the template\ncontent is portaled into the shared body-level overlay container and\npositioned connected to `chatOverlayOrigin`, repositioning live on\nscroll/resize. Closes on outside mousedown (via the `chatOverlayOutsideClick`\noutput) and Tab; returns focus to the origin when focus was inside the pane.\n\nNOTE: the directive does not own the open state — it only emits. To fully\nclose the overlay, consumers MUST handle BOTH `(chatOverlayOutsideClick)` and\n`(chatOverlayDetach)`. Tab-close (and Escape, when the consumer routes it)\nsurface through `chatOverlayDetach`, so wiring only `chatOverlayOutsideClick`\nleaves the overlay stuck open on Tab.", + "params": [], + "examples": [], + "properties": [ + { + "name": "attached", + "type": "OutputEmitterRef", + "description": "Emits the pane element once attached (consumers focus content from it).", + "optional": false + }, + { + "name": "detached", + "type": "OutputEmitterRef", + "description": "", + "optional": false + }, + { + "name": "open", + "type": "InputSignal", + "description": "", + "optional": false + }, + { + "name": "origin", + "type": "InputSignal>", + "description": "", + "optional": false + }, + { + "name": "outsideClick", + "type": "OutputEmitterRef", + "description": "", + "optional": false + }, + { + "name": "panelClass", + "type": "InputSignal", + "description": "", + "optional": false + }, + { + "name": "positions", + "type": "InputSignal", + "description": "", + "optional": false + } + ], + "methods": [] + }, { "name": "ChatErrorComponent", "kind": "class", @@ -2875,6 +2927,22 @@ } ] }, + { + "name": "ChatOverlayOriginDirective", + "kind": "class", + "description": "Marks the anchor element a connected overlay positions against.", + "params": [], + "examples": [], + "properties": [ + { + "name": "elementRef", + "type": "ElementRef", + "description": "", + "optional": false + } + ], + "methods": [] + }, { "name": "ChatPopupComponent", "kind": "class", @@ -3281,7 +3349,7 @@ { "name": "ChatSelectComponent", "kind": "class", - "description": "Generic single-select dropdown. Designed to slot into the chat input pill\n(via [chatInputModelSelect]) but usable anywhere.\n\nThe popover is rendered through a CDK connected overlay (a body-level portal)\nrather than an absolutely-positioned child, so it is never clipped by an\nancestor's `overflow` and never trapped by an ancestor `transform` (e.g. a\nsliding chat-sidebar panel). CDK's flexible position strategy flips and\nshifts the menu to keep it inside the viewport.\n\nInputs:\n options — array of { value, label, disabled? }; required\n value — currently selected value (two-way via model())\n placeholder — trigger label when no option matches; default 'Select'\n disabled — disables the trigger; default false\n menuLabel — aria-label for the popover; defaults to placeholder\n panelClass — extra class(es) on the overlay panel, for consumer styling\n (the menu is portaled to the body, so `::ng-deep chat-select\n .chat-select__menu` no longer reaches it — target the panel\n class instead).", + "description": "Generic single-select dropdown. The menu renders through the chat\nconnected-overlay primitive (a body-level portal), so it is never clipped by\nan ancestor's `overflow` and never trapped by an ancestor `transform`.\n\nInputs: options (required), value (two-way), placeholder, disabled, menuLabel,\npanelClass (extra class(es) on the overlay pane — the menu is portaled, so\n`::ng-deep chat-select .chat-select__menu` no longer reaches it).", "params": [], "examples": [], "properties": [ @@ -3297,6 +3365,12 @@ "description": "", "optional": false }, + { + "name": "menuId", + "type": "string", + "description": "", + "optional": false + }, { "name": "menuLabel", "type": "InputSignal", @@ -3347,6 +3421,19 @@ } ], "methods": [ + { + "name": "onAttached", + "signature": "onAttached(pane: HTMLElement): void", + "description": "", + "params": [ + { + "name": "pane", + "type": "HTMLElement", + "description": "", + "optional": false + } + ] + }, { "name": "onMenuKeydown", "signature": "onMenuKeydown(e: KeyboardEvent): void", @@ -6310,6 +6397,50 @@ ], "examples": [] }, + { + "name": "ConnectedPosition", + "kind": "interface", + "description": "", + "properties": [ + { + "name": "offsetX", + "type": "number", + "description": "", + "optional": true + }, + { + "name": "offsetY", + "type": "number", + "description": "", + "optional": true + }, + { + "name": "originX", + "type": "HorizontalConnectionPos", + "description": "", + "optional": false + }, + { + "name": "originY", + "type": "VerticalConnectionPos", + "description": "", + "optional": false + }, + { + "name": "overlayX", + "type": "HorizontalConnectionPos", + "description": "", + "optional": false + }, + { + "name": "overlayY", + "type": "VerticalConnectionPos", + "description": "", + "optional": false + } + ], + "examples": [] + }, { "name": "ContentClassifier", "kind": "interface", @@ -6741,6 +6872,32 @@ ], "examples": [] }, + { + "name": "OverlayPositionResult", + "kind": "interface", + "description": "", + "properties": [ + { + "name": "left", + "type": "number", + "description": "", + "optional": false + }, + { + "name": "position", + "type": "ConnectedPosition", + "description": "", + "optional": false + }, + { + "name": "top", + "type": "number", + "description": "", + "optional": false + } + ], + "examples": [] + }, { "name": "ParseTreeStore", "kind": "interface", diff --git a/libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts b/libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts index 38185161..5c90457b 100644 --- a/libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts +++ b/libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts @@ -1,5 +1,11 @@ // libs/chat/src/lib/primitives/overlay/connected-overlay.directive.ts // SPDX-License-Identifier: MIT +/* eslint-disable @angular-eslint/no-input-rename, @angular-eslint/no-output-rename -- + * The `chatOverlay*` binding aliases ARE the intended public API: they namespace + * the directive's inputs/outputs under the `chatOverlay` prefix (mirroring Angular + * CDK's `cdkConnectedOverlay*` convention) rather than exposing bare names like + * `open`/`positions` on an ``. The internal property names stay + * concise, so aliasing here is deliberate, not a rename to avoid. */ import { DestroyRef, Directive,