@mt-gloss/ui 0.0.22 → 0.0.23
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-BCEAQsJY.js → Expandable-BYdvJg3S.js} +5051 -4920
- package/catalog.js +92 -91
- package/index.d.ts +4 -0
- package/index.js +291 -288
- package/lib/facade/data-display.d.ts +2 -2
- package/lib/primitives/dashboard/MetricCard/CardShell.d.ts +1 -1
- package/lib/primitives/dashboard/MetricCard/index.d.ts +0 -2
- package/lib/primitives/dashboard/MetricCard/overflowMenuRegistry.d.ts +1 -25
- package/lib/primitives/dashboard/MetricCard/types.d.ts +17 -3
- package/lib/primitives/dashboard/MetricCard/useSlideOutReveal.d.ts +1 -42
- package/lib/primitives/overlays/ActionStrip/ActionStrip.d.ts +9 -0
- package/lib/primitives/overlays/ActionStrip/defaultActions.d.ts +32 -0
- package/lib/primitives/overlays/ActionStrip/index.d.ts +7 -0
- package/lib/primitives/overlays/ActionStrip/motion.d.ts +148 -0
- package/lib/primitives/overlays/ActionStrip/overflowMenuRegistry.d.ts +30 -0
- package/lib/primitives/overlays/ActionStrip/types.d.ts +117 -0
- package/lib/primitives/overlays/ActionStrip/useActionStripRegistry.d.ts +7 -0
- package/lib/primitives/overlays/ActionStrip/useSlideOutReveal.d.ts +47 -0
- package/lib/primitives/overlays/index.d.ts +1 -0
- package/package.json +1 -1
- package/lib/primitives/dashboard/MetricCard/GutterActions.d.ts +0 -89
|
@@ -10,11 +10,11 @@ export { CardShell } from '../primitives/dashboard/MetricCard';
|
|
|
10
10
|
export { TrendIndicator } from '../primitives/dashboard/MetricCard';
|
|
11
11
|
export { StackedGroupCard } from '../primitives/dashboard/MetricCard';
|
|
12
12
|
export { CardBack } from '../primitives/dashboard/MetricCard';
|
|
13
|
-
export { GutterActions } from '../primitives/dashboard/MetricCard';
|
|
14
13
|
export type { MetricCardProps, CardShellProps } from '../primitives/dashboard/MetricCard/types';
|
|
15
14
|
export type { StackedGroupCardProps, StackedValueEntry } from '../primitives/dashboard/MetricCard/StackedGroupCard';
|
|
16
15
|
export type { CardBackProps } from '../primitives/dashboard/MetricCard/CardBack';
|
|
17
|
-
export
|
|
16
|
+
export { ActionStrip, buildDefaultOverflow } from '../primitives/overlays/ActionStrip';
|
|
17
|
+
export type { ActionStripProps, PrimaryAction, OverflowAction, ActionStripContext, ActionStripVariant, ActionStripMenuDirection, DefaultHandlers, } from '../primitives/overlays/ActionStrip';
|
|
18
18
|
export { SparklineBg } from '../primitives/dashboard/MetricCard';
|
|
19
19
|
export { BarsBg } from '../primitives/dashboard/MetricCard';
|
|
20
20
|
export { DonutChart } from '../primitives/dashboard/MetricCard';
|
|
@@ -17,6 +17,6 @@ import { CardShellProps } from './types';
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
export declare const CardShell: {
|
|
20
|
-
({ contentSlot, children, colSpan, isStale, isRetrying, beta, disabled, style, accentRing, onGraph, onDetails, onCustomize, onRemove, onWhatsThis, onExpand, onShrink, onMove, onReplace, onNavigate, onRetry, onRefresh, enableQuickSettings, onUpdateTimeframe, instanceTimeframe, cardTitle, quickConfigSlot, onViewAsStack, onUnstack, isStackedGroup, onUpdateStackedTimeframes, instanceStackedTimeframes, isGraphActive, isTableActive, isGraphCard, canExpand, anchorX, cardRef: externalCardRef, }: CardShellProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
({ contentSlot, children, colSpan, isStale, isRetrying, beta, disabled, style, accentRing, onGraph, onDetails, onCustomize, onRemove, onWhatsThis, onExpand, onShrink, onMove, onReplace, onNavigate, onRetry, onRefresh, enableQuickSettings, onUpdateTimeframe, instanceTimeframe, cardTitle, quickConfigSlot, onViewAsStack, onUnstack, isStackedGroup, onUpdateStackedTimeframes, instanceStackedTimeframes, isGraphActive, isTableActive, isGraphCard, canExpand, anchorX, extensionOverflow, cardRef: externalCardRef, }: CardShellProps): import("react/jsx-runtime").JSX.Element;
|
|
21
21
|
displayName: string;
|
|
22
22
|
};
|
|
@@ -2,7 +2,6 @@ export { MetricCard } from './MetricCard';
|
|
|
2
2
|
export { CardShell } from './CardShell';
|
|
3
3
|
export { CardBack } from './CardBack';
|
|
4
4
|
export { TrendIndicator } from './TrendIndicator';
|
|
5
|
-
export { GutterActions } from './GutterActions';
|
|
6
5
|
export { StackedGroupCard } from './StackedGroupCard';
|
|
7
6
|
export { StatusModeCard } from './StatusModeCard';
|
|
8
7
|
export { StatusSlotChipMenu } from './StatusSlotChipMenu';
|
|
@@ -14,7 +13,6 @@ export { useEdgeHoverResize } from './useEdgeHoverResize';
|
|
|
14
13
|
export * from './flipAndStage';
|
|
15
14
|
export * from './types';
|
|
16
15
|
export type { CardBackProps } from './CardBack';
|
|
17
|
-
export type { GutterActionsProps } from './GutterActions';
|
|
18
16
|
export type { StackedGroupCardProps, StackedValueEntry } from './StackedGroupCard';
|
|
19
17
|
export type { SlideOutRevealConfig, SlideOutRevealReturn } from './useSlideOutReveal';
|
|
20
18
|
export type { ResizeState, ResizeDirection, ResizeMode, ResizeCommit, UseEdgeHoverResizeArgs, UseEdgeHoverResizeReturn, } from './useEdgeHoverResize';
|
|
@@ -1,25 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* overflowMenuRegistry — Module-scoped singleton tracker for MetricCard overflow menus.
|
|
3
|
-
*
|
|
4
|
-
* quick-260417-ago Cluster C (item 14): only one overflow menu may be open at a time.
|
|
5
|
-
* When menu B opens, menu A receives a notification via its useSyncExternalStore
|
|
6
|
-
* subscription and closes itself.
|
|
7
|
-
*
|
|
8
|
-
* Uses a plain module-level `activeId` + Set<listener> — no new dep (Zustand is
|
|
9
|
-
* over-engineering for one state field; Context would require hoisting the
|
|
10
|
-
* provider higher than the card tree, which complicates flag-off paths).
|
|
11
|
-
*
|
|
12
|
-
* React 19's useSyncExternalStore consumes `subscribe` / `getSnapshot` and keeps
|
|
13
|
-
* components in sync without triggering tearing under concurrent rendering.
|
|
14
|
-
*
|
|
15
|
-
* Exports:
|
|
16
|
-
* - subscribe(fn): listen to activeId changes; returns unsubscribe
|
|
17
|
-
* - getActive(): current activeId (or null)
|
|
18
|
-
* - setActive(id | null): declare which menu is open; notifies all subscribers
|
|
19
|
-
* - resetForTests(): clears state between vitest runs
|
|
20
|
-
*/
|
|
21
|
-
export declare function subscribe(listener: () => void): () => void;
|
|
22
|
-
export declare function getActive(): string | null;
|
|
23
|
-
export declare function setActive(next: string | null): void;
|
|
24
|
-
/** Test-only: resets internal state. Not exported from the public barrel. */
|
|
25
|
-
export declare function resetForTests(): void;
|
|
1
|
+
export * from '../../overlays/ActionStrip/overflowMenuRegistry';
|
|
@@ -178,15 +178,29 @@ export interface CardShellProps {
|
|
|
178
178
|
isGraphCard?: boolean;
|
|
179
179
|
canExpand?: boolean;
|
|
180
180
|
/**
|
|
181
|
-
* Horizontal anchor (px from card's left edge) forwarded to
|
|
181
|
+
* Horizontal anchor (px from card's left edge) forwarded to ActionStrip.
|
|
182
182
|
*
|
|
183
|
-
* When provided, overrides
|
|
183
|
+
* When provided, overrides ActionStrip's default `left: 50%` centered pill
|
|
184
184
|
* position. Drives the per-slot gutter-slide choreography for stack cards
|
|
185
185
|
* (Cluster W quick-260417-d5z item 3 / gutter hover slide). Undefined
|
|
186
186
|
* preserves the pre-existing centered layout.
|
|
187
187
|
*
|
|
188
|
-
* @see
|
|
188
|
+
* @see ActionStripProps.anchorX
|
|
189
189
|
*/
|
|
190
190
|
anchorX?: number;
|
|
191
|
+
/**
|
|
192
|
+
* Consumer-supplied overflow menu entries that CardShell concatenates into
|
|
193
|
+
* the ActionStrip `overflow` prop after the default set (settings / remove
|
|
194
|
+
* / replace / refresh) and before the footer `whats-this`.
|
|
195
|
+
*
|
|
196
|
+
* Per D-04 (variant ownership), gloss primitives stay reptime-agnostic:
|
|
197
|
+
* extensions like Move / Customize are constructed at the reptime
|
|
198
|
+
* consumer and passed in via this prop (usually sourced from
|
|
199
|
+
* `CARD_MENU_EXTENSIONS.getExtensions(cardType, baseOrder)` per AP-09).
|
|
200
|
+
*
|
|
201
|
+
* Phase 16 plan 16-06 Task 3 adds this prop; reptime adopts it for
|
|
202
|
+
* cardType-specific Move / Customize opt-in.
|
|
203
|
+
*/
|
|
204
|
+
extensionOverflow?: import('../../overlays/ActionStrip').OverflowAction[];
|
|
191
205
|
cardRef?: RefObject<HTMLDivElement | null>;
|
|
192
206
|
}
|
|
@@ -1,42 +1 @@
|
|
|
1
|
-
|
|
2
|
-
type AnimationPhase = 'hidden' | 'entering-behind' | 'entering-front' | 'visible' | 'exiting-front' | 'exiting-behind';
|
|
3
|
-
export interface SlideOutRevealConfig {
|
|
4
|
-
slideDirection?: SlideDirection;
|
|
5
|
-
behindDuration?: number;
|
|
6
|
-
frontDuration?: number;
|
|
7
|
-
easing?: string;
|
|
8
|
-
behindEasing?: string;
|
|
9
|
-
zBehind?: number;
|
|
10
|
-
zFront?: number;
|
|
11
|
-
}
|
|
12
|
-
export interface SlideOutRevealStyle {
|
|
13
|
-
transform: string;
|
|
14
|
-
zIndex: number;
|
|
15
|
-
transition: string;
|
|
16
|
-
pointerEvents: 'auto' | 'none';
|
|
17
|
-
}
|
|
18
|
-
export interface SlideOutRevealReturn {
|
|
19
|
-
phase: AnimationPhase;
|
|
20
|
-
handleTransitionEnd: () => void;
|
|
21
|
-
style: SlideOutRevealStyle;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* useSlideOutReveal -- 6-state slide-out animation hook.
|
|
25
|
-
*
|
|
26
|
-
* Two-phase reveal: element slides from behind a parent surface (z-index behind),
|
|
27
|
-
* then once it emerges, z-index switches to front and it settles at resting position.
|
|
28
|
-
* Exit is the reverse sequence.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```ts
|
|
32
|
-
* import { useSlideOutReveal } from '@mt-gloss/ui';
|
|
33
|
-
*
|
|
34
|
-
* const { phase, handleTransitionEnd, style } = useSlideOutReveal(isVisible, {
|
|
35
|
-
* slideDirection: 'down',
|
|
36
|
-
* zBehind: 1,
|
|
37
|
-
* zFront: 16,
|
|
38
|
-
* });
|
|
39
|
-
* ```
|
|
40
|
-
*/
|
|
41
|
-
export declare function useSlideOutReveal(visible: boolean, config?: SlideOutRevealConfig): SlideOutRevealReturn;
|
|
42
|
-
export {};
|
|
1
|
+
export * from '../../overlays/ActionStrip/useSlideOutReveal';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { ActionStripProps, OverflowAction } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* D5 pure-icon bypass predicate. When every overflow entry is promotable AND
|
|
5
|
+
* all promotable fit the expanded budget, expansion grows the strip + runs icon
|
|
6
|
+
* ingress ONLY — no border-radius morph, no vertical menu surface.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isPureIconBypass(overflow: readonly OverflowAction[], expandedBudgetSlots: number): boolean;
|
|
9
|
+
export declare const ActionStrip: React.FC<ActionStripProps>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { OverflowAction } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* The three promotable default overflow ids, in canonical order. Callsites
|
|
4
|
+
* that want to filter or extend the default set reference these ids directly.
|
|
5
|
+
*
|
|
6
|
+
* Note: `refresh` is part of the D4 catalog but NOT listed here because it is
|
|
7
|
+
* a context-specific action (only fires when a card has a refresh affordance).
|
|
8
|
+
* Consumers that need Refresh pass `onRefresh` — `buildDefaultOverflow` emits
|
|
9
|
+
* the entry when present. For registry-level "is this id part of the default
|
|
10
|
+
* set?" checks, include 'refresh' in the superset.
|
|
11
|
+
*/
|
|
12
|
+
export declare const DEFAULT_OVERFLOW_IDS: readonly ["settings", "remove", "replace"];
|
|
13
|
+
/** The single non-promotable footer id. */
|
|
14
|
+
export declare const DEFAULT_FOOTER_IDS: readonly ["whats-this"];
|
|
15
|
+
/** Optional handlers for the default overflow set. Absent handlers omit entries. */
|
|
16
|
+
export interface DefaultHandlers {
|
|
17
|
+
onSettings?: () => void;
|
|
18
|
+
onRemove?: () => void;
|
|
19
|
+
onReplace?: () => void;
|
|
20
|
+
onRefresh?: () => void;
|
|
21
|
+
onWhatsThis?: () => void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build the D4 default overflow set. Emits one entry per handler provided,
|
|
25
|
+
* preserving canonical order (`settings`, `remove`, `replace`, `refresh`,
|
|
26
|
+
* `whats-this`) and tagging `isPromotable: true` for everything except the
|
|
27
|
+
* footer `whats-this`.
|
|
28
|
+
*
|
|
29
|
+
* @param handlers - per-card handler map; absent handlers omit entries.
|
|
30
|
+
* @returns `OverflowAction[]` in canonical order, `order` monotonic from 0.
|
|
31
|
+
*/
|
|
32
|
+
export declare function buildDefaultOverflow(handlers: DefaultHandlers): OverflowAction[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ActionStrip } from './ActionStrip';
|
|
2
|
+
export type { PrimaryAction, OverflowAction, ActionStripProps, ActionStripContext, ActionStripVariant, ActionStripMenuDirection, } from './types';
|
|
3
|
+
export { subscribe, getActive, setActive, resetForTests, } from './overflowMenuRegistry';
|
|
4
|
+
export { useSlideOutReveal } from './useSlideOutReveal';
|
|
5
|
+
export type { SlideOutRevealConfig, SlideOutRevealReturn, SlideOutRevealStyle, } from './useSlideOutReveal';
|
|
6
|
+
export { DEFAULT_OVERFLOW_IDS, DEFAULT_FOOTER_IDS, buildDefaultOverflow, } from './defaultActions';
|
|
7
|
+
export type { DefaultHandlers } from './defaultActions';
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ActionStrip — Framer Motion choreography constants (Phase 16 plan 16-02).
|
|
3
|
+
*
|
|
4
|
+
* Every exported constant maps to an exact row in `.planning/phases/16-overflow-menu-reliability/16-UI-SPEC.md`
|
|
5
|
+
* §Motion & Choreography. If a test for the timing table ever fails, either:
|
|
6
|
+
* 1) UI-SPEC was updated and the constant below must change to match, OR
|
|
7
|
+
* 2) the constant was changed accidentally and must be reverted.
|
|
8
|
+
*
|
|
9
|
+
* These values are consumed by `ActionStrip.tsx`; they are exported so tests can
|
|
10
|
+
* assert against them directly (no fragile source-grep of inline numbers).
|
|
11
|
+
*
|
|
12
|
+
* NO automatic-height keyframes anywhere — AP guard enforced by Test 8 in
|
|
13
|
+
* `__tests__/choreography.test.tsx`. Use `scaleY` for menu open/close.
|
|
14
|
+
*/
|
|
15
|
+
export declare const TIMING: {
|
|
16
|
+
readonly STRIP_EXPAND_MS: 250;
|
|
17
|
+
readonly STRIP_COLLAPSE_MS: 180;
|
|
18
|
+
readonly ICON_INGRESS_MS: 150;
|
|
19
|
+
readonly ICON_STAGGER_MS: 50;
|
|
20
|
+
readonly ICON_EGRESS_MS: 120;
|
|
21
|
+
readonly MENU_OPEN_MS: 250;
|
|
22
|
+
readonly MENU_CLOSE_MS: 120;
|
|
23
|
+
readonly BORDER_RADIUS_MS: 200;
|
|
24
|
+
readonly ANCHOR_X_MS: 180;
|
|
25
|
+
readonly FEEDBACK_PRESS_MS: 100;
|
|
26
|
+
readonly FEEDBACK_CHECK_MS: 600;
|
|
27
|
+
readonly FLIP_COLLAPSE_MAX_WIDTH_MS: 250;
|
|
28
|
+
readonly FLIP_COLLAPSE_OPACITY_MS: 200;
|
|
29
|
+
readonly GRACE_CLOSE_MS: 300;
|
|
30
|
+
readonly REDUCED_MOTION_MS: 10;
|
|
31
|
+
};
|
|
32
|
+
/** Framer Motion spring physics (UI-SPEC row "Expand (click) — Strip width"). */
|
|
33
|
+
export declare const SPRING: {
|
|
34
|
+
type: "spring";
|
|
35
|
+
stiffness: number;
|
|
36
|
+
damping: number;
|
|
37
|
+
};
|
|
38
|
+
/** UI-SPEC row "Reveal (hover) — front phase" and Expand — Icon ingress: cubic-bezier(0.22, 1, 0.36, 1). */
|
|
39
|
+
export declare const EASE_OUT: readonly [0.22, 1, 0.36, 1];
|
|
40
|
+
type FlipDirection = 'up' | 'down';
|
|
41
|
+
/**
|
|
42
|
+
* Pill border-radius morph. UI-SPEC §Motion & Choreography row "Expand (click)
|
|
43
|
+
* — Border-radius" + §Up/Down Flip Mirror Contract (D7).
|
|
44
|
+
*
|
|
45
|
+
* Three named variants cover: collapsed (8px all-round), expanded-down (bottom
|
|
46
|
+
* corners flat, menu hangs below), expanded-up (top corners flat, menu sits
|
|
47
|
+
* above — mirror of expanded-down).
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildPillVariants(reduced: boolean): {
|
|
50
|
+
collapsed: {
|
|
51
|
+
borderRadius: number;
|
|
52
|
+
transition: {
|
|
53
|
+
duration: number;
|
|
54
|
+
ease: "easeOut";
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
'expanded-down': {
|
|
58
|
+
borderRadius: string;
|
|
59
|
+
transition: {
|
|
60
|
+
duration: number;
|
|
61
|
+
ease: "easeOut";
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
'expanded-up': {
|
|
65
|
+
borderRadius: string;
|
|
66
|
+
transition: {
|
|
67
|
+
duration: number;
|
|
68
|
+
ease: "easeOut";
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Vertical menu scaleY + opacity + y-offset. UI-SPEC §Motion rows "Expand —
|
|
74
|
+
* Menu drop" + "Collapse — Menu hide" + §Up/Down Flip Mirror "Menu entry
|
|
75
|
+
* y-translation".
|
|
76
|
+
*
|
|
77
|
+
* `custom` is the flip direction — `down` enters from y:-4, `up` from y:+4.
|
|
78
|
+
* Menu is asymmetric: open 250ms ease-out; close 120ms ease-in.
|
|
79
|
+
*/
|
|
80
|
+
export declare function buildMenuVariants(reduced: boolean): {
|
|
81
|
+
initial: (dir: FlipDirection) => {
|
|
82
|
+
opacity: number;
|
|
83
|
+
scaleY: number;
|
|
84
|
+
y: number;
|
|
85
|
+
};
|
|
86
|
+
animate: {
|
|
87
|
+
opacity: number;
|
|
88
|
+
scaleY: number;
|
|
89
|
+
y: number;
|
|
90
|
+
transition: {
|
|
91
|
+
duration: number;
|
|
92
|
+
ease: "easeOut";
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
exit: {
|
|
96
|
+
opacity: number;
|
|
97
|
+
scaleY: number;
|
|
98
|
+
transition: {
|
|
99
|
+
duration: number;
|
|
100
|
+
ease: "easeIn";
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Promoted-icon ingress / egress. UI-SPEC §Motion rows "Expand — Icon ingress"
|
|
106
|
+
* + "Collapse — Icon egress". Stagger is owned by the parent container variant.
|
|
107
|
+
*/
|
|
108
|
+
export declare function buildIconVariants(reduced: boolean): {
|
|
109
|
+
initial: {
|
|
110
|
+
opacity: number;
|
|
111
|
+
scale: number;
|
|
112
|
+
};
|
|
113
|
+
animate: {
|
|
114
|
+
opacity: number;
|
|
115
|
+
scale: number;
|
|
116
|
+
transition: {
|
|
117
|
+
duration: number;
|
|
118
|
+
ease: "easeOut";
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
exit: {
|
|
122
|
+
opacity: number;
|
|
123
|
+
scale: number;
|
|
124
|
+
transition: {
|
|
125
|
+
duration: number;
|
|
126
|
+
ease: "easeIn";
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Parent-container staggerChildren variants. UI-SPEC §Motion row "Expand —
|
|
132
|
+
* Icon ingress: 50ms stagger". Collapse has no stagger (asymmetric per D9).
|
|
133
|
+
*/
|
|
134
|
+
export declare function buildStripContainerVariants(reduced: boolean): {
|
|
135
|
+
collapsed: {
|
|
136
|
+
transition: {
|
|
137
|
+
staggerChildren: number;
|
|
138
|
+
staggerDirection: -1;
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
expanded: {
|
|
142
|
+
transition: {
|
|
143
|
+
staggerChildren: number;
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
export declare function transformOriginFor(dir: FlipDirection): 'top center' | 'bottom center';
|
|
148
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* overflowMenuRegistry — Module-scoped singleton tracker for ActionStrip overflow menus.
|
|
3
|
+
*
|
|
4
|
+
* MOVED from `primitives/dashboard/MetricCard/overflowMenuRegistry.ts` in Phase 16
|
|
5
|
+
* plan 16-01 alongside the GutterActions → ActionStrip rewrite. The legacy path
|
|
6
|
+
* re-exports from this module so existing consumers continue to compile during
|
|
7
|
+
* the multi-plan transition.
|
|
8
|
+
*
|
|
9
|
+
* quick-260417-ago Cluster C (item 14): only one overflow menu may be open at a time.
|
|
10
|
+
* When menu B opens, menu A receives a notification via its useSyncExternalStore
|
|
11
|
+
* subscription and closes itself.
|
|
12
|
+
*
|
|
13
|
+
* Uses a plain module-level `activeId` + Set<listener> — no new dep (Zustand is
|
|
14
|
+
* over-engineering for one state field; Context would require hoisting the
|
|
15
|
+
* provider higher than the card tree, which complicates flag-off paths).
|
|
16
|
+
*
|
|
17
|
+
* React 19's useSyncExternalStore consumes `subscribe` / `getSnapshot` and keeps
|
|
18
|
+
* components in sync without triggering tearing under concurrent rendering.
|
|
19
|
+
*
|
|
20
|
+
* Exports:
|
|
21
|
+
* - subscribe(fn): listen to activeId changes; returns unsubscribe
|
|
22
|
+
* - getActive(): current activeId (or null)
|
|
23
|
+
* - setActive(id | null): declare which menu is open; notifies all subscribers
|
|
24
|
+
* - resetForTests(): clears state between vitest runs
|
|
25
|
+
*/
|
|
26
|
+
export declare function subscribe(listener: () => void): () => void;
|
|
27
|
+
export declare function getActive(): string | null;
|
|
28
|
+
export declare function setActive(next: string | null): void;
|
|
29
|
+
/** Test-only: resets internal state. Not exported from the public barrel. */
|
|
30
|
+
export declare function resetForTests(): void;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Runtime context forwarded to every action's `visibleWhen()` predicate.
|
|
4
|
+
*
|
|
5
|
+
* Known keys reflect today's call-site usage (error gating, card kind, column span,
|
|
6
|
+
* graph card affordance, expand capability). Unknown keys are permitted to keep the
|
|
7
|
+
* extension surface non-breaking as new card types add discriminators.
|
|
8
|
+
*/
|
|
9
|
+
export interface ActionStripContext {
|
|
10
|
+
/** True when the card is in a retry/error state — gates Retry vs Graph/Details mutex. */
|
|
11
|
+
isErrorState?: boolean;
|
|
12
|
+
/** Card subtype discriminator (e.g., 'trend', 'statusMode', 'stackedGroup'). */
|
|
13
|
+
cardType?: string;
|
|
14
|
+
/** Column span of the hosting card; some actions (Expand/Shrink) key on this. */
|
|
15
|
+
colSpan?: 1 | 2 | 3;
|
|
16
|
+
/** True when the host card has a graph affordance (enables Expand in menu). */
|
|
17
|
+
isGraphCard?: boolean;
|
|
18
|
+
/** True when the host card is currently expandable (card-level capability gate). */
|
|
19
|
+
canExpand?: boolean;
|
|
20
|
+
/** Extension point for future visibleWhen predicates — additions are non-breaking. */
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Pinned strip button. Always present in the collapsed pill when `visibleWhen` passes.
|
|
25
|
+
*
|
|
26
|
+
* Supports feedback animation (pressed → Check flash) and active-state color
|
|
27
|
+
* inversion (`isActive` + `activeColor` + `activeIcon`). Preserved behaviors #6/#7
|
|
28
|
+
* from D3 of the rewrite decisions.
|
|
29
|
+
*/
|
|
30
|
+
export interface PrimaryAction {
|
|
31
|
+
/** Stable identifier for test hooks + layoutId assignment. */
|
|
32
|
+
id: string;
|
|
33
|
+
/** Resting icon. */
|
|
34
|
+
icon: ReactNode;
|
|
35
|
+
/** Optional icon swapped in when `isActive` is true (e.g., Check after Graph toggle). */
|
|
36
|
+
activeIcon?: ReactNode;
|
|
37
|
+
/** Tooltip label (native `title=`). */
|
|
38
|
+
label: string;
|
|
39
|
+
/** Click handler. */
|
|
40
|
+
onClick: () => void;
|
|
41
|
+
/** True when the action is the currently-active view (drives color inversion). */
|
|
42
|
+
isActive?: boolean;
|
|
43
|
+
/** When true, render 100ms pressed-state + 600ms Check flash on click. */
|
|
44
|
+
showFeedback?: boolean;
|
|
45
|
+
/** Arbitrary CSS color string for the active state (e.g., '#4f46e5' for Graph). */
|
|
46
|
+
activeColor?: string;
|
|
47
|
+
/** Predicate; action is hidden when returns false. Runs on every render. */
|
|
48
|
+
visibleWhen?: (ctx: ActionStripContext) => boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Overflow menu entry. Rendered in the vertical menu by default; may be promoted
|
|
52
|
+
* into the expanded strip when `isPromotable: true` and there's budget.
|
|
53
|
+
*
|
|
54
|
+
* `order` sets monotonic rank used for promotion priority and menu rendering.
|
|
55
|
+
* The lone non-promotable entry today is "What's this?" (footer).
|
|
56
|
+
*/
|
|
57
|
+
export interface OverflowAction {
|
|
58
|
+
/** Stable identifier for test hooks. */
|
|
59
|
+
id: string;
|
|
60
|
+
/** Icon; required only when the action may be promoted into the strip. */
|
|
61
|
+
icon?: ReactNode;
|
|
62
|
+
/** Menu-item text / promoted-button tooltip. */
|
|
63
|
+
label: string;
|
|
64
|
+
/** Click handler. */
|
|
65
|
+
onClick: () => void;
|
|
66
|
+
/** True = eligible for promotion into the expanded strip; false = vertical-only. */
|
|
67
|
+
isPromotable: boolean;
|
|
68
|
+
/** Monotonic rank for promotion priority + vertical render order. */
|
|
69
|
+
order: number;
|
|
70
|
+
/** Predicate; action is hidden when returns false. Runs on every render. */
|
|
71
|
+
visibleWhen?: (ctx: ActionStripContext) => boolean;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* `'default'` is the standard pill + menu. `'config'` is a transitional variant
|
|
75
|
+
* that replaces the More trigger with Save/Cancel pills during reconfig flow;
|
|
76
|
+
* Phase 17 retires this variant entirely.
|
|
77
|
+
*/
|
|
78
|
+
export type ActionStripVariant = 'default' | 'config';
|
|
79
|
+
/** Menu-flip direction. Omit to let floating-ui's flip() middleware decide. */
|
|
80
|
+
export type ActionStripMenuDirection = 'up' | 'down';
|
|
81
|
+
/**
|
|
82
|
+
* Public ActionStrip prop contract. Stable across Phase 16 plans 16-01..05.
|
|
83
|
+
*/
|
|
84
|
+
export interface ActionStripProps {
|
|
85
|
+
/** Pinned strip buttons (Graph, Details, Navigate, Retry, etc.). */
|
|
86
|
+
primary: PrimaryAction[];
|
|
87
|
+
/** Overflow entries (Settings, Remove, Replace, Refresh, What's this?). */
|
|
88
|
+
overflow: OverflowAction[];
|
|
89
|
+
/** From `useSlideOutReveal` — true when the consumer card is hovered/focused. */
|
|
90
|
+
visible: boolean;
|
|
91
|
+
/** Sticky-on-click expansion state. */
|
|
92
|
+
expanded: boolean;
|
|
93
|
+
/** Called to toggle `expanded`. */
|
|
94
|
+
onExpandedChange: (open: boolean) => void;
|
|
95
|
+
/** Defaults to 'default'. Phase 17 retires 'config'. */
|
|
96
|
+
variant?: ActionStripVariant;
|
|
97
|
+
/** CardBack collapse-to-Undo. Preserved behavior #5. */
|
|
98
|
+
isFlipped?: boolean;
|
|
99
|
+
/** Called when the Undo button is clicked while isFlipped. */
|
|
100
|
+
onFlipBack?: () => void;
|
|
101
|
+
/** Stack-card slot-slide horizontal anchor in px. Preserved behavior #3. */
|
|
102
|
+
anchorX?: number;
|
|
103
|
+
/** Optional override; omit to let floating-ui flip() decide. Re-measured at expand click. */
|
|
104
|
+
menuDirection?: ActionStripMenuDirection;
|
|
105
|
+
/** Singleton registry key. Preserved behavior #1. Auto-generated if omitted. */
|
|
106
|
+
menuId?: string;
|
|
107
|
+
/** Runtime context forwarded to action visibleWhen() predicates. */
|
|
108
|
+
context?: ActionStripContext;
|
|
109
|
+
/** Consumer-overridable tooltip for the Graph pinned button. */
|
|
110
|
+
graphLabel?: string;
|
|
111
|
+
/** Consumer-overridable tooltip for the Details pinned button. */
|
|
112
|
+
detailsLabel?: string;
|
|
113
|
+
/** Config variant Save handler. Retired in Phase 17 — pass-through only this phase. */
|
|
114
|
+
onConfigSave?: () => void;
|
|
115
|
+
/** Config variant Cancel handler. Retired in Phase 17 — pass-through only this phase. */
|
|
116
|
+
onConfigCancel?: () => void;
|
|
117
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface UseActionStripRegistryReturn {
|
|
2
|
+
/** Resolved menu id — prop if provided, else the generated useId() value. */
|
|
3
|
+
menuId: string;
|
|
4
|
+
/** Currently-active menu id across the dashboard (null if no menu is open). */
|
|
5
|
+
activeMenuId: string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function useActionStripRegistry(expanded: boolean, menuId: string | undefined, onExpandedChange: (open: boolean) => void): UseActionStripRegistryReturn;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
type SlideDirection = 'down' | 'left';
|
|
2
|
+
type AnimationPhase = 'hidden' | 'entering-behind' | 'entering-front' | 'visible' | 'exiting-front' | 'exiting-behind';
|
|
3
|
+
export interface SlideOutRevealConfig {
|
|
4
|
+
slideDirection?: SlideDirection;
|
|
5
|
+
behindDuration?: number;
|
|
6
|
+
frontDuration?: number;
|
|
7
|
+
easing?: string;
|
|
8
|
+
behindEasing?: string;
|
|
9
|
+
zBehind?: number;
|
|
10
|
+
zFront?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface SlideOutRevealStyle {
|
|
13
|
+
transform: string;
|
|
14
|
+
zIndex: number;
|
|
15
|
+
transition: string;
|
|
16
|
+
pointerEvents: 'auto' | 'none';
|
|
17
|
+
}
|
|
18
|
+
export interface SlideOutRevealReturn {
|
|
19
|
+
phase: AnimationPhase;
|
|
20
|
+
handleTransitionEnd: () => void;
|
|
21
|
+
style: SlideOutRevealStyle;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* useSlideOutReveal -- 6-state slide-out animation hook.
|
|
25
|
+
*
|
|
26
|
+
* MOVED from `primitives/dashboard/MetricCard/useSlideOutReveal.ts` in Phase 16
|
|
27
|
+
* plan 16-01 alongside the GutterActions → ActionStrip rewrite. The legacy path
|
|
28
|
+
* re-exports from this module so existing consumers continue to compile during
|
|
29
|
+
* the multi-plan transition.
|
|
30
|
+
*
|
|
31
|
+
* Two-phase reveal: element slides from behind a parent surface (z-index behind),
|
|
32
|
+
* then once it emerges, z-index switches to front and it settles at resting position.
|
|
33
|
+
* Exit is the reverse sequence.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* import { useSlideOutReveal } from '@mt-gloss/ui';
|
|
38
|
+
*
|
|
39
|
+
* const { phase, handleTransitionEnd, style } = useSlideOutReveal(isVisible, {
|
|
40
|
+
* slideDirection: 'down',
|
|
41
|
+
* zBehind: 1,
|
|
42
|
+
* zFront: 16,
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function useSlideOutReveal(visible: boolean, config?: SlideOutRevealConfig): SlideOutRevealReturn;
|
|
47
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ActionStrip';
|
package/package.json
CHANGED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
export interface GutterActionsProps {
|
|
2
|
-
visible: boolean;
|
|
3
|
-
menuOpen: boolean;
|
|
4
|
-
onMenuToggle: (open: boolean) => void;
|
|
5
|
-
onGraph?: () => void;
|
|
6
|
-
onDetails?: () => void;
|
|
7
|
-
onCustomize?: () => void;
|
|
8
|
-
onRemove?: () => void;
|
|
9
|
-
onWhatsThis?: () => void;
|
|
10
|
-
onExpand?: () => void;
|
|
11
|
-
onShrink?: () => void;
|
|
12
|
-
onMove?: () => void;
|
|
13
|
-
onReplace?: () => void;
|
|
14
|
-
onNavigate?: () => void;
|
|
15
|
-
onRetry?: () => void;
|
|
16
|
-
onRefresh?: () => void;
|
|
17
|
-
onQuickSettings?: () => void;
|
|
18
|
-
onFlipBack?: () => void;
|
|
19
|
-
isFlipped?: boolean;
|
|
20
|
-
onViewAsStack?: () => void;
|
|
21
|
-
onUnstack?: () => void;
|
|
22
|
-
canExpand?: boolean;
|
|
23
|
-
isGraphCard?: boolean;
|
|
24
|
-
colSpan?: 1 | 2 | 3;
|
|
25
|
-
isGraphActive?: boolean;
|
|
26
|
-
isTableActive?: boolean;
|
|
27
|
-
/** Label for graph pill button (injected, no registry dependency). */
|
|
28
|
-
graphLabel?: string;
|
|
29
|
-
/** Label for details pill button (injected, no registry dependency). */
|
|
30
|
-
detailsLabel?: string;
|
|
31
|
-
/**
|
|
32
|
-
* Pill variant:
|
|
33
|
-
* - 'default': standard pill with graph/details/more controls
|
|
34
|
-
* - 'config': replaces 'more' with Save (Check) + Cancel (Close) pills (D-10)
|
|
35
|
-
*/
|
|
36
|
-
variant?: 'default' | 'config';
|
|
37
|
-
/** Called when Save pill is clicked in config variant. */
|
|
38
|
-
onConfigSave?: () => void;
|
|
39
|
-
/** Called when Cancel pill is clicked in config variant. */
|
|
40
|
-
onConfigCancel?: () => void;
|
|
41
|
-
/**
|
|
42
|
-
* Cluster C (quick-260417-ago) — Singleton overflow-menu identifier.
|
|
43
|
-
*
|
|
44
|
-
* When provided, this GutterActions instance cooperates with
|
|
45
|
-
* `overflowMenuRegistry` so only one overflow menu across the whole
|
|
46
|
-
* dashboard may be open at a time. Opening menu N sets the registry's
|
|
47
|
-
* activeId to N; any OTHER instance sees active !== its own id and closes
|
|
48
|
-
* its menu automatically via onMenuToggle(false).
|
|
49
|
-
*
|
|
50
|
-
* If omitted, a useId() fallback is used so each instance still gets a
|
|
51
|
-
* unique registry key — the singleton behavior still works across cards.
|
|
52
|
-
*/
|
|
53
|
-
menuId?: string;
|
|
54
|
-
/**
|
|
55
|
-
* Cluster D (quick-260417-ago) — Horizontal anchor offset in px from the
|
|
56
|
-
* card's left edge. When provided, overrides the pill's default
|
|
57
|
-
* `left: 50%` centered position; drives the per-slot gutter-slide
|
|
58
|
-
* choreography (180ms ease-out) for stack cards whose hovered slot moves
|
|
59
|
-
* horizontally.
|
|
60
|
-
*
|
|
61
|
-
* Undefined (default) preserves the pre-existing centered layout.
|
|
62
|
-
*/
|
|
63
|
-
anchorX?: number;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* GutterActions - Pill + overflow menu interaction system.
|
|
67
|
-
*
|
|
68
|
-
* Pure presentational version: no context, BFF, or dispatch-actions dependencies.
|
|
69
|
-
* Action labels are injected via graphLabel/detailsLabel props.
|
|
70
|
-
*
|
|
71
|
-
* Two-phase reveal animation via useSlideOutReveal hook (slideDirection: 'down').
|
|
72
|
-
*
|
|
73
|
-
* @example
|
|
74
|
-
* ```tsx
|
|
75
|
-
* import { GutterActions } from '@mt-gloss/ui';
|
|
76
|
-
*
|
|
77
|
-
* <GutterActions
|
|
78
|
-
* visible={isHovered}
|
|
79
|
-
* menuOpen={menuOpen}
|
|
80
|
-
* onMenuToggle={setMenuOpen}
|
|
81
|
-
* onGraph={() => {}}
|
|
82
|
-
* onDetails={() => {}}
|
|
83
|
-
* />
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
export declare const GutterActions: {
|
|
87
|
-
({ visible, menuOpen, onMenuToggle, onGraph, onDetails, onCustomize, onRemove, onWhatsThis, onExpand, onShrink, onMove, onReplace, onNavigate, onRetry, onRefresh, onQuickSettings, onFlipBack, isFlipped, onViewAsStack, onUnstack, canExpand, isGraphCard, colSpan, isGraphActive, isTableActive, graphLabel, detailsLabel, variant, onConfigSave, onConfigCancel, menuId, anchorX, }: GutterActionsProps): import("react/jsx-runtime").JSX.Element;
|
|
88
|
-
displayName: string;
|
|
89
|
-
};
|