@mt-gloss/ui 0.1.7 → 0.1.9
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/index.js +971 -890
- package/lib/composites/dashboard/BottomToolbar/SectionDots.d.ts +18 -1
- 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/SectionDivider/SectionDivider.d.ts +1 -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/index.d.ts +3 -0
- package/package.json +1 -1
- package/ui.css +1 -1
|
@@ -4,11 +4,28 @@
|
|
|
4
4
|
* Renders `count` buttons inside a `role="tablist"`. Click dispatches
|
|
5
5
|
* `onSelect(index)`. Keyboard ← → loop forward/backward with wrap semantics
|
|
6
6
|
* (D-25). Hollow default, filled for the current section.
|
|
7
|
+
*
|
|
8
|
+
* Phase 4 — drag-to-edge-auto-advance — additive extension per D-09/D-10/D-11:
|
|
9
|
+
* - `provisionalIndex` marks an unconfirmed section with hollow-stroke dot
|
|
10
|
+
* (`data-state='provisional-hollow'`) and `aria-label='Unconfirmed section'`.
|
|
11
|
+
* - `pulseIndex` triggers the refuse-pulse animation (`data-state='pulse'`).
|
|
12
|
+
* - `pulseNonce` is composited into the React `key` for the pulsed index so a
|
|
13
|
+
* nonce bump forces a re-mount — which restarts the CSS keyframe animation
|
|
14
|
+
* even if the same index is pulsed twice in a row.
|
|
15
|
+
*
|
|
16
|
+
* All new props are optional; omitting them preserves the Phase 23 two-state
|
|
17
|
+
* `data-state='current'|'hollow'` render exactly (parity contract).
|
|
7
18
|
*/
|
|
8
19
|
export interface SectionDotsProps {
|
|
9
20
|
count: number;
|
|
10
21
|
currentIndex: number;
|
|
11
22
|
onSelect: (index: number) => void;
|
|
12
23
|
'aria-label'?: string;
|
|
24
|
+
/** Phase 4 D-09 — index of the unconfirmed ("provisional") section, if any. */
|
|
25
|
+
provisionalIndex?: number;
|
|
26
|
+
/** Phase 4 D-09 — index of the dot currently playing the refuse pulse, if any. */
|
|
27
|
+
pulseIndex?: number;
|
|
28
|
+
/** Phase 4 D-10 — monotonically-increasing nonce; bump to replay the pulse keyframe. */
|
|
29
|
+
pulseNonce?: number;
|
|
13
30
|
}
|
|
14
|
-
export declare function SectionDots({ count, currentIndex, onSelect, 'aria-label': ariaLabel, }: SectionDotsProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export declare function SectionDots({ count, currentIndex, onSelect, 'aria-label': ariaLabel, provisionalIndex, pulseIndex, pulseNonce, }: SectionDotsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -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;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
export type SectionDividerState = 'hidden' | 'revealed' | 'emphasized';
|
|
2
|
+
export type SectionDividerState = 'hidden' | 'revealed' | 'emphasized' | 'provisional';
|
|
3
3
|
export interface SectionDividerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
4
|
state: SectionDividerState;
|
|
5
5
|
/** Left-to-right cascade position (0, 1, 2, ...) multiplied by staggerMs for animation-delay. */
|
|
@@ -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;
|
|
@@ -17,4 +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';
|
|
20
23
|
export * from './gridMotionPrimitives';
|