@marketrix.ai/widget 4.0.110 → 4.0.111

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.
@@ -1,27 +1,21 @@
1
1
  /**
2
2
  * `Surface` is the canonical container primitive: a polymorphic `forwardRef` element (`as`, default
3
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.
4
+ * `elevation` token and a `paddingPreset`, all emitted as inline style — the `default`/`none` lookup
5
+ * entries are empty, so a bare `Surface` is a plain element. `className` is dropped from the host
6
+ * attributes and re-declared because it is INTERNAL to `blocks/`: layout props are the styling API
7
+ * everywhere else, and the only legitimate classes are the `index.css` hooks the block components key on.
8
8
  *
9
9
  * `floatingCard` is a `variant` shorthand for the card-background/border/card-elevation/card-padding/xl-
10
10
  * rounded/margin bundle both `HomeView`'s recent-conversation card and `ChatView`'s composer card use —
11
11
  * the margin lives in `variantStyles` since both call sites want it, while `ChatView`'s extra
12
12
  * `marginTop: 'auto'` stays an override on its own `style` prop rather than joining the preset.
13
13
  *
14
- * `className` is dropped from those attributes and re-declared because it is INTERNAL to `blocks/`:
15
- * layout props are the styling API everywhere else, and the only legitimate classes are the
16
- * `index.css` hooks the block components key on.
17
- *
18
- * Style order is fixed and load-bearing: background padding preset elevation layout props
19
- * the caller's own `style` last, so an inline style always wins. `Flex` depends on that tail
20
- * position, resolving `display` itself because `resolveLayoutStyle` is applied ahead of it.
21
- *
22
- * `resolveLayoutStyle` is handed the whole `props` (it reads only layout keys), while the DOM spread
23
- * goes through `stripLayoutProps` — a layout token left on the props bag reaches the element as an
24
- * unknown attribute.
14
+ * Style order is fixed and load-bearing: background padding preset elevation layout props → the
15
+ * caller's own `style` last, so an inline style always wins; `Flex` depends on that tail position,
16
+ * resolving `display` itself because `resolveLayoutStyle` is applied ahead of it. `resolveLayoutStyle`
17
+ * is handed the whole `props` (it reads only layout keys), while the DOM spread goes through
18
+ * `stripLayoutProps` a layout token left on the props bag reaches the element as an unknown attribute.
25
19
  */
26
20
  import { type ElementType } from 'react';
27
21
  import { type ShadowToken } from '../../design-system/component-tokens';
@@ -3,25 +3,23 @@
3
3
  * `resolveLayoutStyle` which reduces them to a `CSSProperties` object, and `stripLayoutProps` which
4
4
  * removes them from a props bag so the remainder can be spread onto a DOM element. `SPACING_SCALE` is
5
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.
6
+ * as the pixels it emits.
8
7
  *
9
8
  * 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).
9
+ * (`p-${token}`), which no scanner could see, so a build-time safelist emitting the whole 8x7 matrix was
10
+ * the only thing keeping them alive and a missing entry failed silently at runtime. `resolveLayoutStyle`
11
+ * emits a property only for a prop set to a non-default value (`grow: false`, `shrink: true`, `border:
12
+ * false`, `rounded: false` and `animate: 'none'` deliberately emit nothing), and its `ANIMATION` values
13
+ * name `mtx-*` keyframes `index.css` must define.
16
14
  *
17
15
  * `LAYOUT_KEYS` must list every key of `LayoutProps`: `stripLayoutProps` filters by that set, so a
18
16
  * layout prop missing from it reaches the DOM as an unknown attribute. `as` and `style` are in it
19
17
  * because the consuming component (`Surface`) applies them itself rather than forwarding them.
20
18
  *
