@tensor_1/react 2.29.0 → 2.31.0

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/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ export { Input, InputGroup, InputGroupProps, InputProps } from './components/Inp
11
11
  export { Combobox, ComboboxProps } from './components/Combobox.js';
12
12
  export { ComboboxOption, filterComboboxOptions } from './combobox-model.js';
13
13
  export { SearchSuggest, SearchSuggestAction, SearchSuggestOption, SearchSuggestProps } from './components/SearchSuggest.js';
14
+ export { DEFAULT_ENTITY_PICKER_LABELS, EntityPicker, EntityPickerLabels, EntityPickerProps } from './components/EntityPicker.js';
14
15
  export { FoldedText, SearchSegment, foldForSearch, searchSegments } from './search-suggest-model.js';
15
16
  export { Textarea, TextareaProps } from './components/Textarea.js';
16
17
  export { Select, SelectProps } from './components/Select.js';
@@ -22,6 +23,7 @@ export { Modal, ModalProps } from './components/Modal.js';
22
23
  export { ConfirmDialog, ConfirmDialogProps, Popconfirm, PopconfirmProps, PromptDialog, PromptDialogProps } from './components/Dialogs.js';
23
24
  export { Drawer, DrawerProps } from './components/Drawer.js';
24
25
  export { Peek, PeekProps } from './components/Peek.js';
26
+ export { DEFAULT_LIGHTBOX_LABELS, Lightbox, LightboxItem, LightboxLabels, LightboxProps } from './components/Lightbox.js';
25
27
  export { Card, CardLink, CardLinkProps, CardProps } from './components/Card.js';
26
28
  export { BreadcrumbItem, Breadcrumbs, BreadcrumbsProps } from './components/Breadcrumbs.js';
27
29
  export { PageHeader, PageHeaderProps } from './components/PageHeader.js';
