@mt-gloss/ui 0.1.72 → 0.1.74
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.
- package/{Expandable-CtrmR_gh.js → Expandable-Deyl6mWK.js} +1802 -1804
- package/catalog.js +2 -2
- package/index.js +1747 -1657
- package/lib/primitives/dashboard/MetricCard/CardShell.d.ts +1 -1
- package/lib/primitives/dashboard/MetricCard/index.d.ts +2 -4
- package/lib/primitives/dashboard/MetricCard/resizeTypes.d.ts +23 -0
- package/lib/primitives/dashboard/MetricCard/types/cardShellProps.d.ts +0 -2
- package/lib/primitives/dashboard/MetricCard/useResizeChoreography.d.ts +27 -19
- package/lib/primitives/dashboard/ResizePill/ResizePill.d.ts +82 -0
- package/lib/primitives/dashboard/ResizePill/ResizePillArrowChain.d.ts +22 -0
- package/lib/primitives/dashboard/ResizePill/ResizePillGhost.d.ts +25 -0
- package/lib/primitives/dashboard/ResizePill/ResizePillSizeTooltip.d.ts +21 -0
- package/lib/primitives/dashboard/ResizePill/index.d.ts +13 -0
- package/lib/primitives/dashboard/ResizePill/resizePillPhysics.d.ts +33 -0
- package/lib/primitives/dashboard/ResizePill/useResizePill.d.ts +37 -0
- package/package.json +1 -1
- package/ui.css +1 -1
- package/lib/primitives/dashboard/MetricCard/EdgeHoverHandle.d.ts +0 -66
- package/lib/primitives/dashboard/MetricCard/__tests__/nyquist-10.fixture.d.ts +0 -93
- package/lib/primitives/dashboard/MetricCard/useEdgeHoverResize.d.ts +0 -130
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { ResizeState, ResizeDirection } from './useEdgeHoverResize';
|
|
2
|
-
export interface EdgeHoverHandleProps {
|
|
3
|
-
state: ResizeState;
|
|
4
|
-
onPointerDown: (e: React.PointerEvent) => void;
|
|
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;
|
|
14
|
-
/**
|
|
15
|
-
* D-13 — right-edge resize only. Left-edge support dropped (CONTEXT D-13);
|
|
16
|
-
* narrowed to the literal 'right'. Prop retained so downstream data-edge
|
|
17
|
-
* attributes and future bidirectional revival can slot in without a
|
|
18
|
-
* breaking API change.
|
|
19
|
-
*/
|
|
20
|
-
edge?: 'right';
|
|
21
|
-
/** D-16 — keyboard step handler (ArrowLeft → 'shrink', ArrowRight → 'grow'). */
|
|
22
|
-
onKeyboardStep?: (direction: ResizeDirection) => void;
|
|
23
|
-
/**
|
|
24
|
-
* Quick 260422-gfr — fires when the browser implicitly releases pointer
|
|
25
|
-
* capture from the <button> (window blur / Alt-Tab / modal focus steal /
|
|
26
|
-
* touchcancel). Consumers wire this to the hook's `cancel()` so the gesture
|
|
27
|
-
* deterministically exits `'dragging'` on capture loss. Companion to the
|
|
28
|
-
* window-level blur / visibilitychange / pointercancel listeners installed
|
|
29
|
-
* inside useEdgeHoverResize. See .planning/debug/resize-state-leak-cross-card.md.
|
|
30
|
-
*/
|
|
31
|
-
onLostPointerCapture?: (e: React.PointerEvent) => void;
|
|
32
|
-
ariaLabel?: string;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* EdgeHoverHandle — Corner/edge handle affordance for the resize gesture.
|
|
36
|
-
*
|
|
37
|
-
* Visibility is derived from resize state: only visible when state is
|
|
38
|
-
* 'handle-visible', 'dragging', or 'settling'. Invisible at 'idle' to avoid
|
|
39
|
-
* colliding with the chip-menu click target on the value/row area.
|
|
40
|
-
*
|
|
41
|
-
* Motion contract (AN-06): opacity transitions driven by edge-hover.scss
|
|
42
|
-
* using enterMs=180ms (enter) / exitMs=120ms (exit via ghost-preview).
|
|
43
|
-
*
|
|
44
|
-
* Pointer capture (debug 260417-qt00z / D-02+D-03 root cause): the handle is
|
|
45
|
-
* only 10px wide. On pointerdown we call setPointerCapture(pointerId) so all
|
|
46
|
-
* subsequent pointermove/pointerup events route to this element even after
|
|
47
|
-
* the cursor leaves the handle's hit region. Without this, dragging rightward
|
|
48
|
-
* (the natural grow gesture) moves the pointer off the handle within the
|
|
49
|
-
* first few px — pointerup then fires on whatever is underneath, the handle's
|
|
50
|
-
* React onPointerUp never runs, and the state machine stays stuck at
|
|
51
|
-
* 'dragging' (so onResize is never called and the card never commits).
|
|
52
|
-
*
|
|
53
|
-
* Cross-card gesture suppression (260503-aff): during ANY drag/resize, the
|
|
54
|
-
* resize handles on NON-source cards must hide so they don't compete with
|
|
55
|
-
* the in-flight gesture's chrome. Achieved by AND-gating ONLY the
|
|
56
|
-
* `'handle-visible'` branch on `useAffordanceVisibility().affordancesVisible`.
|
|
57
|
-
* The `'dragging'` and `'settling'` branches stay un-gated to preserve the
|
|
58
|
-
* SOURCE card's pointer-capture invariant — the source card's own handle MUST
|
|
59
|
-
* remain visible (and pointer-capture-eligible) throughout its own gesture,
|
|
60
|
-
* regardless of `affordancesVisible`. Non-source cards sit at
|
|
61
|
-
* `'handle-visible'` or earlier, so when `affordancesVisible=false` (during
|
|
62
|
-
* any global gesture + 200ms idle dwell), they hide. After the global
|
|
63
|
-
* gesture settles back to idle and the dwell elapses, all handles re-emerge
|
|
64
|
-
* together with the rest of the affordance chrome.
|
|
65
|
-
*/
|
|
66
|
-
export declare const EdgeHoverHandle: import('react').ForwardRefExoticComponent<EdgeHoverHandleProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NYQUIST-10 — Phase 19.2 Cross-Card Hover-State Unification behavior matrix fixture.
|
|
3
|
-
*
|
|
4
|
-
* Parametrized behavior definitions that the NYQUIST-10 runner iterates over
|
|
5
|
-
* via `it.each(BEHAVIOR_MATRIX)`. Each row pins one contract-level invariant
|
|
6
|
-
* asserted by Phase 19.2 plans 19.2-01 / 19.2-02 / 19.2-03. The matrix acts as a
|
|
7
|
-
* high-level regression net: if a future wave regresses ANY of the 10 rows,
|
|
8
|
-
* the runner fails with a specific row label even if the underlying test
|
|
9
|
-
* file lives elsewhere.
|
|
10
|
-
*
|
|
11
|
-
* Orthogonal axes (per VALIDATION.md §Orthogonal Sampling Matrix):
|
|
12
|
-
* - gridSize: 3 | 6 | 9 cards (leak-rate scaling)
|
|
13
|
-
* - intervalMs: 8 | 16 | 32 ms (event interval vs frame boundary)
|
|
14
|
-
* - eventCount: 10 | 20 | 40 (min signal / debug baseline / worst case)
|
|
15
|
-
* - cardType: standard | stackable | mixed (StackedGroupCard hover unit)
|
|
16
|
-
* - dndActive: boolean (dnd-kit drag suppression, RESEARCH Pitfall 4)
|
|
17
|
-
* - reducedMotion: boolean (prefers-reduced-motion parity)
|
|
18
|
-
*
|
|
19
|
-
* Row-count pin: the runner asserts exactly 10 rows so that accidentally
|
|
20
|
-
* dropping or silently renaming a behavior fails fast.
|
|
21
|
-
*
|
|
22
|
-
* Invariant each row asserts (after 200ms settle — D-16):
|
|
23
|
-
* 1. ≤1 card has `[data-visible="true"]` on its ActionStrip
|
|
24
|
-
* 2. Every non-hovered card's `useEdgeHoverResize` state === 'idle'
|
|
25
|
-
* 3. `hoveredCardId === expectedFinalCardId || null`
|
|
26
|
-
* 4. `vi.getTimerCount() === 0`
|
|
27
|
-
*
|
|
28
|
-
* @see .planning/phases/19.2-cross-card-hover-state-unification/19.2-CONTEXT.md (D-16, D-17, D-18)
|
|
29
|
-
* @see .planning/phases/19.2-cross-card-hover-state-unification/19.2-VALIDATION.md §Orthogonal Sampling Matrix
|
|
30
|
-
* @see .planning/phases/19.2-cross-card-hover-state-unification/19.2-PATTERNS.md Analog 8 (nyquist-11-fixtures.ts)
|
|
31
|
-
*/
|
|
32
|
-
export interface NyquistHarness {
|
|
33
|
-
/** Root grid container element (for dispatchEvent). */
|
|
34
|
-
gridRoot: HTMLElement;
|
|
35
|
-
/** Ordered list of card root elements (each has data-instance-id). */
|
|
36
|
-
cards: HTMLElement[];
|
|
37
|
-
/**
|
|
38
|
-
* Returns current hoveredCardId value from the grid (reads from
|
|
39
|
-
* data-hovered-card-id attribute on root, or a test-only prop hook).
|
|
40
|
-
*/
|
|
41
|
-
getHoveredCardId: () => string | null;
|
|
42
|
-
/**
|
|
43
|
-
* Returns the useEdgeHoverResize state for a given card id — reads
|
|
44
|
-
* data-resize-state attribute from slot root.
|
|
45
|
-
*/
|
|
46
|
-
getEdgeHoverStateFor: (cardId: string) => string;
|
|
47
|
-
/** Cleanup harness-mounted DOM. */
|
|
48
|
-
unmount: () => void;
|
|
49
|
-
}
|
|
50
|
-
export interface BehaviorParams {
|
|
51
|
-
gridSize: 3 | 6 | 9;
|
|
52
|
-
intervalMs: 8 | 16 | 32;
|
|
53
|
-
eventCount: 10 | 20 | 40;
|
|
54
|
-
cardType: 'standard' | 'stackable' | 'mixed';
|
|
55
|
-
dndActive: boolean;
|
|
56
|
-
reducedMotion: boolean;
|
|
57
|
-
}
|
|
58
|
-
export interface BehaviorDef {
|
|
59
|
-
/** 1-indexed for human readability in test output. */
|
|
60
|
-
id: number;
|
|
61
|
-
/** Short, greppable label. */
|
|
62
|
-
label: string;
|
|
63
|
-
/** Orthogonal axis values for this row. */
|
|
64
|
-
params: BehaviorParams;
|
|
65
|
-
/**
|
|
66
|
-
* The contract invariant this row pins. Either an assert-lambda that the
|
|
67
|
-
* runner invokes inside `it.each`, or `null` when the row is documented as
|
|
68
|
-
* covered by a sibling test file (runner skips but keeps the row in the
|
|
69
|
-
* matrix count pin). Wave 0 ships with `null` assert bodies; Task 2 wires
|
|
70
|
-
* the invariant body via it.each + harness mount, NOT via these callbacks.
|
|
71
|
-
*/
|
|
72
|
-
assert: ((harness: NyquistHarness) => Promise<void>) | null;
|
|
73
|
-
/**
|
|
74
|
-
* When present, the runner skips the row with the returned reason string
|
|
75
|
-
* instead of calling `assert`. Used to document rows whose contract is
|
|
76
|
-
* pinned by a dedicated sibling test file (cross-reference maintained in
|
|
77
|
-
* 19.2-VALIDATION.md).
|
|
78
|
-
*/
|
|
79
|
-
skipFor?: () => string | undefined;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* The 10 NYQUIST-10 behaviors. Each row's `assert` is `null` in Wave 0; the
|
|
83
|
-
* invariant body lives in hoveredCardId.invariant.test.tsx driven by
|
|
84
|
-
* `it.each(BEHAVIOR_MATRIX)`. Rows remain in the matrix so the row-count pin
|
|
85
|
-
* (10) catches silent drops or reorder.
|
|
86
|
-
*/
|
|
87
|
-
export declare const BEHAVIOR_MATRIX: BehaviorDef[];
|
|
88
|
-
/**
|
|
89
|
-
* Row-count pin — NYQUIST-10 runner asserts exactly this number of rows.
|
|
90
|
-
* Changing the behavior set requires updating this constant and adding a
|
|
91
|
-
* line in 19.2-VALIDATION.md §Orthogonal Sampling Matrix.
|
|
92
|
-
*/
|
|
93
|
-
export declare const BEHAVIOR_ROW_COUNT = 10;
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { MotionValue } from 'motion/react';
|
|
2
|
-
import { ResizePhysicsConfig } from './resizePhysics';
|
|
3
|
-
export type ResizeState = 'idle' | 'dwelling' | 'handle-visible' | 'dragging' | 'settling' | 'cancelled';
|
|
4
|
-
export type ResizeDirection = 'grow' | 'shrink';
|
|
5
|
-
export type ResizeMode = 'slot-fill' | 'sparkline-fidelity';
|
|
6
|
-
export interface ResizeCommit {
|
|
7
|
-
direction: ResizeDirection;
|
|
8
|
-
targetColSpan: 1 | 2 | 3;
|
|
9
|
-
mode: ResizeMode;
|
|
10
|
-
}
|
|
11
|
-
export interface UseEdgeHoverResizeArgs {
|
|
12
|
-
currentColSpan: 1 | 2 | 3;
|
|
13
|
-
stackable: boolean;
|
|
14
|
-
onResize: (commit: ResizeCommit) => void;
|
|
15
|
-
onCancel?: () => void;
|
|
16
|
-
/** D-14 — colWidth snapshot passed per-render; captured at pointerdown. Default: 180px (1280px viewport). */
|
|
17
|
-
step?: number;
|
|
18
|
-
/**
|
|
19
|
-
* Grid gap (px) between adjacent columns. Used to compute the ghost's
|
|
20
|
-
* left-anchored width as `colSpan * step + (colSpan - 1) * gap`. Default: 0
|
|
21
|
-
* (single-column grids). Rework 260419-v2 — ghost is width-driven, not
|
|
22
|
-
* translateX-driven; this is the companion scalar.
|
|
23
|
-
*/
|
|
24
|
-
gap?: number;
|
|
25
|
-
/** D-03 panel override; falls back to DEFAULT_RESIZE_PHYSICS. */
|
|
26
|
-
tuning?: Partial<ResizePhysicsConfig>;
|
|
27
|
-
/** Hover dwell time before handle appears. Default: 60ms */
|
|
28
|
-
dwellMs?: number;
|
|
29
|
-
/**
|
|
30
|
-
* Grace period (ms) after pointer leaves the edge zone before collapsing to idle.
|
|
31
|
-
* Prevents the handle from disappearing on brief mouse-off during natural mouse
|
|
32
|
-
* movement (e.g. crossing the sentinel/handle gap). Default: 150ms.
|
|
33
|
-
*/
|
|
34
|
-
graceExitMs?: number;
|
|
35
|
-
/** AN-06 enter motion duration exposed for consumer CSS. Default: 180ms */
|
|
36
|
-
enterMs?: number;
|
|
37
|
-
/** AN-06 exit motion duration exposed for consumer CSS. Default: 120ms */
|
|
38
|
-
exitMs?: number;
|
|
39
|
-
/**
|
|
40
|
-
* Max colSpan supported by the grid (D-13 — right-edge-only grow). Default: 3.
|
|
41
|
-
* Used to clamp ghostWidth writes during drag so the ghost cannot grow
|
|
42
|
-
* past the maximum-allowed column width at any cursor position (debug
|
|
43
|
-
* session 260419-ghost-slides-across-page — AP-17 companion invariant).
|
|
44
|
-
*
|
|
45
|
-
* Bug fix 260420-resize-past-sections — this cap is now enforced on the
|
|
46
|
-
* COMMIT path as well (onPointerUp + onKeyboardStep + hysteresisSnap).
|
|
47
|
-
* Previously only the live ghost width was clamped; onPointerUp passed
|
|
48
|
-
* raw `dx` to hysteresisSnap whose forward walk + final clamp used a
|
|
49
|
-
* hardcoded `3`, letting fast drags commit `targetColSpan = 3` past the
|
|
50
|
-
* section boundary.
|
|
51
|
-
*/
|
|
52
|
-
maxColSpan?: 1 | 2 | 3;
|
|
53
|
-
/**
|
|
54
|
-
* Phase 19.2 D-04 — grid-driven synchronous idle reset.
|
|
55
|
-
*
|
|
56
|
-
* When `true`, the hook synchronously clears pending dwell/touch-idle
|
|
57
|
-
* timers and transitions state to `'idle'`. Protects the drag grip:
|
|
58
|
-
* no-op during `'dragging'` or `'settling'` states (pointer-captured;
|
|
59
|
-
* spring owns settle; see D-05 + D-11 + debug/260419-hover-state-stuck-multi-card.md).
|
|
60
|
-
*
|
|
61
|
-
* Replaces the legacy "Polish Fix #7" window-pointermove self-heal
|
|
62
|
-
* (now deleted — grid-driven beats window-driven; D-04 ¶2).
|
|
63
|
-
*
|
|
64
|
-
* Prop-driven only. DO NOT add a ref-based imperative path (D-05).
|
|
65
|
-
*
|
|
66
|
-
* @default undefined (treated as false — hook runs normally)
|
|
67
|
-
*/
|
|
68
|
-
forceIdle?: boolean;
|
|
69
|
-
}
|
|
70
|
-
export interface UseEdgeHoverResizeReturn {
|
|
71
|
-
state: ResizeState;
|
|
72
|
-
enterEdgeZone: () => void;
|
|
73
|
-
leaveEdgeZone: () => void;
|
|
74
|
-
handleProps: {
|
|
75
|
-
onPointerDown: (e: React.PointerEvent) => void;
|
|
76
|
-
onPointerUp: (e: React.PointerEvent) => void;
|
|
77
|
-
onPointerEnter: () => void;
|
|
78
|
-
onPointerLeave: () => void;
|
|
79
|
-
};
|
|
80
|
-
/**
|
|
81
|
-
* Live preview during drag. Always clamped to 1..3.
|
|
82
|
-
* Reflects the colSpan the user would commit at the current cursor position,
|
|
83
|
-
* with hysteresis snap (D-06).
|
|
84
|
-
*/
|
|
85
|
-
previewColSpan: 1 | 2 | 3;
|
|
86
|
-
ghostProps: {
|
|
87
|
-
visible: boolean;
|
|
88
|
-
targetColSpan: 1 | 2 | 3;
|
|
89
|
-
/**
|
|
90
|
-
* D-07 rework 260419-v2 — MotionValue driving ghost WIDTH (left-anchored).
|
|
91
|
-
* The ghost LEFT edge is pinned at the slot origin; the ghost RIGHT edge
|
|
92
|
-
* follows the cursor; `ghostWidth` carries that width imperatively with
|
|
93
|
-
* zero React re-renders per pointermove. Supersedes the prior `motionX`
|
|
94
|
-
* translateX semantic (which slid the entire ghost horizontally — see
|
|
95
|
-
* debug session 260419-ghost-slides-across-page).
|
|
96
|
-
*/
|
|
97
|
-
ghostWidth: MotionValue<number>;
|
|
98
|
-
enterMs: number;
|
|
99
|
-
exitMs: number;
|
|
100
|
-
};
|
|
101
|
-
/** D-16 — keyboard resize step (grow/shrink by 1) on focused handle. */
|
|
102
|
-
onKeyboardStep: (direction: ResizeDirection) => void;
|
|
103
|
-
/** D-19 — touch tap-to-reveal: show handle immediately on touch pointerdown on card body. */
|
|
104
|
-
onTouchReveal: () => void;
|
|
105
|
-
/** D-19 — outside-tap dismissal for touch. */
|
|
106
|
-
onTouchDismiss: () => void;
|
|
107
|
-
/** D-18 — cancel (used by parent; springs back if dragging). */
|
|
108
|
-
cancel: () => void;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* useEdgeHoverResize — Phase 19 reworked state machine for edge-hover-to-resize.
|
|
112
|
-
*
|
|
113
|
-
* Changes vs Phase 10.5 original:
|
|
114
|
-
* - MotionValue ghost tracking (D-07) — zero React re-renders per pointermove
|
|
115
|
-
* - Hysteresis snap (D-06) replaces Math.round(dx/step)
|
|
116
|
-
* - Velocity ring buffer (D-09) feeds spring commit
|
|
117
|
-
* - Spring commit via framer-motion animate() (D-08: stiffness 500, damping 22, mass 1 — retuned 260419 for visible overshoot, was damping 35)
|
|
118
|
-
* - 'settling' state (D-12) hard-blocks re-engagement during spring
|
|
119
|
-
* - committed state removed (D-05) — rolls into settling → idle
|
|
120
|
-
* - Keyboard step (D-16): onKeyboardStep('grow'|'shrink')
|
|
121
|
-
* - Escape spring-back with cursor velocity (D-15)
|
|
122
|
-
* - Touch tap-to-reveal with 5s idle (D-19)
|
|
123
|
-
* - prefers-reduced-motion bypass (D-22) — instant transform
|
|
124
|
-
*
|
|
125
|
-
* Preserved invariants:
|
|
126
|
-
* - Bug A React 19 updater purity — side effects fire OUTSIDE setState updaters
|
|
127
|
-
* - Bug E handle pointerenter keeps zone alive on sentinel→handle crossover
|
|
128
|
-
* - Dwell timer cleanup on unmount
|
|
129
|
-
*/
|
|
130
|
-
export declare function useEdgeHoverResize({ currentColSpan, stackable, onResize, onCancel, step, gap, tuning, dwellMs, graceExitMs, enterMs, exitMs, maxColSpan, forceIdle, }: UseEdgeHoverResizeArgs): UseEdgeHoverResizeReturn;
|