21
- * `withClass(base, extra)` appends an optional caller `className` to a component's fixed base class
22
- * (`Button`, `Icon`, `Avatar`). It is NOT the banned `cn()`: there is no variant list to merge or
23
- * dedup, just a plain conditional concat of one fixed string and one optional string — variants stay
24
- * on `data-*` attributes per the styling rule in `../../../CLAUDE.md`.
19
+ * `withClass(base, extra)` appends an optional caller `className` to a component's fixed base class. It
20
+ * is NOT the banned `cn()`: there is no variant list to merge or dedup, just a plain conditional concat
21
+ * of one fixed string and one optional string — variants stay on `data-*` attributes per the styling
22
+ * rule in `../../../CLAUDE.md`.
25
23
  */
26
24
  import type { CSSProperties, ElementType } from 'react';
27
25
  import { type RadiusToken } from '../../design-system/component-tokens';
@@ -1,23 +1,20 @@
1
1
  /**
2
2
  * Focus trap for the messenger panel: while `isActive`, focus starts inside `containerRef`, Tab cycles
3
3
  * within it, Escape calls `onEscape`, and on deactivation focus returns to whatever held it before.
4
- *
5
- * The tabbable candidates come from `utils/dom`'s shared `focusablesIn` (built on `TABBABLE_SELECTOR`,
6
- * visibility and `aria-hidden` ancestry the same filter `keySimulation`'s Tab simulation uses, so the
7
- * widget's own tab order and the host page's can't re-diverge); `activeElementIn` reads the focused
8
- * element as seen from a container's own root; and `useFocusTrap(containerRef, isActive, {onEscape,
9
- * focusTargetRef})` focuses `focusTargetRef` (else the first focusable), installs one capture-phase
10
- * `keydown` listener on `document`, and restores focus on the active→inactive edge.
4
+ * `useFocusTrap(containerRef, isActive, {onEscape, focusTargetRef})` focuses `focusTargetRef` (else the
5
+ * first focusable), installs one capture-phase `keydown` listener on `document`, and restores focus on
6
+ * the active→inactive edge. The tabbable candidates come from `utils/dom`'s shared `focusablesIn`, the
7
+ * same filter `keySimulation`'s Tab simulation uses, so the widget's own tab order and the host page's
8
+ * can't re-diverge.
11
9
  *
12
10
  * Inside the widget's closed shadow root `document.activeElement` retargets to the HOST, never naming
13
11
  * an element of the widget's own tree; `activeElementIn` reads through `container.getRootNode()`
14
12
  * instead and is the ONE home for that retargeting — eslint's `no-restricted-properties` bans the bare
15
- * read everywhere else. Hand-rolled on purpose: `MessengerShell` is a NON-modal panel, not a Dialog,
16
- * and Base UI exposes no standalone focus trap; reaching it by making the panel a Dialog would inert
17
- * the customer's page. Both key arms bail unless focus is currently inside the container, since the
13
+ * read everywhere else. Hand-rolled on purpose: `MessengerShell` is a NON-modal panel, not a Dialog, and
14
+ * Base UI exposes no standalone focus trap; reaching it by making the panel a Dialog would inert the
15
+ * customer's page. Both key arms bail unless focus is currently inside the container, since the
18
16
  * listener sits on `document` ahead of host-page handlers and an unguarded Escape would close the
19
- * widget mid-typing. Tab `preventDefault`s only at the two ends; `previousActiveRef` edge-triggers the
20
- * restore once on close.
17
+ * widget mid-typing.
21
18
  */
