@mt-gloss/ui 0.1.6 → 0.1.8
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-CsLVYNv3.js → Expandable-CTI-osAf.js} +2015 -2010
- package/catalog.js +2 -2
- package/index.d.ts +1 -0
- package/index.js +1025 -891
- package/lib/primitives/dashboard/CascadePreview/CascadePreview.d.ts +55 -0
- package/lib/primitives/dashboard/CascadePreview/index.d.ts +2 -0
- package/lib/primitives/dashboard/DragGhost/DragGhost.d.ts +35 -0
- package/lib/primitives/dashboard/DragGhost/index.d.ts +2 -0
- package/lib/primitives/dashboard/DropAnchorCell/DropAnchorCell.d.ts +9 -1
- package/lib/primitives/dashboard/SnapOutline/SnapOutline.d.ts +39 -0
- package/lib/primitives/dashboard/SnapOutline/index.d.ts +2 -0
- package/lib/primitives/dashboard/gridMotionPrimitives.d.ts +82 -0
- package/lib/primitives/dashboard/index.d.ts +4 -0
- package/package.json +1 -1
- package/ui.css +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { MotionValue } from 'framer-motion';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Per-card MotionValue pair carried alongside its cardId. Consumers (Plan 05
|
|
5
|
+
* integration) derive this from `useDragFeedback.cascadePreview.motionValues`
|
|
6
|
+
* via `Array.from(motionValues.entries(), ([cardId, { x, y }]) => ({ cardId, x, y }))`.
|
|
7
|
+
*
|
|
8
|
+
* **Scalar x/y (NOT a tuple MV)** — framer-motion's `style.x` and `style.y`
|
|
9
|
+
* consume scalar MotionValue<number>. Matches the per-card per-axis precedent
|
|
10
|
+
* in `useEdgeHoverResize.ts:495-547` (ghostWidth + spring-back-on-cancel).
|
|
11
|
+
*/
|
|
12
|
+
export interface CascadePreviewItem {
|
|
13
|
+
cardId: string;
|
|
14
|
+
x: MotionValue<number>;
|
|
15
|
+
y: MotionValue<number>;
|
|
16
|
+
}
|
|
17
|
+
export interface CascadePreviewProps {
|
|
18
|
+
items: CascadePreviewItem[];
|
|
19
|
+
/** Render-prop children — called once per item. Consumer owns the per-card
|
|
20
|
+
* display (typically a clone of the displaced source card). */
|
|
21
|
+
children: (item: CascadePreviewItem) => React.ReactNode;
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Phase 3 DRAG-07/08/09 — per-card cascade-preview render primitive.
|
|
26
|
+
*
|
|
27
|
+
* Renders N `<motion.div>` siblings keyed by `item.cardId` (DRAG-09 stable
|
|
28
|
+
* keys — same cardId across re-renders retains the same DOM node so the
|
|
29
|
+
* consumer's MotionValue drives transform without a remount).
|
|
30
|
+
*
|
|
31
|
+
* Each child:
|
|
32
|
+
* - `key={item.cardId}` — React reconciliation stability (DRAG-09)
|
|
33
|
+
* - `data-card-id={item.cardId}` — test hook + attribute-selector targeting
|
|
34
|
+
* - `style.x = item.x`, `style.y = item.y` — framer-motion reads MVs directly
|
|
35
|
+
* - `aria-hidden="true"` — displaced cards are visually cloned during preview;
|
|
36
|
+
* the semantic source card retains focus/aria surface
|
|
37
|
+
* - `pointer-events: none` + `will-change: transform` via SCSS
|
|
38
|
+
*
|
|
39
|
+
* Returns `null` when `items.length === 0` so the consumer does not render an
|
|
40
|
+
* empty fragment wrapper.
|
|
41
|
+
*
|
|
42
|
+
* **MotionValue ownership**: CascadePreview does NOT instantiate MotionValues.
|
|
43
|
+
* The consumer (Plan 05 inside MetricCardGrid) owns the per-instance
|
|
44
|
+
* `useRef<Map<cardId, {x, y}>>` reconciliation (see useDragFeedback.ts
|
|
45
|
+
* `reconcileMotionValues`). Module-scope MVs would cross-contaminate between
|
|
46
|
+
* grid instances; this primitive is purely presentational. See
|
|
47
|
+
* `useRubberBandGhost.ts:57-61` precedent.
|
|
48
|
+
*
|
|
49
|
+
* **Rendering-layer invariants**:
|
|
50
|
+
* - Rendered inside the grid container (NOT inside `<DragOverlay>`); DragOverlay
|
|
51
|
+
* hosts the DragGhost only.
|
|
52
|
+
* - Consumer places this inside a `position: relative` parent so `position:
|
|
53
|
+
* absolute` items stack correctly.
|
|
54
|
+
*/
|
|
55
|
+
export declare function CascadePreview({ items, children, className, }: CascadePreviewProps): JSX.Element | null;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { MotionValue } from 'framer-motion';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
export interface DragGhostProps {
|
|
4
|
+
/** 'ok' = blue dashed (--gloss-valid-stroke/fill); 'rejected' = pink solid (--gloss-rejection-stroke/fill) */
|
|
5
|
+
tint: 'ok' | 'rejected';
|
|
6
|
+
colSpan: 1 | 2 | 3;
|
|
7
|
+
colWidth: number;
|
|
8
|
+
rowHeight: number;
|
|
9
|
+
gap: number;
|
|
10
|
+
/** From parent useSpring(cursorMV, cascadePhysics.spring) — produces the 60ms ease-out lag */
|
|
11
|
+
x: MotionValue<number>;
|
|
12
|
+
y: MotionValue<number>;
|
|
13
|
+
/** Dragged card render (passed from consumer) */
|
|
14
|
+
children?: React.ReactNode;
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Phase 3 DRAG-01/02 — presentational ghost card rendered inside dnd-kit `<DragOverlay>`.
|
|
19
|
+
*
|
|
20
|
+
* Spring-driven x/y MotionValue props produce the 60ms ease-out cursor lag
|
|
21
|
+
* (per Phase 0 `cascadePhysics.spring` {stiffness:380, damping:32}).
|
|
22
|
+
*
|
|
23
|
+
* `data-tint` flips between 'ok' (dashed blue) and 'rejected' (solid pink) based on
|
|
24
|
+
* `predictCascade()` result emitted by `useDragFeedback.ghost.tint`. Reduced-motion
|
|
25
|
+
* CSS override strips the 1.02 scale + elevated shadow + transitions.
|
|
26
|
+
*
|
|
27
|
+
* **Consumer invariants (Plan 04 MUST honor — from Plan 00 spike + Plan 01 JSDoc):**
|
|
28
|
+
* 1. Render inside `<DragOverlay dropAnimation={null}>`
|
|
29
|
+
* 2. `x` / `y` are per-instance `useRef<MotionValue<number>>` (NEVER module-scope)
|
|
30
|
+
* 3. Parent wraps raw cursor MotionValues via `useSpring(cursor, cascadePhysics.spring)`
|
|
31
|
+
* — DragGhost itself is purely presentational and never instantiates springs.
|
|
32
|
+
*
|
|
33
|
+
* `aria-hidden="true"` because the dragged card semantics belong to the source, not the ghost.
|
|
34
|
+
*/
|
|
35
|
+
export declare function DragGhost({ tint, colSpan, colWidth, rowHeight, gap, x, y, children, className, }: DragGhostProps): JSX.Element;
|
|
@@ -6,6 +6,14 @@ export interface DropAnchorCellProps extends React.HTMLAttributes<HTMLDivElement
|
|
|
6
6
|
canAccept: boolean;
|
|
7
7
|
/** Brief not-allowed pulse when user attempts drop on occupied. */
|
|
8
8
|
blocked?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* DRAG-05 — cursor-driven continuous opacity. When provided, the cell
|
|
11
|
+
* renders with `data-proximity-driven='true'` and an inline CSS var
|
|
12
|
+
* `--_proximity-opacity: {value}` that overrides the discrete `data-density`
|
|
13
|
+
* bucket opacity. Phase 23 callers that only pass `density` + `canAccept`
|
|
14
|
+
* see zero behavior change. `canAccept='false'` still suppresses opacity.
|
|
15
|
+
*/
|
|
16
|
+
proximityOpacity?: number;
|
|
9
17
|
/** Stable cell id for test selectors + future instrumentation. */
|
|
10
18
|
['data-cell-id']?: string;
|
|
11
19
|
children?: React.ReactNode;
|
|
@@ -26,4 +34,4 @@ export interface DropAnchorCellProps extends React.HTMLAttributes<HTMLDivElement
|
|
|
26
34
|
*
|
|
27
35
|
* Respects prefers-reduced-motion.
|
|
28
36
|
*/
|
|
29
|
-
export declare function DropAnchorCell({ density, canAccept, blocked, className, children, ...rest }: DropAnchorCellProps): import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
export declare function DropAnchorCell({ density, canAccept, blocked, proximityOpacity, className, children, ...rest }: DropAnchorCellProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface SnapOutlineProps {
|
|
2
|
+
cell: {
|
|
3
|
+
section: 0 | 1 | 2 | 3;
|
|
4
|
+
col: 0 | 1 | 2;
|
|
5
|
+
row: 0 | 1 | 2;
|
|
6
|
+
};
|
|
7
|
+
colSpan: 1 | 2 | 3;
|
|
8
|
+
rowSpan: 1;
|
|
9
|
+
colWidth: number;
|
|
10
|
+
gap: number;
|
|
11
|
+
rowHeight: number;
|
|
12
|
+
/** DRAG-06 default 120ms cubic-bezier(0.4, 0, 0.2, 1) on transform. */
|
|
13
|
+
transitionMs?: number;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Phase 3 DRAG-06 — single 2px snap outline, 120ms cubic-bezier transition on transform.
|
|
18
|
+
*
|
|
19
|
+
* Renders a `position: absolute` 2px solid border rectangle, translated to the
|
|
20
|
+
* target cell via `translate({left}px, {top}px)` where:
|
|
21
|
+
* - `left = cell.col * (colWidth + gap)`
|
|
22
|
+
* - `top = cell.row * (rowHeight + gap)`
|
|
23
|
+
* - `width = colSpan * colWidth + (colSpan - 1) * gap`
|
|
24
|
+
* - `height = rowHeight`
|
|
25
|
+
*
|
|
26
|
+
* Transitions the transform at `${transitionMs ?? 120}ms cubic-bezier(0.4, 0, 0.2, 1)`.
|
|
27
|
+
* Under `prefers-reduced-motion: reduce`, `transition: none !important` strips
|
|
28
|
+
* the slide (SCSS-level override; see snap-outline.scss).
|
|
29
|
+
*
|
|
30
|
+
* Rendering-layer invariants (Plan 05 MUST honor):
|
|
31
|
+
* - `position: absolute` consumer — parent is the grid container with `position: relative`.
|
|
32
|
+
* - `pointer-events: none` (aria-hidden); does NOT intercept drag events.
|
|
33
|
+
* - 2px solid border using `var(--gloss-valid-stroke)` (Phase 0 color token).
|
|
34
|
+
* - Rendered INSIDE the grid container, NOT inside `<DragOverlay>`; DragOverlay
|
|
35
|
+
* hosts the DragGhost only (see Plan 02). The `dropAnimation={null}` invariant
|
|
36
|
+
* on DragOverlay (Plan 00 spike + Plan 01 header) does not apply here — SnapOutline
|
|
37
|
+
* is not a DragOverlay child.
|
|
38
|
+
*/
|
|
39
|
+
export declare function SnapOutline({ cell, colSpan, colWidth, gap, rowHeight, transitionMs, className, }: SnapOutlineProps): JSX.Element;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gridMotionPrimitives — Grid v2 shared motion vocabulary (Phase 0).
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for all timing, easing, color-token-name, and feedback
|
|
5
|
+
* constants consumed by Phases 1–5 (Grid Foundation, Cascade, Drag Feedback,
|
|
6
|
+
* Drag-to-Edge Auto-Advance, Resize + [×]). Zero behavior — framework-agnostic,
|
|
7
|
+
* no React, no Framer Motion, no hooks. Consumers import plain constants +
|
|
8
|
+
* `getMotionMode()` and decide how to apply them.
|
|
9
|
+
*
|
|
10
|
+
* Requirement mapping:
|
|
11
|
+
* MOTION-01 (no fade-from-nowhere) — documented principle; enforced in review
|
|
12
|
+
* MOTION-02 — cascadePhysics
|
|
13
|
+
* MOTION-03 — swingReveal
|
|
14
|
+
* MOTION-04 — colorTokens.rejection*, colorTokens.valid*, colorTokens.validCellStroke
|
|
15
|
+
* MOTION-05 — rejectionFeedback
|
|
16
|
+
* MOTION-06 — provisional, colorTokens.provisionalWash
|
|
17
|
+
* MOTION-07 — HARD_CLIP
|
|
18
|
+
* MOTION-08 — this file is the lone source; no inline timing/hex/easing in
|
|
19
|
+
* consuming component code (grep-enforced in each consumer phase)
|
|
20
|
+
* MOTION-09 — reducedMotion, getMotionMode()
|
|
21
|
+
*
|
|
22
|
+
* Structural precedent: libs/gloss-ui/src/lib/primitives/overlays/ActionStrip/motion.ts
|
|
23
|
+
*/
|
|
24
|
+
/** MOTION-02 — Forward (digest) and reverse (undo) cascade physics. Asymmetric by design. */
|
|
25
|
+
export declare const cascadePhysics: {
|
|
26
|
+
readonly forwardStaggerMs: 50;
|
|
27
|
+
readonly reverseStaggerMs: 30;
|
|
28
|
+
readonly springStiffness: 380;
|
|
29
|
+
readonly springDamping: 32;
|
|
30
|
+
readonly reverseVelocityMultiplier: 1.4;
|
|
31
|
+
};
|
|
32
|
+
/** MOTION-03 — Swing-from-behind reveal (resize handle, [×] affordance, future hover-intent micro-affordances). */
|
|
33
|
+
export declare const swingReveal: {
|
|
34
|
+
readonly enterDurationMs: 220;
|
|
35
|
+
readonly exitDurationMs: 140;
|
|
36
|
+
readonly enterEasing: "cubic-bezier(0.34, 1.56, 0.64, 1)";
|
|
37
|
+
readonly exitEasing: "cubic-bezier(0.4, 0, 1, 1)";
|
|
38
|
+
readonly translateOffsetPx: 4;
|
|
39
|
+
};
|
|
40
|
+
/** MOTION-05 — Rejection kinesthetic: ghost shiver on invalid drop. */
|
|
41
|
+
export declare const rejectionFeedback: {
|
|
42
|
+
readonly shiverCycles: 3;
|
|
43
|
+
readonly shiverAmplitudePx: 2;
|
|
44
|
+
readonly shiverDurationMs: 180;
|
|
45
|
+
readonly validCellOpacity: 0.6;
|
|
46
|
+
};
|
|
47
|
+
/** MOTION-06 — Provisional section/dot materialize + dematerialize. */
|
|
48
|
+
export declare const provisional: {
|
|
49
|
+
readonly materializeMs: 180;
|
|
50
|
+
readonly dematerializeMs: 140;
|
|
51
|
+
readonly easing: "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
52
|
+
readonly dotStrokePx: 2;
|
|
53
|
+
readonly dividerDashGapPx: 4;
|
|
54
|
+
};
|
|
55
|
+
/** MOTION-09 — Substitution values when prefers-reduced-motion: reduce is active. */
|
|
56
|
+
export declare const reducedMotion: {
|
|
57
|
+
readonly cascadeStaggerMs: 0;
|
|
58
|
+
readonly cascadeSpringCapMs: 120;
|
|
59
|
+
readonly swingEnterMs: 100;
|
|
60
|
+
readonly swingEnterStyle: "opacity";
|
|
61
|
+
readonly provisionalMs: 80;
|
|
62
|
+
readonly provisionalStyle: "opacity";
|
|
63
|
+
readonly shiverMs: 200;
|
|
64
|
+
readonly shiverStyle: "color-flash";
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* MOTION-07 — Hard-clip marker. True = when fixed neighbor grows over a card,
|
|
68
|
+
* cards clip at advancing edge (no fade). Downstream phases must reference this
|
|
69
|
+
* constant as the canonical source for the hard-clip rule.
|
|
70
|
+
*/
|
|
71
|
+
export declare const HARD_CLIP: true;
|
|
72
|
+
/** MOTION-04, MOTION-06 — CSS custom property NAMES (not literals). Consumers use var(...). */
|
|
73
|
+
export declare const colorTokens: {
|
|
74
|
+
readonly rejectionFill: "var(--gloss-rejection-fill)";
|
|
75
|
+
readonly rejectionStroke: "var(--gloss-rejection-stroke)";
|
|
76
|
+
readonly validFill: "var(--gloss-valid-fill)";
|
|
77
|
+
readonly validStroke: "var(--gloss-valid-stroke)";
|
|
78
|
+
readonly validCellStroke: "var(--gloss-valid-cell-stroke)";
|
|
79
|
+
readonly provisionalWash: "var(--gloss-provisional-wash)";
|
|
80
|
+
};
|
|
81
|
+
/** MOTION-09 — Motion mode resolver. Pure; SSR-safe; returns 'full' when window is undefined. */
|
|
82
|
+
export declare function getMotionMode(): 'full' | 'reduced';
|
|
@@ -17,3 +17,7 @@ export * from './DropAnchorCell';
|
|
|
17
17
|
export * from './SpilloverArc';
|
|
18
18
|
export * from './SectionDivider';
|
|
19
19
|
export * from './EmptyCellPackAffordance';
|
|
20
|
+
export * from './DragGhost';
|
|
21
|
+
export * from './SnapOutline';
|
|
22
|
+
export * from './CascadePreview';
|
|
23
|
+
export * from './gridMotionPrimitives';
|