@tensor_1/react 2.48.0 → 2.49.1
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/README.md +70 -1
- package/dist/components/Chip.d.ts +7 -3
- package/dist/components/Chip.js +2 -2
- package/dist/components/DashboardCanvas.js +14 -0
- package/dist/components/DataWorkspace.js +1 -4
- package/dist/components/Dialogs.js +5 -5
- package/dist/components/FocusOnMount.d.ts +282 -0
- package/dist/components/FocusOnMount.js +12 -0
- package/dist/components/Kanban.d.ts +14 -3
- package/dist/components/Kanban.js +9 -4
- package/dist/components/MotionList.d.ts +303 -0
- package/dist/components/MotionList.js +175 -0
- package/dist/components/Popover.js +9 -0
- package/dist/components/RelationshipGraph.js +4 -1
- package/dist/components/RelationshipGraphLayered.js +107 -32
- package/dist/components/SearchSuggest.js +8 -1
- package/dist/components/Segmented.js +8 -2
- package/dist/components/Select.js +6 -0
- package/dist/components/SortableList.d.ts +2 -2
- package/dist/components/SortableList.js +16 -3
- package/dist/components/States.d.ts +33 -1
- package/dist/components/States.js +43 -1
- package/dist/components/Tabs.js +9 -2
- package/dist/components/Toast.d.ts +1 -1
- package/dist/components/Toast.js +106 -2
- package/dist/components/Tooltip.js +62 -7
- package/dist/emoji.cjs +115 -14
- package/dist/hooks/useAnchoredPosition.js +14 -2
- package/dist/hooks/useDeferredReorder.d.ts +32 -0
- package/dist/hooks/useDeferredReorder.js +47 -0
- package/dist/hooks/useDialog.js +15 -2
- package/dist/hooks/useKeyboardGrab.d.ts +58 -0
- package/dist/hooks/useKeyboardGrab.js +118 -0
- package/dist/hooks/useSlidingIndicator.d.ts +18 -0
- package/dist/hooks/useSlidingIndicator.js +80 -0
- package/dist/index.cjs +2208 -1378
- package/dist/index.d.cts +477 -13
- package/dist/index.d.ts +7 -3
- package/dist/index.js +14 -2
- package/dist/labels-context.d.ts +3 -0
- package/dist/motion.d.ts +11 -0
- package/dist/motion.js +35 -0
- package/dist/relationship-graph-model.d.ts +17 -3
- package/dist/relationship-graph-model.js +28 -16
- package/dist/rich-text.cjs +42 -2
- package/dist/toast-store.d.ts +5 -2
- package/dist/toast-store.js +3 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,9 @@ export { PENDING_DELAY_MS, PENDING_MIN_VISIBLE_MS, RESULT_HOLD_MS } from './moti
|
|
|
11
11
|
export { ChangeHighlightOptions, flashChanged, useChangeHighlight } from './hooks/useChangeHighlight.js';
|
|
12
12
|
export { OptimisticRollback, UseOptimisticValueOptions, UseOptimisticValueResult, useOptimisticValue } from './hooks/useOptimisticValue.js';
|
|
13
13
|
export { announcePolite } from './announce.js';
|
|
14
|
+
export { UseDeferredReorderResult, useDeferredReorder } from './hooks/useDeferredReorder.js';
|
|
15
|
+
export { useSlidingIndicator } from './hooks/useSlidingIndicator.js';
|
|
16
|
+
export { DEFAULT_KEYBOARD_GRAB_LABELS, KeyboardGrabDirection, KeyboardGrabLabels, UseKeyboardGrabOptions, UseKeyboardGrabResult, settleDrop, useKeyboardGrab } from './hooks/useKeyboardGrab.js';
|
|
14
17
|
export { Align, Placement, PositionOptions, PositionResult, Rect, Side, Size, computePosition } from './overlay-position.js';
|
|
15
18
|
export { Button, ButtonGroup, ButtonGroupProps, ButtonLink, ButtonLinkProps, ButtonProps, ButtonSize, ButtonVariant } from './components/Button.js';
|
|
16
19
|
export { UixDateFormat, UixLabels, UixLabelsProvider, UixLabelsProviderProps, useUixLabels } from './labels-context.js';
|
|
@@ -88,7 +91,7 @@ export { Kbd, KbdCombo, KbdComboProps, KbdPlatform, KbdProps, KeyShortcut, ariaK
|
|
|
88
91
|
export { DEFAULT_STEP_STATE_LABELS, Step, StepProps, StepState, StepStateLabels, Steps, StepsProps } from './components/Steps.js';
|
|
89
92
|
export { Tooltip, TooltipProps } from './components/Tooltip.js';
|
|
90
93
|
export { InfoTip, InfoTipProps } from './components/InfoTip.js';
|
|
91
|
-
export { AccessStateProps, EmptyState, EmptyStateProps, ErrorState, ErrorStateProps, FilteredEmptyState, ForbiddenState, LoadingState, LoadingStateProps, NotFoundState, Skeleton, SkeletonProps, StateVariant } from './components/States.js';
|
|
94
|
+
export { AccessStateProps, EmptyState, EmptyStateProps, ErrorState, ErrorStateProps, FilteredEmptyState, ForbiddenState, LoadingState, LoadingStateProps, NotFoundState, Skeleton, SkeletonProps, StateVariant, SuccessState, SuccessStateProps } from './components/States.js';
|
|
92
95
|
export { RelativeTime, RelativeTimeFormatContext, RelativeTimeProps } from './components/RelativeTime.js';
|
|
93
96
|
export { RelativeTimeUnit, RelativeTimeValue, parseDateValue, relativeTimeValue } from './relative-time-model.js';
|
|
94
97
|
export { AsyncOperationState, AsyncOperationStatus, AsyncOperationStatusProps } from './components/AsyncOperationStatus.js';
|
|
@@ -99,6 +102,7 @@ export { DEFAULT_SAVE_STATUS_LABELS, SaveStatus, SaveStatusLabels, SaveStatusPro
|
|
|
99
102
|
export { BusyRegion, BusyRegionProps } from './components/BusyRegion.js';
|
|
100
103
|
export { ChangeHighlight, ChangeHighlightProps } from './components/ChangeHighlight.js';
|
|
101
104
|
export { Count, CountProps } from './components/Count.js';
|
|
105
|
+
export { MotionList, MotionListProps } from './components/MotionList.js';
|
|
102
106
|
export { ButtonResult, ButtonResultLabels, DEFAULT_BUTTON_RESULT_LABELS } from './components/ButtonFeedback.js';
|
|
103
107
|
export { Composer, ComposerBar, ComposerBarProps, ComposerProps } from './components/Composer.js';
|
|
104
108
|
export { LocaleSwitcher, LocaleSwitcherLocale, LocaleSwitcherProps, Segmented, SegmentedOption, SegmentedOptionProps, SegmentedProps } from './components/Segmented.js';
|
|
@@ -115,7 +119,7 @@ export { Menu, MenuGroup, MenuGroupProps, MenuItem, MenuItemAttributes, MenuItem
|
|
|
115
119
|
export { CommandGroup, CommandGroupProps, CommandItem, CommandItemProps, CommandPalette, CommandPaletteProps } from './components/CommandPalette.js';
|
|
116
120
|
export { CommandPaletteGroup, CommandPaletteItem, filterCommandItems, groupCommandItems } from './command-palette-model.js';
|
|
117
121
|
export { Inbox, InboxDetail, InboxDetailProps, InboxItem, InboxItemProps, InboxList, InboxListProps, InboxProps } from './components/Inbox.js';
|
|
118
|
-
export { Kanban, KanbanCard, KanbanCardProps, KanbanColumn, KanbanColumnProps, KanbanMoveDirection, KanbanProps } from './components/Kanban.js';
|
|
122
|
+
export { Kanban, KanbanCard, KanbanCardProps, KanbanColumn, KanbanColumnProps, KanbanDropLine, KanbanDropLineProps, KanbanMoveDirection, KanbanProps } from './components/Kanban.js';
|
|
119
123
|
export { DEFAULT_TREE_LABELS, Tree, TreeLabels, TreeNodeData, TreeNodeProps, TreeProps } from './components/Tree.js';
|
|
120
124
|
export { DEFAULT_ORG_CHART_LABELS, OrgChart, OrgChartLabels, OrgChartNode, OrgChartProps, orgChartInitials, orgChartZoomStep } from './components/OrgChart.js';
|
|
121
125
|
export { FlatNode, TreeLike, TreeNavAction, flattenTree, treeNav } from './tree-model.js';
|
|
@@ -137,7 +141,7 @@ export { DEFAULT_TIME_PICKER_LABELS, TimeInputProblem, TimePicker, TimePickerLab
|
|
|
137
141
|
export { formatTimeKey, isOvernightRange, isTimeOutOfRange, isValidTimeKey, minutesToTime, parseTimeInput, stepTime, timePartEnds, timeSlots, timeToMinutes, uses12Hour } from './time-field-model.js';
|
|
138
142
|
export { CalendarDay, CalendarWeekday, DateRangeValue, LaneCluster, LaneInterval, LanePlacement, PackLanesOptions, PackedLanes, ZonedDateSpan, ZonedDayBounds, ZonedDayShift, ZonedDaySpan, ZonedHourSlot, addCalendarDays, addCalendarMonths, addZonedDays, buildMonthGrid, cachedDateTimeFormat, enumerateDateKeys, enumerateDateSpan, isDateInRange, isDateUnavailable, packLanes, rankOverflow, selectRangeDate, startOfMonth, toDateKey, zonedDateKey, zonedDateSpan, zonedDayBounds, zonedDaySpan, zonedHourSlots, zonedTimeOfDay } from './calendar-model.js';
|
|
139
143
|
export { DEFAULT_RELATIONSHIP_GRAPH_LABELS, RelationshipGraph, RelationshipGraphLabels, RelationshipGraphLegendItem, RelationshipGraphProps } from './components/RelationshipGraph.js';
|
|
140
|
-
export { BoundedRelationshipGraph, EdgeLabelBox, LayeredColumn, LayeredEdgeClassification, LayeredEdgeKind, LayeredItem, LayeredLayout, LayeredLayoutOptions, LayeredNavigationKey, PlacedEdgeLabel, PositionedRelationshipNode, RelationshipGraphArrow, RelationshipGraphCluster, RelationshipGraphEdge, RelationshipGraphNode, RelationshipGraphTone, RoutedEdge, boundRelationshipGraph, classifyLayeredEdges, clusterIdFor, edgeLabelSize, layeredNeighbor, layoutLayeredGraph, layoutRelationshipGraph, relationshipNeighbors, separateEdgeLabels, traverseRelationshipNode, wrapEdgeLabel } from './relationship-graph-model.js';
|
|
144
|
+
export { BoundedRelationshipGraph, EdgeLabelBox, LabelObstacle, LayeredColumn, LayeredEdgeClassification, LayeredEdgeKind, LayeredItem, LayeredLayout, LayeredLayoutOptions, LayeredNavigationKey, PlacedEdgeLabel, PositionedRelationshipNode, RelationshipGraphArrow, RelationshipGraphCluster, RelationshipGraphEdge, RelationshipGraphNode, RelationshipGraphTone, RoutedEdge, boundRelationshipGraph, classifyLayeredEdges, clusterIdFor, edgeLabelSize, layeredNeighbor, layoutLayeredGraph, layoutRelationshipGraph, relationshipNeighbors, separateEdgeLabels, traverseRelationshipNode, wrapEdgeLabel } from './relationship-graph-model.js';
|
|
141
145
|
export { AuditLog, AuditLogAction, AuditLogEvent, AuditLogFilters, AuditLogLabels, AuditLogProps, DEFAULT_AUDIT_LOG_LABELS } from './components/AuditLog.js';
|
|
142
146
|
export { DEFAULT_MATCH_REVIEW_LABELS, MatchBulkResult, MatchReview, MatchReviewAction, MatchReviewCandidate, MatchReviewField, MatchReviewLabels, MatchReviewProps } from './components/MatchReview.js';
|
|
143
147
|
export { MetricInput, MetricInputProps } from './components/MetricInput.js';
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,9 @@ import { PENDING_DELAY_MS, PENDING_MIN_VISIBLE_MS, RESULT_HOLD_MS } from "./moti
|
|
|
20
20
|
import { useChangeHighlight, flashChanged } from "./hooks/useChangeHighlight.js";
|
|
21
21
|
import { useOptimisticValue } from "./hooks/useOptimisticValue.js";
|
|
22
22
|
import { announcePolite } from "./announce.js";
|
|
23
|
+
import { useDeferredReorder } from "./hooks/useDeferredReorder.js";
|
|
24
|
+
import { useSlidingIndicator } from "./hooks/useSlidingIndicator.js";
|
|
25
|
+
import { useKeyboardGrab, settleDrop, DEFAULT_KEYBOARD_GRAB_LABELS } from "./hooks/useKeyboardGrab.js";
|
|
23
26
|
import { computePosition } from "./overlay-position.js";
|
|
24
27
|
import { Button, ButtonGroup, ButtonLink } from "./components/Button.js";
|
|
25
28
|
import { UixLabelsProvider, useUixLabels } from "./labels-context.js";
|
|
@@ -125,7 +128,7 @@ import { Kbd, KbdCombo, ariaKeyShortcuts } from "./components/Kbd.js";
|
|
|
125
128
|
import { Steps, Step, DEFAULT_STEP_STATE_LABELS } from "./components/Steps.js";
|
|
126
129
|
import { Tooltip } from "./components/Tooltip.js";
|
|
127
130
|
import { InfoTip } from "./components/InfoTip.js";
|
|
128
|
-
import { EmptyState, ErrorState, ForbiddenState, NotFoundState, FilteredEmptyState, Skeleton, LoadingState } from "./components/States.js";
|
|
131
|
+
import { EmptyState, ErrorState, ForbiddenState, NotFoundState, FilteredEmptyState, Skeleton, LoadingState, SuccessState } from "./components/States.js";
|
|
129
132
|
import { RelativeTime } from "./components/RelativeTime.js";
|
|
130
133
|
import { parseDateValue, relativeTimeValue } from "./relative-time-model.js";
|
|
131
134
|
import { AsyncOperationStatus } from "./components/AsyncOperationStatus.js";
|
|
@@ -136,6 +139,7 @@ import { SaveStatus, DEFAULT_SAVE_STATUS_LABELS } from "./components/SaveStatus.
|
|
|
136
139
|
import { BusyRegion } from "./components/BusyRegion.js";
|
|
137
140
|
import { ChangeHighlight } from "./components/ChangeHighlight.js";
|
|
138
141
|
import { Count } from "./components/Count.js";
|
|
142
|
+
import { MotionList } from "./components/MotionList.js";
|
|
139
143
|
import { DEFAULT_BUTTON_RESULT_LABELS } from "./components/ButtonFeedback.js";
|
|
140
144
|
import { Composer, ComposerBar } from "./components/Composer.js";
|
|
141
145
|
import { Segmented, SegmentedOption, LocaleSwitcher } from "./components/Segmented.js";
|
|
@@ -164,7 +168,7 @@ import { Menu, MenuItem, MenuItemRadio, MenuItemCheckbox, MenuRadioGroup, MenuGr
|
|
|
164
168
|
import { CommandPalette, CommandGroup, CommandItem } from "./components/CommandPalette.js";
|
|
165
169
|
import { filterCommandItems, groupCommandItems } from "./command-palette-model.js";
|
|
166
170
|
import { Inbox, InboxList, InboxItem, InboxDetail } from "./components/Inbox.js";
|
|
167
|
-
import { Kanban, KanbanColumn, KanbanCard } from "./components/Kanban.js";
|
|
171
|
+
import { Kanban, KanbanColumn, KanbanCard, KanbanDropLine } from "./components/Kanban.js";
|
|
168
172
|
import { Tree, DEFAULT_TREE_LABELS } from "./components/Tree.js";
|
|
169
173
|
import { OrgChart, DEFAULT_ORG_CHART_LABELS, orgChartInitials, orgChartZoomStep } from "./components/OrgChart.js";
|
|
170
174
|
import { flattenTree, treeNav } from "./tree-model.js";
|
|
@@ -360,6 +364,7 @@ export {
|
|
|
360
364
|
DEFAULT_FILTER_SUMMARY_LABELS,
|
|
361
365
|
DEFAULT_INLINE_EDIT_LABELS,
|
|
362
366
|
DEFAULT_INSIGHT_CARD_LABELS,
|
|
367
|
+
DEFAULT_KEYBOARD_GRAB_LABELS,
|
|
363
368
|
DEFAULT_LIGHTBOX_LABELS,
|
|
364
369
|
DEFAULT_MATCH_REVIEW_LABELS,
|
|
365
370
|
DEFAULT_ORG_CHART_LABELS,
|
|
@@ -431,6 +436,7 @@ export {
|
|
|
431
436
|
Kanban,
|
|
432
437
|
KanbanCard,
|
|
433
438
|
KanbanColumn,
|
|
439
|
+
KanbanDropLine,
|
|
434
440
|
Kbd,
|
|
435
441
|
KbdCombo,
|
|
436
442
|
Label,
|
|
@@ -453,6 +459,7 @@ export {
|
|
|
453
459
|
Meter,
|
|
454
460
|
MetricInput,
|
|
455
461
|
Modal,
|
|
462
|
+
MotionList,
|
|
456
463
|
NUMBER_FILTER_OPERATORS,
|
|
457
464
|
NavFavourites,
|
|
458
465
|
NavGroup,
|
|
@@ -519,6 +526,7 @@ export {
|
|
|
519
526
|
Step,
|
|
520
527
|
Steps,
|
|
521
528
|
SubNavItem,
|
|
529
|
+
SuccessState,
|
|
522
530
|
Switch,
|
|
523
531
|
TEXT_FILTER_OPERATORS,
|
|
524
532
|
TOAST_LEAVE_MS,
|
|
@@ -677,6 +685,7 @@ export {
|
|
|
677
685
|
selectRangeDate,
|
|
678
686
|
separateEdgeLabels,
|
|
679
687
|
setRuleCombinator,
|
|
688
|
+
settleDrop,
|
|
680
689
|
shiftSpan,
|
|
681
690
|
snapToStep,
|
|
682
691
|
splitDateTime,
|
|
@@ -704,11 +713,14 @@ export {
|
|
|
704
713
|
treeNav,
|
|
705
714
|
useAnchoredPosition,
|
|
706
715
|
useChangeHighlight,
|
|
716
|
+
useDeferredReorder,
|
|
707
717
|
useDelayedPending,
|
|
708
718
|
useDialog,
|
|
709
719
|
useDisplayPreferences,
|
|
720
|
+
useKeyboardGrab,
|
|
710
721
|
useOptimisticValue,
|
|
711
722
|
useReducedMotion,
|
|
723
|
+
useSlidingIndicator,
|
|
712
724
|
useTable,
|
|
713
725
|
useUixLabels,
|
|
714
726
|
useVirtualRows,
|
package/dist/labels-context.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { OrgChartLabels } from './components/OrgChart.js';
|
|
|
17
17
|
import { InlineEditLabels } from './components/InlineEdit.js';
|
|
18
18
|
import { DiscardPromptLabels } from './components/DiscardPrompt.js';
|
|
19
19
|
import { SearchBarLabels } from './components/SearchBar.js';
|
|
20
|
+
import { KeyboardGrabLabels } from './hooks/useKeyboardGrab.js';
|
|
20
21
|
import { LightboxLabels } from './components/Lightbox.js';
|
|
21
22
|
import { SortableListLabels } from './components/SortableList.js';
|
|
22
23
|
import { DiffViewerLabels } from './components/DiffViewer.js';
|
|
@@ -143,6 +144,8 @@ interface UixLabels {
|
|
|
143
144
|
inlineEdit?: Partial<InlineEditLabels>;
|
|
144
145
|
/** `SortableList` (HAR-1375): the grip, Move up / Move down, the move announcement. */
|
|
145
146
|
sortableList?: Partial<SortableListLabels>;
|
|
147
|
+
/** `useKeyboardGrab` (HAR-2590): picked up, dropped, cancelled; `{label}`. */
|
|
148
|
+
keyboardGrab?: Partial<KeyboardGrabLabels>;
|
|
146
149
|
/** `typeToConfirmMismatch` (HAR-1831): `{value}` is the text to type. */
|
|
147
150
|
confirmDialog?: {
|
|
148
151
|
typeToConfirm?: string;
|
package/dist/motion.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare const KEY_OPENED = "data-uix-key-opened";
|
|
2
|
+
/** Start following the input modality (idempotent; capture phase, so nothing can hide it). */
|
|
3
|
+
declare function watchInputModality(): void;
|
|
4
|
+
/** Was the input that led here a key press? `false` before any input and on the server. */
|
|
5
|
+
declare function keyboardInitiated(): boolean;
|
|
6
|
+
/** Mark `el` instant when the current open or close came from the keyboard; clear it otherwise. */
|
|
7
|
+
declare function markKeyOpened(el: Element | null | undefined): void;
|
|
8
|
+
/** A time token (`--uix-dur-exit`) in milliseconds, read from `el` (default: the root), or `fallback`. */
|
|
9
|
+
declare function tokenMs(name: string, fallback: number, el?: Element | null): number;
|
|
10
|
+
|
|
11
|
+
export { KEY_OPENED, keyboardInitiated, markKeyOpened, tokenMs, watchInputModality };
|
package/dist/motion.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const KEY_OPENED = "data-uix-key-opened";
|
|
2
|
+
let keyboard = false;
|
|
3
|
+
let watching = false;
|
|
4
|
+
function watchInputModality() {
|
|
5
|
+
if (watching || typeof document === "undefined") return;
|
|
6
|
+
watching = true;
|
|
7
|
+
document.addEventListener("keydown", (event) => {
|
|
8
|
+
if (!["Shift", "Control", "Alt", "Meta"].includes(event.key)) keyboard = true;
|
|
9
|
+
}, true);
|
|
10
|
+
document.addEventListener("pointerdown", () => {
|
|
11
|
+
keyboard = false;
|
|
12
|
+
}, true);
|
|
13
|
+
}
|
|
14
|
+
function keyboardInitiated() {
|
|
15
|
+
return keyboard;
|
|
16
|
+
}
|
|
17
|
+
function markKeyOpened(el) {
|
|
18
|
+
if (!el) return;
|
|
19
|
+
if (keyboard) el.setAttribute(KEY_OPENED, "");
|
|
20
|
+
else el.removeAttribute(KEY_OPENED);
|
|
21
|
+
}
|
|
22
|
+
function tokenMs(name, fallback, el) {
|
|
23
|
+
if (typeof getComputedStyle === "undefined" || typeof document === "undefined") return fallback;
|
|
24
|
+
const raw = getComputedStyle(el ?? document.documentElement).getPropertyValue(name).trim();
|
|
25
|
+
const m = /^(-?\d*\.?\d+)(ms|s)$/.exec(raw);
|
|
26
|
+
if (!m) return fallback;
|
|
27
|
+
return m[2] === "s" ? Number(m[1]) * 1e3 : Number(m[1]);
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
KEY_OPENED,
|
|
31
|
+
keyboardInitiated,
|
|
32
|
+
markKeyOpened,
|
|
33
|
+
tokenMs,
|
|
34
|
+
watchInputModality
|
|
35
|
+
};
|
|
@@ -137,6 +137,8 @@ interface RoutedEdge {
|
|
|
137
137
|
bus: boolean;
|
|
138
138
|
/** The label wrapped to fit the column gap (at most two lines). */
|
|
139
139
|
labelLines: string[];
|
|
140
|
+
/** The widest chip the label may take at its place (map units): the column gap, or a bus stub. */
|
|
141
|
+
labelRoom: number;
|
|
140
142
|
}
|
|
141
143
|
interface LayeredColumn {
|
|
142
144
|
depth: number;
|
|
@@ -187,6 +189,15 @@ interface EdgeLabelBox {
|
|
|
187
189
|
y: number;
|
|
188
190
|
width: number;
|
|
189
191
|
height: number;
|
|
192
|
+
/** Placed first when labels compete for room (a toned, emphasised or one-of-a-kind label). */
|
|
193
|
+
priority?: number;
|
|
194
|
+
}
|
|
195
|
+
/** A box an edge label must not cover (a node), by its top-left corner. */
|
|
196
|
+
interface LabelObstacle {
|
|
197
|
+
x: number;
|
|
198
|
+
y: number;
|
|
199
|
+
width: number;
|
|
200
|
+
height: number;
|
|
190
201
|
}
|
|
191
202
|
/** Where a label is drawn after `separateEdgeLabels`, or that it is left out. */
|
|
192
203
|
interface PlacedEdgeLabel {
|
|
@@ -194,7 +205,7 @@ interface PlacedEdgeLabel {
|
|
|
194
205
|
y: number;
|
|
195
206
|
hidden: boolean;
|
|
196
207
|
}
|
|
197
|
-
/** The
|
|
208
|
+
/** The chip a wrapped edge label takes, from its lines (the meta type size, as `wrapEdgeLabel` assumes). */
|
|
198
209
|
declare function edgeLabelSize(lines: readonly string[]): {
|
|
199
210
|
width: number;
|
|
200
211
|
height: number;
|
|
@@ -204,14 +215,17 @@ declare function edgeLabelSize(lines: readonly string[]): {
|
|
|
204
215
|
* of each other in a dense layered column). Labels are taken top to bottom; one that overlaps a
|
|
205
216
|
* label already placed moves down just below it. A label that would have to move further than
|
|
206
217
|
* `maxShift` from its edge is left out instead (the relationship is still in the nodes'
|
|
207
|
-
* descriptions and in the list)
|
|
218
|
+
* descriptions and in the list), and so is one that would cover an `obstacle` (a node). Labels with
|
|
219
|
+
* a higher `priority` are placed first, so a repeated relation gives way to a one-of-a-kind or
|
|
220
|
+
* toned one. Deterministic: the same boxes give the same placement.
|
|
208
221
|
*/
|
|
209
222
|
declare function separateEdgeLabels(boxes: readonly EdgeLabelBox[], options?: {
|
|
210
223
|
gap?: number;
|
|
211
224
|
maxShift?: number;
|
|
225
|
+
obstacles?: readonly LabelObstacle[];
|
|
212
226
|
}): Map<string, PlacedEdgeLabel>;
|
|
213
227
|
type LayeredNavigationKey = 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'Home' | 'End';
|
|
214
228
|
/** Keyboard traversal over a layered layout: ←/→ along forward edges, ↑/↓ within a column. */
|
|
215
229
|
declare function layeredNeighbor(layout: LayeredLayout, currentId: string | undefined, key: LayeredNavigationKey): string | undefined;
|
|
216
230
|
|
|
217
|
-
export { type BoundedRelationshipGraph, type EdgeLabelBox, type LayeredColumn, type LayeredEdgeClassification, type LayeredEdgeKind, type LayeredItem, type LayeredLayout, type LayeredLayoutOptions, type LayeredNavigationKey, type PlacedEdgeLabel, type PositionedRelationshipNode, type RelationshipGraphArrow, type RelationshipGraphCluster, type RelationshipGraphEdge, type RelationshipGraphNode, type RelationshipGraphTone, type RoutedEdge, boundRelationshipGraph, classifyLayeredEdges, clusterIdFor, edgeLabelSize, layeredNeighbor, layoutLayeredGraph, layoutRelationshipGraph, relationshipNeighbors, separateEdgeLabels, traverseRelationshipNode, wrapEdgeLabel };
|
|
231
|
+
export { type BoundedRelationshipGraph, type EdgeLabelBox, type LabelObstacle, type LayeredColumn, type LayeredEdgeClassification, type LayeredEdgeKind, type LayeredItem, type LayeredLayout, type LayeredLayoutOptions, type LayeredNavigationKey, type PlacedEdgeLabel, type PositionedRelationshipNode, type RelationshipGraphArrow, type RelationshipGraphCluster, type RelationshipGraphEdge, type RelationshipGraphNode, type RelationshipGraphTone, type RoutedEdge, boundRelationshipGraph, classifyLayeredEdges, clusterIdFor, edgeLabelSize, layeredNeighbor, layoutLayeredGraph, layoutRelationshipGraph, relationshipNeighbors, separateEdgeLabels, traverseRelationshipNode, wrapEdgeLabel };
|
|
@@ -68,30 +68,37 @@ const LAYERED_PADDING = 16;
|
|
|
68
68
|
const LAYERED_HEADER = 28;
|
|
69
69
|
const GROUP_HEADER = 28;
|
|
70
70
|
const AUTO_LABEL_MAX_FANOUT = 4;
|
|
71
|
-
const LABEL_CHAR_WIDTH =
|
|
71
|
+
const LABEL_CHAR_WIDTH = 6.3;
|
|
72
|
+
const LABEL_PAD_X = 6;
|
|
73
|
+
const LABEL_PAD_Y = 3;
|
|
74
|
+
const LABEL_LINE = 15;
|
|
75
|
+
const BUS_INSET = 4;
|
|
76
|
+
const ARROW_LENGTH = 9;
|
|
72
77
|
const LABEL_MAX_LINES = 2;
|
|
73
78
|
function wrapEdgeLabel(label, width) {
|
|
74
79
|
const max = Math.max(4, Math.floor(width / LABEL_CHAR_WIDTH));
|
|
75
80
|
const clip = (word) => word.length > max ? `${word.slice(0, max - 1)}\u2026` : word;
|
|
81
|
+
const words = label.split(/\s+/).filter(Boolean);
|
|
76
82
|
const lines = [];
|
|
77
83
|
let current = "";
|
|
78
|
-
|
|
84
|
+
let placed = 0;
|
|
85
|
+
for (const word of words) {
|
|
79
86
|
const next = current ? `${current} ${word}` : word;
|
|
80
87
|
if (next.length <= max) {
|
|
81
88
|
current = next;
|
|
89
|
+
placed += 1;
|
|
82
90
|
continue;
|
|
83
91
|
}
|
|
84
92
|
if (current) lines.push(current);
|
|
85
|
-
current =
|
|
93
|
+
current = "";
|
|
86
94
|
if (lines.length === LABEL_MAX_LINES) break;
|
|
95
|
+
current = clip(word);
|
|
96
|
+
placed += 1;
|
|
87
97
|
}
|
|
88
98
|
if (current && lines.length < LABEL_MAX_LINES) lines.push(current);
|
|
89
|
-
if (lines.length
|
|
90
|
-
const
|
|
91
|
-
if (
|
|
92
|
-
const last = lines[LABEL_MAX_LINES - 1];
|
|
93
|
-
lines[LABEL_MAX_LINES - 1] = last.endsWith("\u2026") ? last : `${last.slice(0, Math.max(1, max - 1))}\u2026`;
|
|
94
|
-
}
|
|
99
|
+
if (placed < words.length && lines.length > 0) {
|
|
100
|
+
const last = lines[lines.length - 1];
|
|
101
|
+
if (!last.endsWith("\u2026")) lines[lines.length - 1] = last.length < max ? `${last}\u2026` : `${last.slice(0, max - 1)}\u2026`;
|
|
95
102
|
}
|
|
96
103
|
return lines;
|
|
97
104
|
}
|
|
@@ -403,9 +410,9 @@ function layoutLayeredGraph(nodes, edges, options = {}) {
|
|
|
403
410
|
startY = from.y + from.height / 2;
|
|
404
411
|
endX = to.x;
|
|
405
412
|
endY = to.y + to.height / 2;
|
|
406
|
-
const trunk = startX +
|
|
413
|
+
const trunk = startX + BUS_INSET;
|
|
407
414
|
path = busPath(startX, startY, trunk, endX, endY);
|
|
408
|
-
labelX = (trunk + endX) / 2;
|
|
415
|
+
labelX = (trunk + BUS_INSET + endX - ARROW_LENGTH) / 2;
|
|
409
416
|
labelY = endY;
|
|
410
417
|
startAngle = Math.PI;
|
|
411
418
|
endAngle = 0;
|
|
@@ -463,6 +470,7 @@ function layoutLayeredGraph(nodes, edges, options = {}) {
|
|
|
463
470
|
arrowY: round1(atStart ? startY : endY),
|
|
464
471
|
arrowAngle: atStart ? startAngle : endAngle,
|
|
465
472
|
labelLines: [],
|
|
473
|
+
labelRoom: columnGap - 8,
|
|
466
474
|
columnLabel: false,
|
|
467
475
|
bus: kind === "forward" && from.children.length > AUTO_LABEL_MAX_FANOUT,
|
|
468
476
|
autoLabel: to.kind !== "cluster" && (edge.emphasis === true || kind === "forward" && from.children.length <= AUTO_LABEL_MAX_FANOUT)
|
|
@@ -508,7 +516,9 @@ function layoutLayeredGraph(nodes, edges, options = {}) {
|
|
|
508
516
|
const seenLabels = /* @__PURE__ */ new Set();
|
|
509
517
|
for (const entry of routed.values()) {
|
|
510
518
|
if (entry.label === void 0) continue;
|
|
511
|
-
|
|
519
|
+
const run = entry.bus ? columnGap - 2 * BUS_INSET - ARROW_LENGTH : columnGap - 8;
|
|
520
|
+
entry.labelRoom = run;
|
|
521
|
+
entry.labelLines = wrapEdgeLabel(entry.label, run - 2 * LABEL_PAD_X);
|
|
512
522
|
if (!entry.autoLabel || entry.emphasis || entry.kind !== "forward") continue;
|
|
513
523
|
const key = `${entry.source}|${entry.label}`;
|
|
514
524
|
if (seenLabels.has(key)) entry.autoLabel = false;
|
|
@@ -530,14 +540,15 @@ function layoutLayeredGraph(nodes, edges, options = {}) {
|
|
|
530
540
|
}
|
|
531
541
|
function edgeLabelSize(lines) {
|
|
532
542
|
const longest = lines.reduce((max, line) => Math.max(max, line.length), 0);
|
|
533
|
-
return { width: longest * LABEL_CHAR_WIDTH +
|
|
543
|
+
return { width: longest * LABEL_CHAR_WIDTH + 2 * LABEL_PAD_X, height: Math.max(1, lines.length) * LABEL_LINE + 2 * LABEL_PAD_Y };
|
|
534
544
|
}
|
|
535
545
|
function separateEdgeLabels(boxes, options = {}) {
|
|
536
546
|
const gap = options.gap ?? 2;
|
|
537
|
-
const maxShift = options.maxShift ??
|
|
547
|
+
const maxShift = options.maxShift ?? 48;
|
|
538
548
|
const placed = [];
|
|
539
549
|
const result = /* @__PURE__ */ new Map();
|
|
540
|
-
const
|
|
550
|
+
const obstacles = options.obstacles ?? [];
|
|
551
|
+
const ordered = [...boxes].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0) || a.y - b.y || a.x - b.x || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
541
552
|
for (const box of ordered) {
|
|
542
553
|
const left = box.x - box.width / 2;
|
|
543
554
|
const right = box.x + box.width / 2;
|
|
@@ -548,7 +559,8 @@ function separateEdgeLabels(boxes, options = {}) {
|
|
|
548
559
|
top = hit.bottom + gap;
|
|
549
560
|
}
|
|
550
561
|
const shift = top - (box.y - box.height / 2);
|
|
551
|
-
|
|
562
|
+
const covers = obstacles.some((o) => left < o.x + o.width && o.x < right && top < o.y + o.height && o.y < top + box.height);
|
|
563
|
+
if (shift > maxShift || covers) {
|
|
552
564
|
result.set(box.id, { x: box.x, y: box.y, hidden: true });
|
|
553
565
|
continue;
|
|
554
566
|
}
|
package/dist/rich-text.cjs
CHANGED
|
@@ -1369,12 +1369,17 @@ function removeAnchorName(el, name) {
|
|
|
1369
1369
|
else el.style.removeProperty("anchor-name");
|
|
1370
1370
|
}
|
|
1371
1371
|
function translationOf(el) {
|
|
1372
|
-
const
|
|
1372
|
+
const style = getComputedStyle(el);
|
|
1373
|
+
const t = style.transform;
|
|
1373
1374
|
if (!t || t === "none" || typeof DOMMatrixReadOnly === "undefined") return { x: 0, y: 0 };
|
|
1374
1375
|
try {
|
|
1375
1376
|
const m = new DOMMatrixReadOnly(t);
|
|
1377
|
+
const [ox = 0, oy = 0] = style.transformOrigin.split(" ").map((v) => parseFloat(v) || 0);
|
|
1378
|
+
const cx2 = el.offsetWidth / 2 - ox;
|
|
1379
|
+
const cy = el.offsetHeight / 2 - oy;
|
|
1380
|
+
const p = m.transformPoint({ x: cx2, y: cy });
|
|
1376
1381
|
const z = zoomOf(el);
|
|
1377
|
-
return { x:
|
|
1382
|
+
return { x: (p.x - cx2) * z, y: (p.y - cy) * z };
|
|
1378
1383
|
} catch {
|
|
1379
1384
|
return { x: 0, y: 0 };
|
|
1380
1385
|
}
|
|
@@ -1471,6 +1476,13 @@ function useAnchoredPosition(anchor, floatingRef, { open, placement = "bottom-st
|
|
|
1471
1476
|
const measured = size.width > 0 || size.height > 0;
|
|
1472
1477
|
if (measured && session.current) side.current = pos.side;
|
|
1473
1478
|
if (floating.dataset.placement !== pos.placement) floating.dataset.placement = pos.placement;
|
|
1479
|
+
if (measured) {
|
|
1480
|
+
const clamp2 = (v, max) => Math.min(Math.max(v, 0), max);
|
|
1481
|
+
const ox = pos.side === "left" ? size.width : pos.side === "right" ? 0 : clamp2(a.x + a.width / 2 - pos.x, size.width);
|
|
1482
|
+
const oy = pos.side === "top" ? size.height : pos.side === "bottom" ? 0 : clamp2(a.y + a.height / 2 - pos.y, size.height);
|
|
1483
|
+
const origin = `${Math.round(ox / zoom)}px ${Math.round(oy / zoom)}px`;
|
|
1484
|
+
if (s.getPropertyValue("--uix-anchor-origin") !== origin) s.setProperty("--uix-anchor-origin", origin);
|
|
1485
|
+
}
|
|
1474
1486
|
const writeFixed = (at) => {
|
|
1475
1487
|
const left2 = `${Math.round(at.x / zoom)}px`;
|
|
1476
1488
|
const top2 = `${Math.round(at.y / zoom)}px`;
|
|
@@ -1567,6 +1579,26 @@ function useAnchoredPosition(anchor, floatingRef, { open, placement = "bottom-st
|
|
|
1567
1579
|
return reposition;
|
|
1568
1580
|
}
|
|
1569
1581
|
|
|
1582
|
+
// src/motion.ts
|
|
1583
|
+
var KEY_OPENED = "data-uix-key-opened";
|
|
1584
|
+
var keyboard = false;
|
|
1585
|
+
var watching = false;
|
|
1586
|
+
function watchInputModality() {
|
|
1587
|
+
if (watching || typeof document === "undefined") return;
|
|
1588
|
+
watching = true;
|
|
1589
|
+
document.addEventListener("keydown", (event) => {
|
|
1590
|
+
if (!["Shift", "Control", "Alt", "Meta"].includes(event.key)) keyboard = true;
|
|
1591
|
+
}, true);
|
|
1592
|
+
document.addEventListener("pointerdown", () => {
|
|
1593
|
+
keyboard = false;
|
|
1594
|
+
}, true);
|
|
1595
|
+
}
|
|
1596
|
+
function markKeyOpened(el) {
|
|
1597
|
+
if (!el) return;
|
|
1598
|
+
if (keyboard) el.setAttribute(KEY_OPENED, "");
|
|
1599
|
+
else el.removeAttribute(KEY_OPENED);
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1570
1602
|
// src/components/Popover.tsx
|
|
1571
1603
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1572
1604
|
var useIsomorphicLayoutEffect2 = typeof document !== "undefined" ? import_react4.useLayoutEffect : import_react4.useEffect;
|
|
@@ -1620,6 +1652,14 @@ function Popover({
|
|
|
1620
1652
|
el.hidePopover();
|
|
1621
1653
|
} : void 0
|
|
1622
1654
|
});
|
|
1655
|
+
(0, import_react4.useEffect)(() => {
|
|
1656
|
+
watchInputModality();
|
|
1657
|
+
const el = ref.current;
|
|
1658
|
+
if (!el) return;
|
|
1659
|
+
const mark = () => markKeyOpened(el);
|
|
1660
|
+
el.addEventListener("beforetoggle", mark);
|
|
1661
|
+
return () => el.removeEventListener("beforetoggle", mark);
|
|
1662
|
+
}, []);
|
|
1623
1663
|
(0, import_react4.useEffect)(() => {
|
|
1624
1664
|
const el = ref.current;
|
|
1625
1665
|
if (!el || !anchor) return;
|
package/dist/toast-store.d.ts
CHANGED
|
@@ -74,8 +74,11 @@ interface ToastStore {
|
|
|
74
74
|
subscribe: (listener: () => void) => () => void;
|
|
75
75
|
getSnapshot: () => readonly ToastRecord[];
|
|
76
76
|
}
|
|
77
|
-
/**
|
|
78
|
-
|
|
77
|
+
/**
|
|
78
|
+
* How long the leave transition gets before the record is removed when no stylesheet answers:
|
|
79
|
+
* the store reads `--uix-dur-exit` (toast.css leaves on it), so the two never disagree (HAR-2578).
|
|
80
|
+
*/
|
|
81
|
+
declare const TOAST_LEAVE_MS = 110;
|
|
79
82
|
/** A separate queue, e.g. per test or per embedded app. Most products use the default `toast`. */
|
|
80
83
|
declare function createToastStore(): ToastStore;
|
|
81
84
|
interface ToastApi {
|
package/dist/toast-store.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { tokenMs } from "./motion.js";
|
|
1
2
|
const DEFAULT_DURATION = {
|
|
2
3
|
success: 5e3,
|
|
3
4
|
info: 5e3,
|
|
@@ -6,7 +7,7 @@ const DEFAULT_DURATION = {
|
|
|
6
7
|
error: null,
|
|
7
8
|
loading: null
|
|
8
9
|
};
|
|
9
|
-
const TOAST_LEAVE_MS =
|
|
10
|
+
const TOAST_LEAVE_MS = 110;
|
|
10
11
|
let counter = 0;
|
|
11
12
|
function createToastStore() {
|
|
12
13
|
let records = [];
|
|
@@ -52,7 +53,7 @@ function createToastStore() {
|
|
|
52
53
|
set(records.map((r) => ids.has(r.id) ? { ...r, leaving: true } : r));
|
|
53
54
|
for (const r of closing) r.onDismiss?.(reason);
|
|
54
55
|
const remove = () => set(records.filter((r) => !(ids.has(r.id) && r.leaving)));
|
|
55
|
-
if (typeof setTimeout === "function") setTimeout(remove, TOAST_LEAVE_MS);
|
|
56
|
+
if (typeof setTimeout === "function") setTimeout(remove, tokenMs("--uix-dur-exit", TOAST_LEAVE_MS));
|
|
56
57
|
else remove();
|
|
57
58
|
};
|
|
58
59
|
return {
|