@marketrix.ai/widget 3.8.493 → 3.8.495

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.
Files changed (67) hide show
  1. package/README.md +4 -4
  2. package/dist/loader.js +8 -1
  3. package/dist/src/components/WidgetRoot.d.ts +19 -0
  4. package/dist/src/components/base/Avatar.d.ts +5 -2
  5. package/dist/src/components/base/Button.d.ts +1 -1
  6. package/dist/src/components/base/ErrorBoundary.d.ts +19 -0
  7. package/dist/src/components/base/Flex.d.ts +14 -0
  8. package/dist/src/components/base/Icon.d.ts +12 -1
  9. package/dist/src/components/base/IconButton.d.ts +4 -0
  10. package/dist/src/components/base/Spinner.d.ts +4 -0
  11. package/dist/src/components/base/Surface.d.ts +22 -5
  12. package/dist/src/components/base/Text.d.ts +17 -1
  13. package/dist/src/components/base/icons.d.ts +16 -0
  14. package/dist/src/components/base/layoutProps.d.ts +20 -6
  15. package/dist/src/components/blocks/ChatInput.d.ts +9 -0
  16. package/dist/src/components/blocks/HeaderBar.d.ts +4 -0
  17. package/dist/src/components/blocks/Notifications.d.ts +20 -10
  18. package/dist/src/components/blocks/WidgetDialog.d.ts +0 -5
  19. package/dist/src/components/blocks/WidgetFab.d.ts +10 -0
  20. package/dist/src/components/chat/MessageItem.d.ts +13 -0
  21. package/dist/src/components/chat/MessageList.d.ts +20 -0
  22. package/dist/src/components/chat/VideoStreamDisplay.d.ts +20 -0
  23. package/dist/src/components/navigation/ShellTabBar.d.ts +0 -1
  24. package/dist/src/components/views/ChatView.d.ts +20 -0
  25. package/dist/src/components/views/HomeView.d.ts +9 -0
  26. package/dist/src/context/ChatContext.d.ts +20 -0
  27. package/dist/src/context/UIStateContext.d.ts +5 -0
  28. package/dist/src/context/WidgetProviders.d.ts +20 -1
  29. package/dist/src/context/sseReducer.d.ts +20 -9
  30. package/dist/src/design-system/component-tokens.d.ts +27 -1
  31. package/dist/src/design-system/semantic-tokens.d.ts +18 -0
  32. package/dist/src/hooks/useDragSnap.d.ts +13 -0
  33. package/dist/src/hooks/useFocusTrap.d.ts +20 -0
  34. package/dist/src/hooks/useWidget.d.ts +11 -1
  35. package/dist/src/index.d.ts +20 -0
  36. package/dist/src/sdk/contracts/common.d.ts +0 -16
  37. package/dist/src/sdk/index.d.ts +0 -1
  38. package/dist/src/services/BrowserToolService.d.ts +22 -5
  39. package/dist/src/services/ChatService.d.ts +15 -1
  40. package/dist/src/services/ChatSessionManager.d.ts +0 -2
  41. package/dist/src/services/DomService.d.ts +18 -3
  42. package/dist/src/services/RrwebSessionRecorder.d.ts +0 -1
  43. package/dist/src/services/ShowModeService.d.ts +22 -5
  44. package/dist/src/services/StorageService.d.ts +20 -1
  45. package/dist/src/services/StreamClient.d.ts +22 -4
  46. package/dist/src/services/keySimulation.d.ts +3 -0
  47. package/dist/src/test/fixtures.d.ts +13 -2
  48. package/dist/src/test/renderWidget.d.ts +6 -0
  49. package/dist/src/test/setup.d.ts +14 -0
  50. package/dist/src/types/index.d.ts +20 -7
  51. package/dist/src/utils/chat.d.ts +21 -1
  52. package/dist/src/utils/color.d.ts +21 -0
  53. package/dist/src/utils/dom.d.ts +21 -0
  54. package/dist/src/utils/errors.d.ts +12 -0
  55. package/dist/src/utils/suggestedActions.d.ts +11 -0
  56. package/dist/src/utils/validation.d.ts +20 -7
  57. package/dist/src/utils/widgetPositioning.d.ts +20 -0
  58. package/dist/widget.mjs +63 -64
  59. package/package.json +6 -6
  60. package/dist/src/components/base/Stack.d.ts +0 -3
  61. package/dist/src/components/chat/MessageContent.d.ts +0 -8
  62. package/dist/src/components/chat/SuggestedActions.d.ts +0 -8
  63. package/dist/src/components/chat/TaskStatusIcon.d.ts +0 -5
  64. package/dist/src/components/chat/ThinkingIndicator.d.ts +0 -6
  65. package/dist/src/components/navigation/ResizeHandle.d.ts +0 -7
  66. package/dist/src/design-system/layers.d.ts +0 -7
  67. package/dist/src/design-system/shadows.d.ts +0 -9
package/README.md CHANGED
@@ -27,7 +27,7 @@ Add one `<script>` to your page `<head>`, **before any `<script type="module">`
27
27
 
28
28
  `loader.js`:
29
29
 
30
- 1. Injects a React 19 importmap (defaults to `esm.sh/react@19`). If your page already has an importmap, the loader **merges** it and your mappings win — so a host that already ships React 19 keeps its own copy.
30
+ 1. Injects a React 19 importmap pointing at `esm.sh/react@19`. If your page already has an importmap before the loader, the browser keeps your entries a later import map never overrides an earlier key — so a host that already ships React 19 keeps its own copy.
31
31
  2. Injects `<script type="module" src=".../widget.mjs">` from the same origin as the loader.