22
19
  export declare function useFocusTrap(containerRef: React.RefObject<HTMLElement | null>, isActive: boolean, options?: {
23
20
  onEscape?: () => void;
@@ -1,29 +1,27 @@
1
1
  /**
2
2
  * Predicates the agent's element index runs against the HOST page's DOM — what counts as a control and
3
- * whether it is reachable — plus `WIDGET_SHADOW_HOST_CLASS`, set by `bootstrap` on the shadow host so
4
- * `DomService` can recognise its own overlay chrome instead of reporting it as obscuring the host page, and
5
- * `TABBABLE_SELECTOR`, the one tab-order candidate query: `send_keys`' Tab simulation walks the host page
6
- * with it and `useFocusTrap` the widget's own tree, and they must agree on what the browser would focus next.
3
+ * whether it is reachable. `TABBABLE_SELECTOR` is the one tab-order candidate query: `send_keys`'s Tab
4
+ * simulation walks the host page with it and `useFocusTrap` the widget's own tree, and they must agree
5
+ * on what the browser would focus next. `WIDGET_SHADOW_HOST_CLASS`, set by `bootstrap` on the shadow
6
+ * host, lets `DomService` recognise its own overlay chrome instead of reporting it as obscuring the host
7
+ * page.
7
8
  *
8
- * `ancestry` walks element → `parentElement`, crossing each shadow boundary at its host; a bare
9
- * `parentElement` walk stops dead at a `ShadowRoot`, so a control inside a host-page web component
10
- * would read as top-level. `disabledReason` names why an element cannot be operated (disabled control,
11
- * `aria-disabled`, or an `inert` ancestor) as a sentence fragment completing `DomService`'s
12
- * `Element <n> …` message — reword both together; `disabled` is read duck-typed since it sits on
13
- * several unrelated control interfaces. `isIndexable`, checked against `INTERACTIVE_ROLES`, is
14
- * `DomService`'s geometry-aware fallback after its cheap selector/handler checks. Visibility there is more
15
- * than computed style: an element scrolled out of an `overflow: hidden|clip` ancestor is unreachable despite
16
- * a non-zero rect (that walk stops at `document.body`), and a zero-size shadow host hides its whole tree, so
17
- * both chains are climbed. Its one `try` is deliberate — the host page owns this DOM and may have patched
18
- * anything on it, so a poisoned element is logged with the real error and skipped rather than aborting the
19
- * whole indexing pass.
9
+ * `ancestry` walks element → `parentElement`, crossing each shadow boundary at its host, since a bare
10
+ * `parentElement` walk stops dead at a `ShadowRoot` and a control inside a host-page web component would
11
+ * read as top-level. `disabledReason` names why an element cannot be operated (disabled control,
12
+ * `aria-disabled`, or an `inert` ancestor) as a sentence fragment completing `DomService`'s `Element
13
+ * <n> …` message — reword both together. `isIndexable` is `DomService`'s geometry-aware fallback after
14
+ * its cheap selector/handler checks; visibility there climbs both the `overflow: hidden|clip` chain
15
+ * (that walk stops at `document.body`) and the shadow-host size, since either can hide an element
16
+ * despite a non-zero rect. Its one `try` is deliberate the host page owns this DOM and may have
17
+ * patched anything on it, so a poisoned element is logged with the real error and skipped rather than
18
+ * aborting the whole indexing pass.
20
19
  *
21
20
  * `focusablesIn` is the one home for "which `TABBABLE_SELECTOR` matches are actually reachable" —
22
- * `useFocusTrap` (the widget's own tree) and `keySimulation`'s Tab simulation (the host page) both call
23
- * it so they can't re-diverge. Per WAI-ARIA, `aria-hidden="true"` removes an element (and its whole
24
- * subtree) from the accessibility tree, so it must not receive focus `isAriaHidden` walks ancestors,
25
- * not just the element itself, since a hidden container hides everything under it even though none of
26
- * those descendants carry the attribute.
21
+ * `useFocusTrap` and `keySimulation`'s Tab simulation both call it so they can't re-diverge.
22
+ * `isAriaHidden` walks ancestors, not just the element itself, since a hidden container hides everything
23
+ * under it (per WAI-ARIA, `aria-hidden="true"` removes an element and its whole subtree from the
24
+ * accessibility tree) even though none of those descendants carry the attribute.
27
25
  */
28
26
  export declare const WIDGET_SHADOW_HOST_CLASS = "marketrix-widget-container";
29
27
  export declare const TABBABLE_SELECTOR = "a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marketrix.ai/widget",
3
- "version": "4.0.110",
3
+ "version": "4.0.111",
4
4
  "type": "module",
5
5
  "packageManager": "bun@1.4.2",
6
6
  "sideEffects": false,