@mt-gloss/ui 0.0.18 → 0.0.20

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.
@@ -6,9 +6,14 @@ import { QuickConfigPanelProps } from './types';
6
6
  * Provides header + pill-menu chrome (Save / Cancel buttons).
7
7
  *
8
8
  * D-01: Generic — no reptime/entityType/metricInfo domain knowledge.
9
- * D-03: Panel width uses CSS var `--gloss-slot-width` (MetricGroupContainer slot sizing reuse; 180px fallback).
10
9
  * D-19: NOT a modal — role is not "dialog"; no aria-modal; no focus trap.
11
10
  * AN-01: `will-change: transform` on root element; panel transitions use transform/opacity only.
11
+ *
12
+ * Positioning (WR-03): the panel is CONSUMER-POSITIONED — placement is driven
13
+ * by the parent grid (CSS-grid placement adjacent to the active card) or by
14
+ * a wrapper element the consumer supplies. `anchorRect` is retained as an
15
+ * opaque pass-through for diagnostics; this component does NOT compute
16
+ * translate(x, y) from it. Width is sized via `--gloss-slot-width` (180px
17
+ * fallback) from the MetricGroupContainer slot primitive.
12
18
  */
13
- export declare function QuickConfigPanel({ sections, onCommit, onCancel, anchorRect: _anchorRect, // accepted for position math by consumer — not used internally
14
- title, }: QuickConfigPanelProps): import("react/jsx-runtime").JSX.Element;
19
+ export declare function QuickConfigPanel({ sections, onCommit, onCancel, anchorRect: _anchorRect, title, }: QuickConfigPanelProps): import("react/jsx-runtime").JSX.Element;
@@ -15,8 +15,21 @@ export interface QuickConfigSection {
15
15
  /**
16
16
  * Props for QuickConfigPanel.
17
17
  * D-01: opaque — no reptime/entityType/metricInfo semantics.
18
- * D-03: anchorRect provides DOMRect for position math via MetricGroupContainer slot sizing.
19
18
  * D-19: Panel is NOT a modal — role is not "dialog".
19
+ *
20
+ * Positioning contract (WR-03 clarification):
21
+ * The panel is CONSUMER-POSITIONED. Placement is driven by the parent grid
22
+ * (e.g. MetricCardGrid uses CSS-grid placement adjacent to the active card)
23
+ * or by a wrapper element supplied by the consumer. This composite does
24
+ * NOT compute `translate(x, y)` from an anchor rect internally — the
25
+ * historical D-03 plan for internal anchor-rect math was superseded by the
26
+ * grid-placement approach adopted in Phase 13.
27
+ *
28
+ * `anchorRect` is retained as an opaque pass-through so consumers can
29
+ * forward a DOMRect for diagnostics / future position-math plugins, but
30
+ * the panel chrome ignores it. Width is sized from the
31
+ * `--gloss-slot-width` CSS var (MetricGroupContainer slot-primitive reuse,
32
+ * 180px fallback). Height is intrinsic.
20
33
  */
21
34
  export interface QuickConfigPanelProps {
22
35
  /** Sections to render in the panel body */
@@ -26,8 +39,9 @@ export interface QuickConfigPanelProps {
26
39
  /** Fired when the user clicks the Cancel pill */
27
40
  onCancel: () => void;
28
41
  /**
29
- * DOMRect of the anchor card used for extrude position math (D-03).
30
- * Panel does not crash when undefined; layout defaults apply.
42
+ * Opaque anchor-rect pass-through (see positioning contract above).
43
+ * Not consumed internally supplied for consumer instrumentation only.
44
+ * @deprecated for direct use — placement is consumer-managed via grid / wrapper styles.
31
45
  */
32
46
  anchorRect?: DOMRect;
33
47
  /**
@@ -3,6 +3,14 @@ export interface EdgeHoverHandleProps {
3
3
  state: ResizeState;
4
4
  onPointerDown: (e: React.PointerEvent) => void;
5
5
  onPointerUp: (e: React.PointerEvent) => void;
6
+ /**
7
+ * Bug E (260417-drag-resize-5th-attempt) — handle's own pointerenter/leave
8
+ * keeps the edge-hover zone alive when pointer crosses from sentinel to
9
+ * handle (they're siblings, so sentinel.pointerleave would otherwise collapse
10
+ * state to idle, hiding the handle mid-gesture).
11
+ */
12
+ onPointerEnter?: () => void;
13
+ onPointerLeave?: (e: React.PointerEvent) => void;
6
14
  /** Which card edge the handle is positioned on. Default: 'right' */
7
15
  edge?: 'right' | 'left';
8
16
  ariaLabel?: string;
@@ -25,6 +25,8 @@ export interface UseEdgeHoverResizeReturn {
25
25
  handleProps: {
26
26
  onPointerDown: (e: React.PointerEvent) => void;
27
27
  onPointerUp: (e: React.PointerEvent) => void;
28
+ onPointerEnter: () => void;
29
+ onPointerLeave: () => void;
28
30
  };
29
31
  /**
30
32
  * quick-260417-2na §2a — Live preview during drag.
@@ -3,12 +3,18 @@ import { MetricCardGridProps } from './types';
3
3
  /**
4
4
  * Finds the best adjacent slot to extrude the QuickConfigPanel into.
5
5
  *
6
- * Priority: right → below → left → above.
7
- * Returns null if activeIndex is invalid or no candidates exist.
6
+ * Priority (for both extrude AND dim-cover): right → below → left → above.
7
+ *
8
+ * Two modes, distinguished by caller:
9
+ * 1. Extrude — first candidate whose index is `>= cardCount` (empty slot)
10
+ * 2. Dim-cover fallback — when every candidate is occupied (`< cardCount`),
11
+ * returns the FIRST candidate in priority order (right wins for LTR
12
+ * readability; falls through to below / left / above only when the edge
13
+ * of the grid excludes earlier candidates). WR-05: the dim-cover fallback
14
+ * intentionally shares the priority list above — future enhancement could
15
+ * pick the neighbor closest to the viewport center for symmetric behavior.
8
16
  *
9
- * When all neighbors are occupied (packed grid), returns the right neighbor
10
- * index for dim-cover fallback — the caller distinguishes empty vs occupied
11
- * by checking if extrudeIndex >= cardCount.
17
+ * Returns null if activeIndex is invalid or no candidates exist.
12
18
  *
13
19
  * @param activeIndex Index of the active card in the ordered visible-cards array (0-based)
14
20
  * @param cardCount Total number of cards in the visible page
@@ -34,8 +34,16 @@ export interface UseSortableZonesConfig<T extends {
34
34
  * Pure React hook (useState, useCallback). Does NOT import DndContext —
35
35
  * SortableZones.tsx connects the event handlers to DndContext callbacks.
36
36
  *
37
- * Uncontrolled by default: zones state is initialised from config.zones and
38
- * managed internally. Call onZoneChange to sync back to parent.
37
+ * State model: **hybrid controlled + uncontrolled**.
38
+ * - Internal state is seeded from `config.zones` at mount.
39
+ * - Drag handlers mutate internal state and call `onZoneChange` to sync up.
40
+ * - If the parent later passes a structurally different `config.zones`
41
+ * (different zoneKeys or item id orderings) while no drag is in flight,
42
+ * the hook re-syncs to the new prop. This lets parents drive zones from
43
+ * external events (e.g. store updates outside a drag) without being
44
+ * surprised by a "frozen at mount" internal snapshot.
45
+ * - Mid-drag prop updates are ignored so a stale controlled value cannot
46
+ * clobber the in-progress drag.
39
47
  *
40
48
  * Generic over T extends { id: string }. No reptime-specific types. D-06, D-04, D-11 compliant.
41
49
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mt-gloss/ui",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "restricted"