32
32
  3. Forwards every `mtx-*` attribute from the loader tag to the widget.
33
33
 
@@ -102,7 +102,7 @@ Widget **appearance and behavior** (position, colors, sizing, border radius, ani
102
102
  </html>
103
103
  ```
104
104
 
105
- The loader takes care of the React 19 importmap. If you manage your own importmap, place it before the loader and the loader will merge (and defer to) it:
105
+ The loader takes care of the React 19 importmap. If you manage your own importmap, place it before the loader; your entries win and the loader's map only fills what is missing:
106
106
 
107
107
  ```html
108
108
  <script type="importmap">
@@ -193,13 +193,12 @@ function Preview() {
193
193
  return (
194
194
  <MarketrixWidgetPreview
195
195
  settings={{ widget_enabled: true, widget_position: 'bottom_right' /* ...WidgetSettingsData */ }}
196
- mtxApiHost='https://api.marketrix.ai'
197
196
  />
198
197
  );
199
198
  }
200
199
  ```
201
200
 
202
- Props: `settings` (required), `container?`, `mtxId?`, `mtxKey?`, `mtxApiHost?`.
201
+ Props: `settings` (required) and `container?`.
203
202
 
204
203
  ---
205
204
 
@@ -217,6 +216,7 @@ TypeScript types are bundled with the package:
217
216
 
218
217
  - `MarketrixConfig` — full config for `initWidget` / `updateMarketrixConfig` (`mtxId`, `mtxKey`, `mtxApiHost`, `userId`, `show_widget`, `use_screenshare`, plus all widget appearance settings, optional).
219
218
  - `AddWidgetConfig` — discriminated config for `mountWidget` (production / preview variants + common options).
219
+ - `ClientOwnedConfig` — the host-supplied options the API never sends (`mtxApiHost`, `userId`, `widget_position_z_index`, `show_widget`, `use_screenshare`).
220
220
  - `MarketrixWidgetPreviewProps` — props for the `MarketrixWidgetPreview` component.
221
221
  - `ChatMessage`, `WidgetState`, `InstructionType` (`'tell' | 'show' | 'do'`).
222
222
 
package/dist/loader.js CHANGED
@@ -1,4 +1,11 @@
1
- // Must sit in <head> before any <script type="module"> — it defines the importmap they resolve against.
1
+ /**
2
+ * The classic script-tag bootstrap, served as `dist/loader.js`. Must sit in <head> before any
3
+ * <script type="module">: it writes the importmap those modules resolve `react`/`react-dom` against
4
+ * (esm.sh, React 19 — the bundle keeps React external and the host must supply it), then appends
5
+ * `widget.mjs` as a module script next to itself, copying every `mtx-*` attribute from its own tag so
6
+ * the widget auto-initializes with the host's settings. Plain ES5 on purpose — this file runs unbundled
7
+ * in whatever browser the host page has.
8
+ */
2
9
  (function () {
3
10
  var map = document.createElement('script');
4
11
  map.type = 'importmap';
@@ -1,3 +1,22 @@
1
+ /**
2
+ * The widget's root component: the one place the raw config prop is touched — position and z-index layered onto it
3
+ * and published through `WidgetConfigContext` — and the one place the root element is published through
4
+ * `PortalContainerContext`. Renders `MessengerShell` (inside an `ErrorBoundary`, so a panel crash still leaves the
5
+ * launcher and toasts alive), `WidgetFab`, `WidgetNotifications`, and a fixed screen-edge glow while a reply or
6
+ * task is in flight; a mount-time effect restores the drag-pinned corner and a second arms the greeting toast.
7
+ *
8
+ * The position storage key is written ONLY by a drag — seeding it with `config.widget_position` would pin the
9
+ * dashboard's setting at whatever it was on a visitor's first load — and preview mode neither reads nor writes it,
10
+ * so the dashboard always shows the configured corner. Preview mode overrides the hidden check (`show_widget:
11
+ * false` / `widget_appearance: 'hidden'` suppress the widget on a host page, but the dashboard preview must still
12
+ * render) with its `null` return sitting below every hook so hook order stays stable either way.
13
+ *
14
+ * The published z-index is `max(tenant value, LAYER_TOKENS.panel)` so a tenant's low setting cannot sink the
15
+ * widget under the host page's own stacking context. The root `Surface` IS the `[data-marketrix-widget]` element
16
+ * carrying every tenant token as an inline style, which is why it, not the shadow root, is the portal container —
17
+ * a portal landing outside it falls back to `index.css`'s hardcoded palette. `onRetry` is spread in only when
18
+ * `StreamClient.canReconnect()`, so a terminal failure offers no Retry button rather than one that does nothing.
19
+ */
1
20
  import React from 'react';
2
21
  import type { ValidWidgetConfig } from '../types';
3
22
  interface WidgetRootProps {
@@ -1,6 +1,9 @@
1
+ /**
2
+ * `Avatar` — an `<img>` sized by preset or number, with fit, radius (via `resolveLayoutStyle`) and
3
+ * elevation from the design tokens; keeps its own class beside a caller className.
4
+ */
1
5
  import type { ComponentPropsWithRef } from 'react';
2
- import { type RadiusToken } from '../../design-system/component-tokens';
3
- import type { ShadowToken } from '../../design-system/shadows';
6
+ import { type RadiusToken, type ShadowToken } from '../../design-system/component-tokens';
4
7
  type AvatarSize = 'sm' | 'md' | 'lg';
5
8
  export interface AvatarProps extends Omit<ComponentPropsWithRef<'img'>, 'size'> {
6
9
  src: string;
@@ -1,5 +1,5 @@
1
1
  import type { ComponentPropsWithRef } from 'react';
2
- import type { ShadowToken } from '../../design-system/shadows';
2
+ import { type ShadowToken } from '../../design-system/component-tokens';
3
3
  type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'bare' | 'chip' | 'tab';
4
4
  type ButtonSize = 'sm' | 'md';
5
5
  type ButtonShape = 'default' | 'pill';
@@ -1,3 +1,22 @@
1
+ /**
2
+ * The widget's one React error boundary: a subtree that throws while rendering is contained here rather than
3
+ * tearing down the widget's whole React root. It is a class because React exposes no hook equivalent.
4
+ *
5
+ * `ErrorBoundaryProps` are the wrapped `children`, a `label` naming the subtree in the console line, and an
6
+ * optional `fallback` to show in its place. `getDerivedStateFromError` flips to the caught state,
7
+ * `componentDidCatch` logs the error and the component stack, and `render` returns the fallback (or nothing)
8
+ * once caught.
9
+ *
10
+ * - The widget runs inside arbitrary customer pages, so a crash must degrade to a missing widget and never a
11
+ * broken host page. Rendering `null` with no fallback is that degradation, not a swallowed exception —
12
+ * `componentDidCatch` has already surfaced the error with its stack.
13
+ * - `console.error` specifically: terser's `drop_console` strips `log`/`info`/`debug` from the shipped
14
+ * bundle, so only `warn` and `error` reach a host page's console, and a contained render crash is the
15
+ * unexpected failure `error` is reserved for.
16
+ * - Two call sites, each deliberate: `WidgetRoot` wraps `MessengerShell` with no fallback, so a panel crash
17
+ * leaves the launcher and toasts alive, while `ChatView` wraps only the transcript with a refresh prompt,
18
+ * so one unrenderable message cannot take the composer down with it.
19
+ */
1
20
  import React from 'react';
2
21
  interface ErrorBoundaryProps {
3
22
  children: React.ReactNode;
@@ -1,7 +1,21 @@
1
+ /**
2
+ * The two flex containers over `Surface`. `Flex` is the primitive: `FlexProps` extends `SurfaceProps`
3
+ * with `direction` (`row` default, `column` opt-in) and children, and the forwardRef component spreads
4
+ * the rest onto `Surface` so the whole layout-token vocabulary still applies. `Stack` (`StackProps`) is
5
+ * that same component with `direction='column'` fixed — it lives here rather than in a file of its own
6
+ * because it is three lines of `Flex` and shares its tests.
7
+ *
8
+ * `display` is resolved here rather than left to `resolveLayoutStyle`, which `Surface` applies BEFORE
9
+ * the caller's `style`: a `display: flex` arriving later in that cascade would silently defeat
10
+ * `hidden`, so this component reads `hidden` itself and emits `none` or `flex` from the one place that
11
+ * wins.
12
+ */
1
13
  import { type ReactNode } from 'react';
2
14
  import { type SurfaceProps } from './Surface';
3
15
  export interface FlexProps extends SurfaceProps {
4
16
  direction?: 'row' | 'column';
5
17
  children?: ReactNode;
6
18
  }
19
+ export type StackProps = Omit<FlexProps, 'direction'>;
7
20
  export declare const Flex: import("react").ForwardRefExoticComponent<FlexProps & import("react").RefAttributes<HTMLElement>>;
21
+ export declare const Stack: import("react").ForwardRefExoticComponent<StackProps & import("react").RefAttributes<HTMLElement>>;
@@ -1,9 +1,20 @@
1
+ /**
2
+ * `Icon` — the widget's one SVG glyph primitive: resolves `name` in the `icons` registry and renders a
3
+ * square `<svg>` of `size` (default 16), forwarding ref and any other svg prop. An unknown name renders
4
+ * null, so a stale name degrades to a gap rather than a crash.
5
+ *
6
+ * Glyphs are decorative, so `aria-hidden` is fixed here and the accessible name belongs on the control
7
+ * wrapping the icon. A path's fill defaults to `currentColor` — unless it sets a `stroke`, where the
8
+ * default is `none`; that resolution is what lets `icons.ts`'s `stroked()` omit `fill` altogether.
9
+ * `mtx-icon` (the layout rule in `index.css`) always applies and a caller `className` is appended to it,
10
+ * never substituted — and `className` is for `blocks/` only: with no CSS framework here every class must
11
+ * have a real `index.css` rule, and `WidgetFab`'s `mtx-fab-chevron` is the sole production caller.
12
+ */
1
13
  import type { ComponentPropsWithRef } from 'react';
2
14
  import { type IconName } from './icons';
3
15
  export interface IconProps extends ComponentPropsWithRef<'svg'> {
4
16
  name: IconName;
5
17
  size?: number;
6
- /** @internal blocks/ only */
7
18
  className?: string;
8
19
  }
9
20
  export declare function Icon({ name, size, className, ref, ...props }: IconProps): import("react").JSX.Element | null;
@@ -1,3 +1,7 @@
1
+ /**
2
+ * `IconButton` — an icon-only button that REQUIRES a `label` (its aria-label), so no unnamed control
3
+ * can ship; variant and size ride as `data-*`, tone as an inline colour from `TEXT_TONE`.
4
+ */
1
5
  import type { ComponentPropsWithRef } from 'react';
2
6
  import { type TextTone } from '../../design-system/component-tokens';
3
7
  type IconButtonVariant = 'primary' | 'secondary' | 'ghost';
@@ -1,3 +1,7 @@
1
+ /**
2
+ * `Spinner` — a `role=status` ring in three sizes with a visually-hidden "Loading" label, so the
3
+ * state is announced without visible text.
4
+ */
1
5
  import type { CSSProperties, Ref } from 'react';
2
6
  type SpinnerSize = 'sm' | 'md' | 'lg';
3
7
  export interface SpinnerProps {
@@ -1,5 +1,25 @@
1
- import { type CSSProperties, type ElementType } from 'react';
2
- import type { ShadowToken } from '../../design-system/shadows';
1
+ /**
2
+ * `Surface` is the canonical container primitive: a polymorphic `forwardRef` element (`as`, default
3
+ * `div`) that composes the shared layout-token vocabulary with a `background` token, a `SHADOW`
4
+ * `elevation` token and a `paddingPreset`, all emitted as inline style. `SurfaceBackground` and
5
+ * `SurfacePadding` are those token unions, `backgroundStyles` and `paddingPresetStyles` their lookup
6
+ * tables — the `default`/`none` entries are empty, so a bare `Surface` is a plain element — and
7
+ * `SurfaceProps` the prop surface: `LayoutProps` plus the host element's HTML attributes.
8
+ *
9
+ * `className` is dropped from those attributes and re-declared because it is INTERNAL to `blocks/`:
10
+ * layout props are the styling API everywhere else, and the only legitimate classes are the
11
+ * `index.css` hooks the block components key on.
12
+ *
13
+ * Style order is fixed and load-bearing: background → padding preset → elevation → layout props →
14
+ * the caller's own `style` last, so an inline style always wins. `Flex` depends on that tail
15
+ * position, resolving `display` itself because `resolveLayoutStyle` is applied ahead of it.
16
+ *
17
+ * `resolveLayoutStyle` is handed the whole `props` (it reads only layout keys), while the DOM spread
18
+ * goes through `stripLayoutProps` — a layout token left on the props bag reaches the element as an
19
+ * unknown attribute.
20
+ */
21
+ import { type ElementType } from 'react';
22
+ import { type ShadowToken } from '../../design-system/component-tokens';
3
23
  import { type LayoutProps } from './layoutProps';
4
24
  export type SurfaceBackground = 'default' | 'card';
5
25
  export type SurfacePadding = 'none' | 'card' | 'toast';
@@ -8,9 +28,6 @@ export interface SurfaceProps extends LayoutProps, Omit<React.HTMLAttributes<HTM
8
28
  background?: SurfaceBackground;
9
29
  elevation?: ShadowToken;
10
30
  paddingPreset?: SurfacePadding;
11
- /** @internal blocks/ only */
12
31
  className?: string;
13
32
  }
14
- export declare const backgroundStyles: Record<SurfaceBackground, CSSProperties>;
15
- export declare const paddingPresetStyles: Record<SurfacePadding, CSSProperties>;
16
33
  export declare const Surface: import("react").ForwardRefExoticComponent<SurfaceProps & import("react").RefAttributes<HTMLElement>>;
@@ -1,3 +1,20 @@
1
+ /**
2
+ * `Text` — the widget's typography primitive; every rendered string goes through it.
3
+ *
4
+ * Contents: `TextProps` (prop surface, extending the rendered element's HTML attributes) · `Text`,
5
+ * which renders `as` (default `span`) and folds tone, size, weight, align, leading, block, italic
6
+ * and truncation into ONE inline style object · the `SIZE` / `WEIGHT` / `TRUNCATE` lookups it reads.
7
+ *
8
+ * Styling is inline only — the widget has no CSS framework and no `cn()`, so a variant is a style
9
+ * value here, never a class name. Tone and leading come from `design-system/component-tokens`, the
10
+ * shared home for those scales; the size, weight and truncate maps stay local because nothing but
11
+ * text reads them. Every optional prop is spread only when set, so an unset one inherits from the
12
+ * cascade rather than being pinned to a default, and the caller's `style` spreads LAST so it wins
13
+ * over every resolved token. `inheritColor` overrides `variant` and resolves to `TEXT_TONE.inherit`,
14
+ * letting text inside an already-coloured container (button, badge) take that colour.
15
+ *
16
+ * `className` is an escape hatch for `blocks/` only — product code styles through the props above.
17
+ */
1
18
  import type { ElementType, Ref } from 'react';
2
19
  import { type TextLeading } from '../../design-system/component-tokens';
3
20
  type TextVariant = 'default' | 'muted' | 'faint';
@@ -15,7 +32,6 @@ export interface TextProps extends React.HTMLAttributes<HTMLElement> {
15
32
  weight?: TextWeight;
16
33
  truncate?: boolean;
17
34
  align?: TextAlign;
18
- /** @internal blocks/ only */
19
35
  className?: string;
20
36
  ref?: Ref<HTMLElement>;
21
37
  }
@@ -1,3 +1,19 @@
1
+ /**
2
+ * Icon registry: the SVG path data behind every `<Icon name=... />`, plus the shapes Icon.tsx renders.
3
+ *
4
+ * Contents — `IconPath` (one `<path>`'s attributes; Icon.tsx forwards them field by field, so an attribute added
5
+ * here stays inert until it is forwarded there too); `IconData` (an icon's own `viewBox` plus its paths — entries
6
+ * come from source sets drawn on different grids and are never renormalized, so the viewBox travels per icon);
7
+ * `stroked()` (builds an outline path in `currentColor` with round caps and joins, strokeWidth 2 unless
8
+ * overridden); `icons` (the registry itself); `IconName` (its keys).
9
+ *
10
+ * Icon.tsx resolves an absent `fill` to 'none' when a stroke is set and to 'currentColor' otherwise, so
11
+ * a stroked path omits `fill` and a solid path omits both `fill` and `stroke`.
12
+ *
13
+ * `as const satisfies Record<string, IconData>` is load-bearing twice over: `as const` keeps `IconName` a
14
+ * literal union of the keys, and `satisfies` fails a malformed entry at compile time without widening the
15
+ * value type. The bundle is a single chunk, so every entry here is unconditional weight in each host page.
16
+ */
1
17
  export interface IconPath {
2
18
  d: string;
3
19
  fill?: string;
@@ -1,3 +1,23 @@
1
+ /**
2
+ * Layout vocabulary shared by the base components: the token props `LayoutProps` accepts,
3
+ * `resolveLayoutStyle` which reduces them to a `CSSProperties` object, and `stripLayoutProps` which
4
+ * removes them from a props bag so the remainder can be spread onto a DOM element. `SPACING_SCALE` is
5
+ * the exported `SpacingToken`→pixel table, declared smallest-first so a token name orders the same way
6
+ * as the pixels it emits (`__tests__/layoutProps.test.ts` pins that); `ALIGN`, `JUSTIFY`, `ANIMATION`
7
+ * and `BORDER_SIDE` are the private lookups for the remaining token families.
8
+ *
9
+ * Layout props resolve to a style object rather than class names: as classes they were interpolated
10
+ * (`p-${token}`), which no scanner could see, so a build-time safelist emitting the whole 8x7 matrix
11
+ * was the only thing keeping them alive and a missing entry failed silently at runtime.
12
+ * `resolveLayoutStyle` emits a property only for a prop set to a non-default value — `grow: false`,
13
+ * `shrink: true`, `border: false`, `rounded: false` and `animate: 'none'` deliberately emit nothing —
14
+ * and its `ANIMATION` values name `mtx-*` keyframes `index.css` must define
15
+ * (`__tests__/stylesheet-contract.test.ts` pins the pairing).
16
+ *
17
+ * `LAYOUT_KEYS` must list every key of `LayoutProps`: `stripLayoutProps` filters by that set, so a
18
+ * layout prop missing from it reaches the DOM as an unknown attribute. `as` and `style` are in it
19
+ * because the consuming component (`Surface`) applies them itself rather than forwarding them.
20
+ */
1
21
  import type { CSSProperties, ElementType } from 'react';
2
22
  import { type RadiusToken } from '../../design-system/component-tokens';
3
23
  export type SpacingToken = 'none' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
@@ -47,12 +67,6 @@ export interface LayoutProps {
47
67
  as?: ElementType;
48
68
  style?: CSSProperties;
49
69
  }
50
- /**
51
- * Layout props resolve to a style object rather than class names. As classes they were interpolated
52
- * (`p-${token}`), which no scanner could see — a build-time safelist was the only thing keeping them
53
- * alive, it emitted the whole 8x7 matrix whether used or not, and a missing entry failed silently at
54
- * runtime. A style object makes every token work by construction and costs nothing per unused one.
55
- */
56
70
  export declare function resolveLayoutStyle(props: LayoutProps): CSSProperties;
57
71
  export declare function stripLayoutProps<T extends LayoutProps>(props: T): Omit<T, keyof LayoutProps>;
58
72
  export {};
@@ -1,3 +1,12 @@
1
+ /**
2
+ * The widget's chat input: an auto-growing textarea with send and stop.
3
+ *
4
+ * `MAX_TEXTAREA_HEIGHT` caps growth at three lines — 20px each plus 6px of padding — after which it
5
+ * scrolls, so a long message cannot push the conversation off a small host page.
6
+ *
7
+ * `mergeRefs` combines the caller's ref with the internal one, since the component needs its own
8
+ * handle to measure and resize.
9
+ */
1
10
  import React from 'react';
2
11
  import type { InstructionType } from '../../types';
3
12
  import type { IconName } from '../base/icons';
@@ -1,3 +1,7 @@
1
+ /**
2
+ * `HeaderBar` — the panel header: Marketrix avatar, title and optional subtitle (both truncating), an
3
+ * optional controls slot, and the Close button.
4
+ */
1
5
  import React from 'react';
2
6
  interface HeaderBarProps {
3
7
  title: string;
@@ -1,17 +1,31 @@
1
+ /**
2
+ * The widget's one notification surface: a Base UI Toast provider, the toast renderer, and the effect
3
+ * that drives toasts from widget state. Base UI owns the live region, the dismiss timers, hover-to-pause
4
+ * and stacking; before this the widget announced nothing to a screen reader and ran its own setTimeout.
5
+ *
6
+ * `NotificationList` renders every live toast and stays a component of its own because `useToastManager`
7
+ * only resolves inside `Toast.Provider`; both text lines truncate through `Text`'s own prop, a toast
8
+ * carrying an action lets its title wrap instead, and a toast's `type` is a free string in Base UI, so it
9
+ * is narrowed inline to the three tones `notificationToneStyles` understands, anything else falling back
10
+ * to `neutral`. `NotificationProvider` wraps the provider, portal and viewport — `container` is the
11
+ * widget's CLOSED shadow root, since portalling to `document.body` instead would leave the injected
12
+ * styles behind, and `offsetBottom` raises the viewport above the launcher when the launcher also sits
13
+ * at the bottom, so the two cannot overlap. `useNotifications` re-exports Base UI's toast manager as the
14
+ * one door for adding and closing toasts.
15
+ *
16
+ * `WidgetNotifications` renders nothing; it mirrors the `error` and `greeting` props into toasts and
17
+ * closes them when the prop clears. Both use a STABLE id, so `add` upserts and a re-render cannot stack
18
+ * duplicates of the same condition. The error toast carries `timeout: 0` — it stays until acted on
19
+ * (dismissed or retried); only the greeting is transient.
20
+ */
1
21
  import { Toast } from '@base-ui/react/toast';
2
22
  import React from 'react';
3
23
  export declare const GREETING_TIMEOUT_MS = 8000;
4
24
  export interface NotificationProviderProps {
5
25
  children?: React.ReactNode;
6
- /** The closed shadow root to portal into — a portal to document.body would leave the styles behind. */
7
26
  container?: HTMLElement | null;
8
- /** Raised above the launcher when the launcher sits at the bottom, so the two cannot overlap. */
9
27
  offsetBottom?: number;
10
28
  }
11
- /**
12
- * The one notification surface. Base UI owns the live region, the dismiss timers, hover-to-pause and
13
- * stacking; before this the widget announced nothing to a screen reader and ran its own setTimeout.
14
- */
15
29
  export declare const NotificationProvider: React.FC<NotificationProviderProps>;
16
30
  export declare const useNotifications: typeof Toast.useToastManager;
17
31
  export interface WidgetNotificationsProps {
@@ -22,8 +36,4 @@ export interface WidgetNotificationsProps {
22
36
  greetingBody?: string;
23
37
  onGreetingDismiss: () => void;
24
38
  }
25
- /**
26
- * Drives the toasts from widget state. Both use a stable id, so `add` upserts and a re-render cannot
27
- * stack duplicates of the same condition.
28
- */
29
39
  export declare const WidgetNotifications: React.FC<WidgetNotificationsProps>;
@@ -7,11 +7,6 @@ export interface WidgetDialogProps {
7
7
  onConfirm?: () => void;
8
8
  confirmLabel?: string;
9
9
  cancelLabel?: string;
10
- /**
11
- * Where focus lands on close. Base UI's default restore is broken here: it descends
12
- * `element.shadowRoot.activeElement`, which is null for a CLOSED root, so it records the shadow
13
- * HOST and hands focus to a host-page element on close. Naming the target sidesteps that.
14
- */
15
10
  finalFocusRef?: React.RefObject<HTMLElement | null>;
16
11
  }
17
12
  export declare const WidgetDialog: React.FC<WidgetDialogProps>;
@@ -1,3 +1,13 @@
1
+ /**
2
+ * `WidgetFab` — the launcher button: draggable via `useDragSnap`, positioned at the configured corner,
3
+ * glowing while a reply or task is in flight, and showing the stop control while a task runs and the
4
+ * panel is closed. Colours and z-index come from the tenant config; `pointerEvents: none` while open so
5
+ * the panel beneath receives the clicks.
6
+ *
7
+ * Glow and activity ring are ONE class each, red or green keyed on the `data-tone` the error state
8
+ * picks — the same data-attribute variant convention every other component here uses. The two icon
9
+ * layers carry only their own transform and opacity; the transition they share is `.mtx-fab-icon-layer`.
10
+ */
1
11
  import React from 'react';
2
12
  import type { WidgetPosition } from '../../types';
3
13
  interface WidgetFabProps {
@@ -1,3 +1,16 @@
1
+ /**
2
+ * One transcript row and everything drawn inside it. `MessageItem` renders a system message centred and
3
+ * faint, or a user/agent row with a leading glyph (a pointer for show/do requests, a check for a
4
+ * screen-access request or a waiting-for-user placeholder), the sender label as an aria-label, the body,
5
+ * the allow/deny controls of a screen-access request, and a done/failed/stopped glyph in the tenant
6
+ * accent at a per-status opacity. The last message fades in.
7
+ *
8
+ * `MessageBody` renders the message's `parts` — text and progress lines — and `Thinking` is the
9
+ * spinner-and-caption row shown while a reply is pending, its caption switching to name the visitor's
10
+ * action when the agent is blocked on them. Thinking shows while a placeholder carries no text yet, and
11
+ * also while the task is still running on the LAST show/do message, where text has already arrived but
12
+ * more work is coming; a message with no parts at all falls back to a bare `Surface`.
13
+ */
1
14
  import React from 'react';
2
15
  import type { ChatMessage } from '../../types';
3
16
  interface MessageItemProps {
@@ -1,3 +1,23 @@
1
+ /**
2
+ * The chat transcript pane: a scrolling `role='log'` list of `MessageItem`s with the "Clear conversation"
3
+ * action beneath it and two floating scroll affordances layered over it.
4
+ *
5
+ * `scrollButtonStyle` is the card-on-surface look shared by both affordances. `MessageListProps` carries
6
+ * the end-of-list anchor ref owned by `ChatView` plus the screen-access answers, forwarded only to
7
+ * `MessageItem`. `MessageList` prepends a greeting message built from `widget_body` through the shared
8
+ * `createAgentMessage`, the one home for a `ChatMessage`; it never enters the store, which is why
9
+ * "Clear conversation" is gated on `messages.length` rather than on the rendered list. `handleScroll` derives both affordances from container geometry — top once scrolled past
10
+ * 200px, bottom while the list overflows and sits more than 50px off the end. The transcript paints
11
+ * `widget_background_color` through `backgroundGradient`, the one home for that expansion, zeroing
12
+ * `backgroundColor` for a gradient setting so the two declarations cannot fight.
13
+ *
14
+ * Every scroll is suppressed in preview mode: there the widget is embedded in the dashboard's modal, and
15
+ * `scrollIntoView` would scroll that parent modal rather than this list. The scroll on a new message waits
16
+ * a `requestAnimationFrame` so layout has settled before it fires. A streaming reply arrives as
17
+ * `chat/delta` fragments that grow the last message in place without changing the message count, so a
18
+ * second effect keys on that message's content length and re-pins to the bottom only while the reader is
19
+ * already within 120px of it — a reader who scrolled away is left where they are.
20
+ */
1
21
  import React from 'react';
2
22
  interface MessageListProps {
3
23
  messagesEndRef: React.RefObject<HTMLDivElement | null>;
@@ -1,3 +1,23 @@
1
+ /**
2
+ * Inline screen-share viewport for a chat message: a live MediaStream as a muted, auto-playing <video>
3
+ * under a loading overlay, a failure overlay, a "Live" pill and a persistent banner. `Overlay` is the
4
+ * centred full-bleed scrim carrying a spinner or icon above a caption, shared by the loading and failure
5
+ * states; `VideoStreamDisplay` binds the stream, tracks loaded/failed and layers the rest over it.
6
+ *
7
+ * The bind effect is keyed on `stream`: a replacement clears both flags and rebinds the
8
+ * `loadedmetadata`/`error` listeners, and cleanup nulls `srcObject` so a stopped stream is not retained.
9
+ * `play()` rejecting with AbortError is exactly that replacement racing the previous play — the one
10
+ * benign rejection; anything else is logged with its error and surfaced as the failure overlay.
11
+ * `muted` + `autoPlay` is what makes autoplay legal without a user gesture, and `playsInline` stops iOS
12
+ * Safari taking the stream fullscreen over the host page. The video stays mounted at opacity 0 while
13
+ * loading, since unmounting it leaves nothing for `loadedmetadata` to fire on.
14
+ *
15
+ * Corners are rounded on top only because `MessageItem` collapses the bubble padding to 0 for a video
16
+ * message, so this sits flush in the bubble's top corners. Stacking is deliberate — overlays 10, Live
17
+ * pill 20, banner 30 — and the banner is `pointerEvents: 'none'` so its full-bleed wrapper never
18
+ * swallows clicks meant for the message. The pulsing dot in the Live pill is the shared `mtx-live-dot`,
19
+ * the same one the header's screen-share button wears; it paints in `currentColor`.
20
+ */
1
21
  import React from 'react';
2
22
  interface VideoStreamDisplayProps {
3
23
  stream: MediaStream;
@@ -1,3 +1,2 @@
1
1
  import React from 'react';
2
- /** Selection, roles, ids and arrow-key navigation come from Tabs.Root — see MessengerShell. */
3
2
  export declare const ShellTabBar: React.FC;
@@ -1,3 +1,23 @@
1
+ /**
2
+ * The messenger panel's chat view: the scrolling transcript, the composer, and the screen-access
3
+ * dialog that gates Show/Do.
4
+ *
5
+ * `ChatViewProps` are the shell's three wires — a screen-sharing flag lifted to the header, a ref the
6
+ * shell's toolbar button fills with a share toggle, and the composer textarea ref. `MODES` pairs the
7
+ * mode chips' display order with the tenant setting enabling each, so the composer offers only what
8
+ * the workspace turned on. `ChatView` owns the draft text; `handleSendMessage` posts the turn and
9
+ * `handleModeChange` announces a mode switch in the transcript before flipping state.
10
+ *
11
+ * The composer is locked both while a reply is outstanding and while a screen-access request is open,
12
+ * since a second turn queued behind an unanswered permission card has nowhere to land. `use_screenshare`
13
+ * absent means enabled; only an explicit `false` skips the ask — Show and Do request screen access first
14
+ * unless a share is already live, and `useScreenShare` flushes the held turn on every outcome. This view
15
+ * writes the user's bubble itself, so every dispatch from here is `skipUserMessage`. Stop tears down
16
+ * `showModeService` before `stopTask`, since an in-flight highlight owns listeners, a watchdog and
17
+ * injected nodes that outlive the task otherwise. `WidgetDialog` gets an explicit `finalFocusRef`
18
+ * since Base UI's focus restore resolves to the host page inside a closed shadow root otherwise. The
19
+ * transcript sits under its own `ErrorBoundary` so one unrenderable message can't take the composer down.
20
+ */
1
21
  import React from 'react';
2
22
  interface ChatViewProps {
3
23
  onScreenSharingChange: (isSharing: boolean) => void;
@@ -1,3 +1,12 @@
1
+ /**
2
+ * `HomeView` — the opening screen: tenant greeting and body, the Ask-a-question button that switches to
3
+ * the chat view, the suggested-action chips (`getSuggestedActionsFromConfig`), which navigate and dispatch
4
+ * in one click, and a card linking back into a conversation already in progress.
5
+ *
6
+ * Chip captions render VERBATIM in the tenant text colour: a `show`/`do` caption doubles as the
7
+ * instruction dispatched on click and is given its mode prefix in the config layer, so prefixing here
8
+ * would double it.
9
+ */
1
10
  import React from 'react';
2
11
  import { type SuggestedActionItem } from '../../utils/suggestedActions';
3
12
  interface HomeViewProps {
@@ -1,3 +1,23 @@
1
+ /**
2
+ * React context owning the widget's chat store and its live SSE wiring: one committed `{messages, task}`
3
+ * state and the `ChatActions`/`TaskActions` mutators reached through `useChatContext`, which throws
4
+ * outside `ChatProvider`. Messages and task share ONE object so they cannot tear across an await.
5
+ *
6
+ * `commit` is the ONLY writer of the `stateRef` mirror — re-syncing from render could regress it between a
7
+ * commit and its paint — and runs the transition synchronously, not inside a `setState` updater: React
8
+ * defers updaters and loses the effects captured in them, so tool calls never execute. `messageDispatch`
9
+ * POSTs fire-and-forget: the reply arrives over SSE, so only a POST failure resolves the placeholder
10
+ * locally, and a stale-reply watchdog keyed on id AND part count re-arms on every progress line.
11
+ *
12
+ * The stream effect subscribes to the `StreamClient` singleton: `handleMessage` does the bookkeeping the
13
+ * pure reducer cannot hold (`tool_call_id` dedupe in a bounded set, cleared on a terminal status), then
14
+ * each effect runs its browser tool, stamps progress, replies `tool/response` and only then fires
15
+ * `afterResponseAttempt`. `handleError` converts only a `StreamGaveUpError` into a transport failure, as a
16
+ * retriable blip settles when the reply lands on the reconnected stream. `stopTask` sends `chat/stop`,
17
+ * which carries no task id. Every failure on the tool and stop paths reaches `uiActions.setError` as well
18
+ * as the console: an undelivered `tool/response` leaves the agent waiting on a reply that never comes, so
19
+ * the run stalls with nothing on screen unless the visitor is told, and `do` mode may still be clicking.
20
+ */
1
21
  import React from 'react';
2
22
  import type { ChatMessage, InstructionType } from '../types';
3
23
  import { type TaskState } from './sseReducer';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * `UIStateProvider` / `useUIStateContext` — the widget's view state: open/closed, active view, current
3
+ * mode (tell/show/do) and the error banner. Actions are stable (memoised once) so consumers can depend
4
+ * on them without re-rendering; `applyState` merges a partial for restore-from-storage.
5
+ */
1
6
  import React from 'react';
2
7
  import type { InstructionType, WidgetView } from '../types';
3
8
  export interface UIState {
@@ -1,5 +1,24 @@
1
+ /**
2
+ * The widget's provider stack and the two bridges under it: `WidgetProviders` wraps children in
3
+ * `UIStateProvider` → `ChatProvider` → `InitBridge`, so everything below reads UI state and the chat
4
+ * store from context. Also home to `PortalContainerContext`/`usePortalContainer` — `WidgetRoot`
5
+ * publishes its own root here, since a portal landing outside it escapes the element carrying the
6
+ * tenant tokens and falls back to `index.css`'s hardcoded palette; the default is `document.body`.
7
+ *
8
+ * `InitBridge` runs the one-shot mount init: read the stored snapshot, apply `{currentMode, isOpen}`
9
+ * to UI state and the transcript to the chat store, then get-or-create the chat_id and open the stream.
10
+ * Task state is deliberately not restored — a run never survives a reload. `PersistBridge` writes the
11
+ * snapshot back on every message or UI-state change; it is its own component so subscribing to every
12
+ * message change can't re-render the tree `InitBridge` wraps, and mounts only once `restored` is true —
13
+ * mounted before the read, its first effect would overwrite the stored transcript on every remount.
14
+ * `previewMode` skips init entirely: no chat session is minted, no stream opened, nothing persisted.
15
+ *
16
+ * The init effect's deps are empty on purpose — once per mount — and `cancelled` drops the connect when
17
+ * a StrictMode double-invoke or an unmount cleans up before the chat_id resolves. A failed connect is
18
+ * logged only, since `StreamClient` owns the backoff reconnect; a failed init is logged AND surfaced
19
+ * through `uiActions.setError`.
20
+ */
1
21
  import React from 'react';
2
- /** WidgetRoot publishes its own root here: a portal outside it escapes the element carrying the tenant tokens. */
3
22
  export declare const PortalContainerContext: React.Context<HTMLElement | null>;
4
23
  export declare const usePortalContainer: () => HTMLElement;
5
24
  interface WidgetProvidersProps {