@@ -38,6 +40,9 @@ export { NavGroup, NavGroupProps, NavItem, NavItemProps, Sidebar, SidebarProps,
38
40
  export { StarButton, StarButtonProps } from './components/StarButton.js';
39
41
  export { CopyButton, CopyButtonProps } from './components/CopyButton.js';
40
42
  export { NavFavouriteItem, NavFavourites, NavFavouritesLabels, NavFavouritesProps } from './components/NavFavourites.js';
43
+ export { DEFAULT_FILE_UPLOAD_LABELS, FileUpload, FileUploadItem, FileUploadLabels, FileUploadProps, FileUploadStatus } from './components/FileUpload.js';
44
+ export { Attachment, AttachmentLabels, AttachmentList, AttachmentListProps, AttachmentProps, DEFAULT_ATTACHMENT_LABELS } from './components/Attachment.js';
45
+ export { FileRejection, FileRejectionReason, fileKind, fileMatchesAccept, formatFileSize, partitionFiles } from './file-model.js';
41
46
  export { Alert, AlertProps, AlertTone } from './components/Alert.js';
42
47
  export { Spinner, SpinnerProps } from './components/Spinner.js';
43
48
  export { Toast, ToastProps, ToastTone, Toaster, ToasterProps } from './components/Toast.js';
@@ -65,6 +70,8 @@ export { DEFAULT_SAVE_STATUS_LABELS, SaveStatus, SaveStatusLabels, SaveStatusPro
65
70
  export { Composer, ComposerBar, ComposerBarProps, ComposerProps } from './components/Composer.js';
66
71
  export { Segmented, SegmentedOption, SegmentedOptionProps, SegmentedProps } from './components/Segmented.js';
67
72
  export { FilterOption, FilterPopover, FilterPopoverProps, SavedViewItem, SavedViewMenu, SavedViewMenuProps, SavedViewSection, ViewMenu, ViewMenuColumn, ViewMenuColumnLabels, ViewMenuProps } from './components/TableControls.js';
73
+ export { DEFAULT_FILTER_EDITOR_LABELS, FilterEditor, FilterEditorLabels, FilterEditorProps } from './components/FilterEditor.js';
74
+ export { DEFAULT_FILTER_SUMMARY_LABELS, FilterChoice, FilterField, FilterSummaryLabels, FilterValue, FilterValueKind, NUMBER_FILTER_OPERATORS, NumberFilterOperator, SummarizeFilterOptions, TEXT_FILTER_OPERATORS, TextFilterOperator, emptyFilterValue, isFilterEmpty, summarizeFilter } from './filter-model.js';
68
75
  export { Timeline, TimelineItem, TimelineItemProps, TimelineProps } from './components/Timeline.js';
69
76
  export { Pipeline, PipelineProps, PipelineStage, PipelineStageProps, PipelineStageState } from './components/Pipeline.js';
70
77
  export { Flow, FlowNode, FlowNodeProps, FlowNodeState, FlowProps, FlowVariant } from './components/Flow.js';
@@ -82,6 +89,8 @@ export { DEFAULT_RULE_BUILDER_LABELS, RuleActionDefinition, RuleBuilder, RuleBui
82
89
  export { RuleAction, RuleCondition, RuleDefinition, RuleGroup, RuleValidationIssue, appendRuleNode, findRuleNodeDepth, isRuleGroup, mapRuleGroup, moveRuleNode, removeRuleNode, ruleDepth, summarizeRule, validateRuleDefinition } from './rule-builder-model.js';
83
90
  export { BuilderCanvas, BuilderCanvasItem, BuilderCanvasLabels, BuilderCanvasProps, BuilderPaletteItem, DEFAULT_BUILDER_CANVAS_LABELS } from './components/BuilderCanvas.js';
84
91
  export { DEFAULT_SCHEDULING_CALENDAR_LABELS, SchedulingCalendar, SchedulingCalendarEntry, SchedulingCalendarLabels, SchedulingCalendarOverlay, SchedulingCalendarProps, SchedulingCalendarView, SchedulingDatePart, SchedulingEntryState, SchedulingOverlayKind } from './components/SchedulingCalendar.js';
92
+ export { DEFAULT_SCHEDULING_TIMELINE_LABELS, SchedulingTimeline, SchedulingTimelineItem, SchedulingTimelineLabels, SchedulingTimelineLane, SchedulingTimelineMarker, SchedulingTimelineOverlay, SchedulingTimelineOverlayKind, SchedulingTimelineProps } from './components/SchedulingTimeline.js';
93
+ export { DAY, HOUR, PlacedSpan, TimelineRange, TimelineScale, TimelineSpan, TimelineTick, defaultTimelineStep, layoutLane, pixelsToMs, placeSpan, shiftSpan, snapToStep, timelineTicks } from './scheduling-timeline-model.js';
85
94
  export { DEFAULT_DATE_RANGE_PICKER_LABELS, DateRangePicker, DateRangePickerLabels, DateRangePickerProps } from './components/DateRangePicker.js';
86
95
  export { CalendarDay, CalendarWeekday, DateRangeValue, ZonedDateSpan, addCalendarDays, addCalendarMonths, buildMonthGrid, enumerateDateSpan, isDateInRange, isDateUnavailable, selectRangeDate, startOfMonth, toDateKey, zonedDateKey, zonedDateSpan } from './calendar-model.js';
87
96
  export { DEFAULT_RELATIONSHIP_GRAPH_LABELS, RelationshipGraph, RelationshipGraphLabels, RelationshipGraphLegendItem, RelationshipGraphProps } from './components/RelationshipGraph.js';
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import { Input, InputGroup } from "./components/Input.js";
11
11
  import { Combobox } from "./components/Combobox.js";
12
12
  import { filterComboboxOptions } from "./combobox-model.js";
13
13
  import { SearchSuggest } from "./components/SearchSuggest.js";
14
+ import { EntityPicker, DEFAULT_ENTITY_PICKER_LABELS } from "./components/EntityPicker.js";
14
15
  import { searchSegments, foldForSearch } from "./search-suggest-model.js";
15
16
  import { Textarea } from "./components/Textarea.js";
16
17
  import { Select } from "./components/Select.js";
@@ -22,6 +23,7 @@ import { Modal } from "./components/Modal.js";
22
23
  import { ConfirmDialog, Popconfirm, PromptDialog } from "./components/Dialogs.js";
23
24
  import { Drawer } from "./components/Drawer.js";
24
25
  import { Peek } from "./components/Peek.js";
26
+ import { Lightbox, DEFAULT_LIGHTBOX_LABELS } from "./components/Lightbox.js";
25
27
  import { Card, CardLink } from "./components/Card.js";
26
28
  import { Breadcrumbs } from "./components/Breadcrumbs.js";
27
29
  import { PageHeader } from "./components/PageHeader.js";
@@ -38,6 +40,9 @@ import { Sidebar, SidebarSection, NavItem, NavGroup, SubNavItem } from "./compon
38
40
  import { StarButton } from "./components/StarButton.js";
39
41
  import { CopyButton } from "./components/CopyButton.js";
40
42
  import { NavFavourites } from "./components/NavFavourites.js";
43
+ import { FileUpload, DEFAULT_FILE_UPLOAD_LABELS } from "./components/FileUpload.js";
44
+ import { Attachment, AttachmentList, DEFAULT_ATTACHMENT_LABELS } from "./components/Attachment.js";
45
+ import { fileKind, fileMatchesAccept, formatFileSize, partitionFiles } from "./file-model.js";
41
46
  import { Alert } from "./components/Alert.js";
42
47
  import { Spinner } from "./components/Spinner.js";
43
48
  import { Toast, Toaster } from "./components/Toast.js";
@@ -79,6 +84,15 @@ import { SaveStatus, DEFAULT_SAVE_STATUS_LABELS } from "./components/SaveStatus.
79
84
  import { Composer, ComposerBar } from "./components/Composer.js";
80
85
  import { Segmented, SegmentedOption } from "./components/Segmented.js";
81
86
  import { ViewMenu, FilterPopover, SavedViewMenu } from "./components/TableControls.js";
87
+ import { FilterEditor, DEFAULT_FILTER_EDITOR_LABELS } from "./components/FilterEditor.js";
88
+ import {
89
+ DEFAULT_FILTER_SUMMARY_LABELS,
90
+ NUMBER_FILTER_OPERATORS,
91
+ TEXT_FILTER_OPERATORS,
92
+ emptyFilterValue,
93
+ isFilterEmpty,
94
+ summarizeFilter
95
+ } from "./filter-model.js";
82
96
  import { Timeline, TimelineItem } from "./components/Timeline.js";
83
97
  import { Pipeline, PipelineStage } from "./components/Pipeline.js";
84
98
  import { Flow, FlowNode } from "./components/Flow.js";
@@ -119,6 +133,18 @@ import {
119
133
  } from "./rule-builder-model.js";
120
134
  import { BuilderCanvas, DEFAULT_BUILDER_CANVAS_LABELS } from "./components/BuilderCanvas.js";
121
135
  import { DEFAULT_SCHEDULING_CALENDAR_LABELS, SchedulingCalendar } from "./components/SchedulingCalendar.js";
136
+ import { DEFAULT_SCHEDULING_TIMELINE_LABELS, SchedulingTimeline } from "./components/SchedulingTimeline.js";
137
+ import {
138
+ DAY,
139
+ HOUR,
140
+ defaultTimelineStep,
141
+ layoutLane,
142
+ pixelsToMs,
143
+ placeSpan,
144
+ shiftSpan,
145
+ snapToStep,
146
+ timelineTicks
147
+ } from "./scheduling-timeline-model.js";
122
148
  import { DateRangePicker, DEFAULT_DATE_RANGE_PICKER_LABELS } from "./components/DateRangePicker.js";
123
149
  import {
124
150
  addCalendarDays,
@@ -148,6 +174,8 @@ export {
148
174
  Alert,
149
175
  AppShell,
150
176
  AsyncOperationStatus,
177
+ Attachment,
178
+ AttachmentList,
151
179
  Avatar,
152
180
  AvatarGroup,
153
181
  BrandProfileEditor,
@@ -179,17 +207,25 @@ export {
179
207
  ContentList,
180
208
  ContentListItem,
181
209
  CopyButton,
210
+ DAY,
211
+ DEFAULT_ATTACHMENT_LABELS,
182
212
  DEFAULT_BRAND_PROFILE_EDITOR_LABELS,
183
213
  DEFAULT_BUILDER_CANVAS_LABELS,
184
214
  DEFAULT_COLOR_PICKER_LABELS,
185
215
  DEFAULT_DATE_RANGE_PICKER_LABELS,
186
216
  DEFAULT_DIFF_VIEWER_LABELS,
217
+ DEFAULT_ENTITY_PICKER_LABELS,
218
+ DEFAULT_FILE_UPLOAD_LABELS,
219
+ DEFAULT_FILTER_EDITOR_LABELS,
220
+ DEFAULT_FILTER_SUMMARY_LABELS,
221
+ DEFAULT_LIGHTBOX_LABELS,
187
222
  DEFAULT_MATCH_REVIEW_LABELS,
188
223
  DEFAULT_PAGINATION_LABELS,
189
224
  DEFAULT_RELATIONSHIP_GRAPH_LABELS,
190
225
  DEFAULT_RULE_BUILDER_LABELS,
191
226
  DEFAULT_SAVE_STATUS_LABELS,
192
227
  DEFAULT_SCHEDULING_CALENDAR_LABELS,
228
+ DEFAULT_SCHEDULING_TIMELINE_LABELS,
193
229
  DEFAULT_STEP_STATE_LABELS,
194
230
  DateRangePicker,
195
231
  DescriptionItem,
@@ -199,6 +235,7 @@ export {
199
235
  DiffViewer,
200
236
  Drawer,
201
237
  EmptyState,
238
+ EntityPicker,
202
239
  ErrorState,
203
240
  EventRow,
204
241
  ExpandToggle,
@@ -206,11 +243,14 @@ export {
206
243
  FeaturedRundownItem,
207
244
  FeaturedStage,
208
245
  Field,
246
+ FileUpload,
247
+ FilterEditor,
209
248
  FilterPopover,
210
249
  FilteredEmptyState,
211
250
  Flow,
212
251
  FlowNode,
213
252
  ForbiddenState,
253
+ HOUR,
214
254
  Highlighted,
215
255
  Inbox,
216
256
  InboxDetail,
@@ -226,6 +266,7 @@ export {
226
266
  KbdCombo,
227
267
  Label,
228
268
  LicensePositionBar,
269
+ Lightbox,
229
270
  List,
230
271
  ListItem,
231
272
  LoadingState,
@@ -238,6 +279,7 @@ export {
238
279
  Meter,
239
280
  MetricInput,
240
281
  Modal,
282
+ NUMBER_FILTER_OPERATORS,
241
283
  NavFavourites,
242
284
  NavGroup,
243
285
  NavItem,
@@ -268,6 +310,7 @@ export {
268
310
  SaveStatus,
269
311
  SavedViewMenu,
270
312
  SchedulingCalendar,
313
+ SchedulingTimeline,
271
314
  SearchSuggest,
272
315
  SectionHead,
273
316
  Segmented,
@@ -286,6 +329,7 @@ export {
286
329
  Steps,
287
330
  SubNavItem,
288
331
  Switch,
332
+ TEXT_FILTER_OPERATORS,
289
333
  TOAST_LEAVE_MS,
290
334
  Tab,
291
335
  TabPanel,
@@ -321,18 +365,25 @@ export {
321
365
  createToastApi,
322
366
  createToastStore,
323
367
  cx,
368
+ defaultTimelineStep,
369
+ emptyFilterValue,
324
370
  enumerateDateSpan,
371
+ fileKind,
372
+ fileMatchesAccept,
325
373
  filterComboboxOptions,
326
374
  findRuleNodeDepth,
327
375
  flattenTree,
328
376
  foldForSearch,
377
+ formatFileSize,
329
378
  hexToRgb,
330
379
  hsvToHex,
331
380
  hsvToRgb,
332
381
  isDateInRange,
333
382
  isDateUnavailable,
383
+ isFilterEmpty,
334
384
  isRuleGroup,
335
385
  layeredNeighbor,
386
+ layoutLane,
336
387
  layoutLayeredGraph,
337
388
  layoutRelationshipGraph,
338
389
  mapRuleGroup,
@@ -341,6 +392,9 @@ export {
341
392
  normalizeHex,
342
393
  parseDateValue,
343
394
  parseMetricValue,
395
+ partitionFiles,
396
+ pixelsToMs,
397
+ placeSpan,
344
398
  relationshipNeighbors,
345
399
  relativeTimeValue,
346
400
  removeRuleNode,
@@ -351,10 +405,14 @@ export {
351
405
  ruleDepth,
352
406
  searchSegments,
353
407
  selectRangeDate,
408
+ shiftSpan,
409
+ snapToStep,
354
410
  startOfMonth,
355
411
  stepMetricValue,
356
412
  summarizeDiff,
413
+ summarizeFilter,
357
414
  summarizeRule,
415
+ timelineTicks,
358
416
  toDateKey,
359
417
  toast,
360
418
  traverseRelationshipNode,
@@ -3,8 +3,10 @@ import { ReactNode } from 'react';
3
3
  import { PaginationLabels } from './components/Pagination.js';
4
4
  import { SchedulingCalendarLabels } from './components/SchedulingCalendar.js';
5
5
  import { DateRangePickerLabels } from './components/DateRangePicker.js';
6
+ import { SchedulingTimelineLabels } from './components/SchedulingTimeline.js';
6
7
  import './link.js';
7
8
  import './calendar-model.js';
9
+ import './scheduling-timeline-model.js';
8
10
 
9
11
  /**
10
12
  * Kit chrome strings by component (HAR-1358; TENSOR C20, MOTUS executive summary #3).
@@ -53,6 +55,7 @@ interface UixLabels {
53
55
  };
54
56
  schedulingCalendar?: Partial<SchedulingCalendarLabels>;
55
57
  dateRangePicker?: Partial<DateRangePickerLabels>;
58
+ schedulingTimeline?: Partial<SchedulingTimelineLabels>;
56
59
  /** Read by `useUixLabels()` callers; `Pagination` itself is server-safe and takes `labels`. */
57
60
  pagination?: Partial<PaginationLabels>;
58
61
  /** Read by `useUixLabels()` callers; `BulkBar` itself is server-safe and takes `label`. */
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Pure model for `SchedulingTimeline` (HAR-1364; TENSOR C8): ticks on a time axis, where a
3
+ * bar sits on it, which bars in a lane overlap (and so stack and are flagged), and how a
4
+ * keyboard or pointer move snaps. Instants are ISO 8601 strings or epoch milliseconds; the
5
+ * axis is linear in real time, and only labels depend on the time zone.
6
+ */
7
+ type TimelineScale = 'hour' | 'day' | 'week' | 'month';
8
+ interface TimelineRange {
9
+ start: string;
10
+ end: string;
11
+ }
12
+ interface TimelineTick {
13
+ /** Epoch ms of the tick. */
14
+ at: number;
15
+ /** Position on the axis, 0–100. */
16
+ offset: number;
17
+ /** A major tick starts a larger unit (a new day on an hour axis, a new month on a day axis). */
18
+ major: boolean;
19
+ }
20
+ interface TimelineSpan {
21
+ id: string;
22
+ start: string;
23
+ end: string;
24
+ }
25
+ interface PlacedSpan<T extends TimelineSpan = TimelineSpan> {
26
+ item: T;
27
+ /** 0–100, clamped to the visible range. */
28
+ left: number;
29
+ width: number;
30
+ /** Starts before / ends after the visible range (draw a cut edge). */
31
+ clippedStart: boolean;
32
+ clippedEnd: boolean;
33
+ /** Sub-row inside the lane, so overlapping bars stack instead of covering each other. */
34
+ row: number;
35
+ /** Overlaps at least one other bar in the same lane. */
36
+ conflict: boolean;
37
+ }
38
+ declare const HOUR = 3600000;
39
+ declare const DAY: number;
40
+ /** The default move/resize step for a scale: 15 min on an hour axis, 1 h on a day axis, 1 day otherwise. */
41
+ declare const defaultTimelineStep: (scale: TimelineScale) => number;
42
+ /**
43
+ * Ticks for the range at the scale's unit (hour, day, week starting `weekStartsOn`, month),
44
+ * aligned to wall-clock boundaries in `timeZone`. Bounded to 500 ticks; a month axis over a
45
+ * year walks ~8,800 hours, so keep ranges to what fits on screen.
46
+ */
47
+ declare function timelineTicks(range: TimelineRange, scale: TimelineScale, timeZone: string, weekStartsOn?: number): TimelineTick[];
48
+ /** Position of one span on the axis, clamped to it; null when it is entirely outside. */
49
+ declare function placeSpan(span: {
50
+ start: string;
51
+ end: string;
52
+ }, range: TimelineRange): Omit<PlacedSpan, 'item' | 'row' | 'conflict'> | null;
53
+ /**
54
+ * Places a lane's spans: sorted by start, each in the first sub-row where it does not overlap
55
+ * the previous bar, and flagged `conflict` when it overlaps any other span in the lane.
56
+ */
57
+ declare function layoutLane<T extends TimelineSpan>(items: readonly T[], range: TimelineRange): PlacedSpan<T>[];
58
+ /** Rounds a millisecond offset to the nearest step. */
59
+ declare const snapToStep: (ms: number, step: number) => number;
60
+ /** A span moved (both ends) or resized (end only) by `delta` ms, as ISO strings; never shorter than one step. */
61
+ declare function shiftSpan(span: {
62
+ start: string;
63
+ end: string;
64
+ }, delta: number, mode: 'move' | 'resize', step: number): {
65
+ start: string;
66
+ end: string;
67
+ };
68
+ /** Converts a horizontal pointer distance on a track of `trackWidth` px to snapped milliseconds. */
69
+ declare function pixelsToMs(px: number, trackWidth: number, range: TimelineRange, step: number): number;
70
+
71
+ export { DAY, HOUR, type PlacedSpan, type TimelineRange, type TimelineScale, type TimelineSpan, type TimelineTick, defaultTimelineStep, layoutLane, pixelsToMs, placeSpan, shiftSpan, snapToStep, timelineTicks };
@@ -0,0 +1,108 @@
1
+ const HOUR = 36e5;
2
+ const DAY = 24 * HOUR;
3
+ const toMs = (value) => {
4
+ const ms = typeof value === "number" ? value : Date.parse(value);
5
+ if (Number.isNaN(ms)) throw new TypeError(`Invalid instant: ${String(value)}`);
6
+ return ms;
7
+ };
8
+ const defaultTimelineStep = (scale) => scale === "hour" ? 15 * 6e4 : scale === "day" ? HOUR : DAY;
9
+ function zonedParts(ms, timeZone) {
10
+ const parts = new Intl.DateTimeFormat("en-US", {
11
+ timeZone,
12
+ hourCycle: "h23",
13
+ year: "numeric",
14
+ month: "numeric",
15
+ day: "numeric",
16
+ hour: "numeric",
17
+ minute: "numeric",
18
+ weekday: "short"
19
+ }).formatToParts(new Date(ms));
20
+ const get = (type) => parts.find((p) => p.type === type)?.value ?? "";
21
+ return { year: +get("year"), month: +get("month"), day: +get("day"), hour: +get("hour"), minute: +get("minute"), weekday: get("weekday") };
22
+ }
23
+ function timelineTicks(range, scale, timeZone, weekStartsOn = 1) {
24
+ const start = toMs(range.start);
25
+ const end = toMs(range.end);
26
+ if (end <= start) return [];
27
+ const span = end - start;
28
+ const ticks = [];
29
+ const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
30
+ const step = scale === "hour" ? 15 * 6e4 : HOUR;
31
+ let prev = zonedParts(start - step, timeZone);
32
+ for (let at = Math.ceil(start / step) * step; at <= end && ticks.length < 500; at += step) {
33
+ const p = zonedParts(at, timeZone);
34
+ const newHour = p.minute === 0 && (p.hour !== prev.hour || prev.minute !== 0);
35
+ const newDay = p.day !== prev.day && p.minute === 0;
36
+ const newMonth = newDay && p.day === 1;
37
+ const newWeek = newDay && weekdays.indexOf(p.weekday) === weekStartsOn;
38
+ const isTick = scale === "hour" ? newHour : scale === "day" ? newDay : scale === "week" ? newWeek : newMonth;
39
+ if (isTick) {
40
+ const major = scale === "hour" ? newDay : scale === "day" ? newWeek : scale === "week" ? newMonth : p.month === 1;
41
+ ticks.push({ at, offset: (at - start) / span * 100, major });
42
+ }
43
+ prev = p;
44
+ }
45
+ return ticks;
46
+ }
47
+ function placeSpan(span, range) {
48
+ const start = toMs(range.start);
49
+ const end = toMs(range.end);
50
+ const s = toMs(span.start);
51
+ const e = Math.max(toMs(span.end), s);
52
+ if (e < start || s > end || end <= start) return null;
53
+ const total = end - start;
54
+ const left = (Math.max(s, start) - start) / total * 100;
55
+ const right = (Math.min(e, end) - start) / total * 100;
56
+ return { left, width: Math.max(right - left, 0), clippedStart: s < start, clippedEnd: e > end };
57
+ }
58
+ function layoutLane(items, range) {
59
+ const sorted = [...items].sort((a, b) => toMs(a.start) - toMs(b.start) || toMs(a.end) - toMs(b.end));
60
+ const rowEnds = [];
61
+ const placed = [];
62
+ for (const item of sorted) {
63
+ const pos = placeSpan(item, range);
64
+ if (!pos) continue;
65
+ const s = toMs(item.start);
66
+ let row = rowEnds.findIndex((end) => end <= s);
67
+ if (row === -1) {
68
+ row = rowEnds.length;
69
+ rowEnds.push(0);
70
+ }
71
+ rowEnds[row] = Math.max(toMs(item.end), s);
72
+ placed.push({ item, ...pos, row, conflict: false });
73
+ }
74
+ for (let i = 0; i < placed.length; i++) {
75
+ for (let j = i + 1; j < placed.length; j++) {
76
+ const a = placed[i].item;
77
+ const b = placed[j].item;
78
+ if (toMs(b.start) >= toMs(a.end)) continue;
79
+ if (toMs(a.start) < toMs(b.end)) {
80
+ placed[i].conflict = true;
81
+ placed[j].conflict = true;
82
+ }
83
+ }
84
+ }
85
+ return placed;
86
+ }
87
+ const snapToStep = (ms, step) => Math.round(ms / step) * step;
88
+ function shiftSpan(span, delta, mode, step) {
89
+ const s = toMs(span.start);
90
+ const e = toMs(span.end);
91
+ if (mode === "move") return { start: new Date(s + delta).toISOString(), end: new Date(e + delta).toISOString() };
92
+ return { start: new Date(s).toISOString(), end: new Date(Math.max(e + delta, s + step)).toISOString() };
93
+ }
94
+ function pixelsToMs(px, trackWidth, range, step) {
95
+ if (trackWidth <= 0) return 0;
96
+ return snapToStep(px / trackWidth * (toMs(range.end) - toMs(range.start)), step);
97
+ }
98
+ export {
99
+ DAY,
100
+ HOUR,
101
+ defaultTimelineStep,
102
+ layoutLane,
103
+ pixelsToMs,
104
+ placeSpan,
105
+ shiftSpan,
106
+ snapToStep,
107
+ timelineTicks
108
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tensor_1/react",
3
- "version": "2.29.0",
3
+ "version": "2.31.0",
4
4
  "description": "Thin React wrappers over the UIx v2 CSS component library.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",