@xenosystem/blocks 0.13.8 → 0.13.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.
@@ -1,18 +1,3 @@
1
- import {
2
- EndIcon,
3
- LoopIcon,
4
- MetronomeIcon,
5
- PauseIcon,
6
- PlayIcon,
7
- PlayPauseIcon,
8
- RecordIcon,
9
- ShuttleLeftIcon,
10
- ShuttleRightIcon,
11
- StartIcon,
12
- StepBackIcon,
13
- StepForwardIcon,
14
- StopIcon
15
- } from "./chunk-GTN5EDY3.js";
16
1
  import {
17
2
  CancelGlyph,
18
3
  CaseGlyph,
@@ -249,6 +234,92 @@ function LockStateIcon({ locked, size }) {
249
234
  return locked ? /* @__PURE__ */ jsx5(LockIcon, { size }) : /* @__PURE__ */ jsx5(UnlockIcon, { size });
250
235
  }
251
236
 
237
+ // src/time/transport/react/icons.tsx
238
+ import Pause from "@xenosystem/elements/elements/pause";
239
+ import Play from "@xenosystem/elements/elements/play";
240
+ import Stop from "@xenosystem/elements/elements/stop";
241
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
242
+ var base3 = (size) => ({
243
+ width: size,
244
+ height: size,
245
+ viewBox: "0 0 24 24",
246
+ fill: "none",
247
+ stroke: "currentColor",
248
+ strokeWidth: 1.5,
249
+ strokeLinecap: "round",
250
+ strokeLinejoin: "round",
251
+ "aria-hidden": true
252
+ });
253
+ var PlayIcon = fromElement(Play, 12);
254
+ var PauseIcon = fromElement(Pause, 12);
255
+ var StopIcon = fromElement(Stop);
256
+ function RecordIcon({ size = 11 }) {
257
+ return /* @__PURE__ */ jsx6("svg", { ...base3(size), fill: "currentColor", stroke: "none", children: /* @__PURE__ */ jsx6("rect", { x: "6", y: "6", width: "12", height: "12", rx: "3" }) });
258
+ }
259
+ function StartIcon({ size = 11 }) {
260
+ return /* @__PURE__ */ jsxs6("svg", { ...base3(size), children: [
261
+ /* @__PURE__ */ jsx6("path", { d: "M19 20 9 12l10-8z" }),
262
+ /* @__PURE__ */ jsx6("path", { d: "M5 19V5" })
263
+ ] });
264
+ }
265
+ function EndIcon({ size = 11 }) {
266
+ return /* @__PURE__ */ jsxs6("svg", { ...base3(size), children: [
267
+ /* @__PURE__ */ jsx6("path", { d: "m5 4 10 8-10 8z" }),
268
+ /* @__PURE__ */ jsx6("path", { d: "M19 5v14" })
269
+ ] });
270
+ }
271
+ function StepBackIcon({ size = 11 }) {
272
+ return /* @__PURE__ */ jsx6("svg", { ...base3(size), children: /* @__PURE__ */ jsx6("path", { d: "M15 18 9 12l6-6" }) });
273
+ }
274
+ function StepForwardIcon({ size = 11 }) {
275
+ return /* @__PURE__ */ jsx6("svg", { ...base3(size), children: /* @__PURE__ */ jsx6("path", { d: "m9 6 6 6-6 6" }) });
276
+ }
277
+ function ShuttleLeftIcon({ size = 11 }) {
278
+ return /* @__PURE__ */ jsxs6("svg", { ...base3(size), children: [
279
+ /* @__PURE__ */ jsx6("path", { d: "M11 19 2 12l9-7z" }),
280
+ /* @__PURE__ */ jsx6("path", { d: "M22 19l-9-7 9-7z" })
281
+ ] });
282
+ }
283
+ function ShuttleRightIcon({ size = 11 }) {
284
+ return /* @__PURE__ */ jsxs6("svg", { ...base3(size), children: [
285
+ /* @__PURE__ */ jsx6("path", { d: "m13 19 9-7-9-7z" }),
286
+ /* @__PURE__ */ jsx6("path", { d: "m2 19 9-7-9-7z" })
287
+ ] });
288
+ }
289
+ function LoopIcon({ size = 11 }) {
290
+ return /* @__PURE__ */ jsxs6("svg", { ...base3(size), children: [
291
+ /* @__PURE__ */ jsx6("path", { d: "m17 2 4 4-4 4" }),
292
+ /* @__PURE__ */ jsx6("path", { d: "M3 11v-1a4 4 0 0 1 4-4h14" }),
293
+ /* @__PURE__ */ jsx6("path", { d: "m7 22-4-4 4-4" }),
294
+ /* @__PURE__ */ jsx6("path", { d: "M21 13v1a4 4 0 0 1-4 4H3" })
295
+ ] });
296
+ }
297
+ function MetronomeIcon({ size = 11 }) {
298
+ return /* @__PURE__ */ jsxs6("svg", { ...base3(size), children: [
299
+ /* @__PURE__ */ jsx6("path", { d: "M9 3h6l4 18H5z" }),
300
+ /* @__PURE__ */ jsx6("path", { d: "m12 18 4-11" })
301
+ ] });
302
+ }
303
+ function PlayPauseIcon({ playing, size }) {
304
+ return playing ? /* @__PURE__ */ jsx6(PauseIcon, { size }) : /* @__PURE__ */ jsx6(PlayIcon, { size });
305
+ }
306
+ var TRANSPORT_ICONS = {
307
+ "transport/PlayIcon": PlayIcon,
308
+ "transport/PauseIcon": PauseIcon,
309
+ "transport/PlayPauseIcon": PlayPauseIcon,
310
+ "transport/StopIcon": StopIcon,
311
+ "transport/RecordIcon": RecordIcon,
312
+ "transport/StartIcon": StartIcon,
313
+ "transport/EndIcon": EndIcon,
314
+ "transport/StepBackIcon": StepBackIcon,
315
+ "transport/StepForwardIcon": StepForwardIcon,
316
+ "transport/ShuttleLeftIcon": ShuttleLeftIcon,
317
+ "transport/ShuttleRightIcon": ShuttleRightIcon,
318
+ "transport/LoopIcon": LoopIcon,
319
+ "transport/MetronomeIcon": MetronomeIcon
320
+ };
321
+ var TRANSPORT_RUNTIME_UNITS = [];
322
+
252
323
  // src/icons/index.ts
253
324
  var ICONS = Object.freeze({
254
325
  // transport
@@ -307,6 +378,19 @@ var ICONS = Object.freeze({
307
378
  var ICON_UNITS = Object.keys(ICONS);
308
379
 
309
380
  export {
381
+ StopIcon,
382
+ RecordIcon,
383
+ StartIcon,
384
+ EndIcon,
385
+ StepBackIcon,
386
+ StepForwardIcon,
387
+ ShuttleLeftIcon,
388
+ ShuttleRightIcon,
389
+ LoopIcon,
390
+ MetronomeIcon,
391
+ PlayPauseIcon,
392
+ TRANSPORT_ICONS,
393
+ TRANSPORT_RUNTIME_UNITS,
310
394
  TreeIcon,
311
395
  EyedropperIcon,
312
396
  SwapIcon,
@@ -8,8 +8,7 @@ import {
8
8
  } from "../chunk-DJJGZ6U4.js";
9
9
  import {
10
10
  ICONS
11
- } from "../chunk-BNALWAAQ.js";
12
- import "../chunk-GTN5EDY3.js";
11
+ } from "../chunk-W4PTX2Y4.js";
13
12
  import {
14
13
  ChevronGlyph,
15
14
  DownloadGlyph,
@@ -18,8 +18,7 @@ import {
18
18
  VisibilityIcon,
19
19
  XIcon,
20
20
  XIcon2
21
- } from "../chunk-BNALWAAQ.js";
22
- import "../chunk-GTN5EDY3.js";
21
+ } from "../chunk-W4PTX2Y4.js";
23
22
  import {
24
23
  ChevronGlyph,
25
24
  CollapseGlyph,
@@ -1,8 +1,7 @@
1
1
  import {
2
2
  ICONS,
3
3
  ICON_UNITS
4
- } from "../chunk-BNALWAAQ.js";
5
- import "../chunk-GTN5EDY3.js";
4
+ } from "../chunk-W4PTX2Y4.js";
6
5
  import {
7
6
  Svg
8
7
  } from "../chunk-K7YLLV2W.js";
@@ -421,7 +421,7 @@ interface TransportPanelViewModel extends TransportViewState {
421
421
  positionLabel: string;
422
422
  }
423
423
  declare function transportPanelView(state: TransportViewState): TransportPanelViewModel;
424
- declare const BEHAVIOURS: {
424
+ declare const BEHAVIOURS$1: {
425
425
  'time/transportPanelView': (inputs: Record<string, unknown>) => TransportPanelViewModel;
426
426
  };
427
427
  declare const TRANSPORT_DECLARATION: BlockDeclaration;
@@ -2416,7 +2416,116 @@ declare function weekStart(key: string, firstDayOfWeek: number): string;
2416
2416
  declare function rowInWindow(row: XenoRow, columnId: string, column: XenoColumn | undefined, from: string, to: string): boolean;
2417
2417
 
2418
2418
  /**
2419
- * The Calendar panel view.
2419
+ * The Calendar panel AS A DECLARATION — the eleventh declared block, and the first over a GRID:
2420
+ * a period's day cells with their events, or the same events as an agenda list.
2421
+ *
2422
+ * Everything drawn is data: the toolbar (previous / next / Today, the anchor month, the partial and
2423
+ * time-zone badges, the view-mode segmented control), the three body states (not configured, error,
2424
+ * nothing scheduled), the agenda listbox (agenda / timeline modes), the grid (month / week / day —
2425
+ * `chrome/CalendarGrid` with a `WeekdayRow` when it is seven wide, one `DayCell` per cell, one
2426
+ * `EventChip` per event), the status bar. The cell that carries the roving tab stop is decided here
2427
+ * (today when in view, else the first cell) — the grid MOVES it, the view state SEEDS it.
2428
+ *
2429
+ * No runtime-bound unit: every intent is a `ui` emit. The chips' pointer affordances (select,
2430
+ * activate, context menu) are declared as emits; the cell's activation is the keyboard path.
2431
+ */
2432
+
2433
+ interface CalendarViewChip {
2434
+ id: string;
2435
+ title: string;
2436
+ time?: string;
2437
+ selected: boolean;
2438
+ tooltip: string;
2439
+ }
2440
+ interface CalendarViewCell {
2441
+ key: string;
2442
+ day: number;
2443
+ label: string;
2444
+ today: boolean;
2445
+ outside: boolean;
2446
+ tabStop: boolean;
2447
+ overflow: number;
2448
+ chips: CalendarViewChip[];
2449
+ }
2450
+ interface CalendarViewAgendaRow {
2451
+ id: string;
2452
+ title: string;
2453
+ meta: string;
2454
+ selected: boolean;
2455
+ status?: string;
2456
+ tone: 'neutral' | 'success' | 'warning' | 'error';
2457
+ }
2458
+ interface CalendarViewModel {
2459
+ anchor: string;
2460
+ partial: boolean;
2461
+ timeZone: string;
2462
+ viewMode: XenoCalendarViewMode;
2463
+ modes: {
2464
+ value: string;
2465
+ label: string;
2466
+ }[];
2467
+ configProblem?: string;
2468
+ notConfigured: boolean;
2469
+ errorMessage?: string;
2470
+ errored: boolean;
2471
+ empty: boolean;
2472
+ emptyHint: string;
2473
+ agenda: boolean;
2474
+ grid: boolean;
2475
+ columns: number;
2476
+ weekHeaded: boolean;
2477
+ weekdays: string[];
2478
+ gridLabel: string;
2479
+ cells: CalendarViewCell[];
2480
+ rows: CalendarViewAgendaRow[];
2481
+ countLabel: string;
2482
+ selectionLabel?: string;
2483
+ }
2484
+ type CalendarUiIntent = {
2485
+ kind: 'navigate';
2486
+ direction: 1 | -1;
2487
+ } | {
2488
+ kind: 'today';
2489
+ } | {
2490
+ kind: 'mode';
2491
+ mode: XenoCalendarViewMode;
2492
+ } | {
2493
+ kind: 'activateSlot';
2494
+ key: string;
2495
+ } | {
2496
+ kind: 'select';
2497
+ id: string;
2498
+ additive?: boolean;
2499
+ meta?: boolean;
2500
+ } | {
2501
+ kind: 'activateRow';
2502
+ id: string;
2503
+ } | {
2504
+ kind: 'contextMenu';
2505
+ id: string;
2506
+ x: number;
2507
+ y: number;
2508
+ };
2509
+ interface CalendarViewOptions {
2510
+ firstDayOfWeek?: number;
2511
+ emptyHint?: string;
2512
+ }
2513
+ declare function formatMinutes(minutes: number | null): string;
2514
+ /** Derive the view from the live controller — the runtime calls this on every draw. */
2515
+ declare function calendarViewState(c: CalendarController, options?: CalendarViewOptions): CalendarViewModel;
2516
+ /** Apply a `ui` intent to the controller. */
2517
+ declare function applyCalendarUi(c: CalendarController, intent: CalendarUiIntent): void;
2518
+ declare const calendarViewManifest: PanelManifest;
2519
+ declare const BEHAVIOURS: {
2520
+ 'time/calendarPanelView': (inputs: Record<string, unknown>) => CalendarViewModel;
2521
+ };
2522
+ declare const CALENDAR_RUNTIME_UNITS: readonly [];
2523
+ declare const CALENDAR_DECLARATION: BlockDeclaration;
2524
+
2525
+ /**
2526
+ * The Calendar panel view — the CODE VIEW of `CALENDAR_DECLARATION`, drawing the same
2527
+ * `CalendarViewModel` byte-identical (the equivalence suite holds the two together). No runtime-bound
2528
+ * unit; every intent goes through `applyCalendarUi`.
2420
2529
  *
2421
2530
  * Composes `@xenosystem/components/chrome`; the host must ensure `@xenosystem/workbench/primitives.css` is
2422
2531
  * present.
@@ -2425,12 +2534,10 @@ declare function rowInWindow(row: XenoRow, columnId: string, column: XenoColumn
2425
2534
  */
2426
2535
 
2427
2536
  /** Props for {@link CalendarPanelView}. */
2428
- interface CalendarPanelViewProps {
2537
+ interface CalendarPanelViewProps extends CalendarViewOptions {
2429
2538
  controller: CalendarController;
2430
- firstDayOfWeek?: number;
2431
- emptyHint?: string;
2432
2539
  }
2433
2540
  /** The Calendar panel view. */
2434
- declare function CalendarPanelView({ controller, firstDayOfWeek, emptyHint, }: CalendarPanelViewProps): ReactNode;
2541
+ declare function CalendarPanelView({ controller, firstDayOfWeek, emptyHint }: CalendarPanelViewProps): ReactNode;
2435
2542
 
2436
- export { ALL_CALENDAR_MODES, type BeginDragOptions, type BuildCellsOptions, CALENDAR_PANEL_ID, CalendarController, type CalendarControllerOptions, type CalendarHostBridge, type CalendarPanelState, CalendarPanelView, type CalendarPanelViewProps, type CalendarRenderContext, type CalendarViewState, type CreateCalendarPanelOptions, type CreateTimelinePanelOptions, type CreateTransportPanelOptions, DEFAULT_SNAP, DEFAULT_ZOOM, DRAG_THRESHOLD_PX, type DeriveOptions, EDGE_ZONE_MIN_CLIP_PX, EDGE_ZONE_PX, MIN_MAJOR_PX, MIN_MINOR_PX, TIMELINE_PANEL_ID, BEHAVIOURS as TRANSPORT_BEHAVIOURS, TRANSPORT_DECLARATION, TRANSPORT_ICONS, TRANSPORT_RUNTIME_UNITS, TRIM_SNAP_PX, TimelineController, type TimelineControllerOptions, type TimelineHostBridge, type TimelinePanelState, TimelinePanelView, type TimelinePanelViewProps, type TimelineRenderConfig, type TimelineRenderContext, type TimelineViewState, type TransportKeyEvent, TransportPanelController, type TransportPanelControllerOptions, type TransportPanelSerialized, TransportPanelView, type TransportPanelViewModel, type TransportPanelViewProps, type TransportUiIntent, type TransportViewState, type XenoArrangement, type XenoCachedTile, type XenoCalendarCell, type XenoCalendarEdit, type XenoCalendarEvent, type XenoCalendarSlotActivate, type XenoCalendarViewMode, type XenoCalendarWindow, type XenoClip, type XenoClipFade, type XenoDragKind, type XenoDragModifiers, type XenoDragPreview, type XenoDragState, type XenoHitTarget, type XenoLaneTile, type XenoLaneTileRequest, type XenoMarker, type XenoOverlaySpan, type XenoRenderTier, type XenoRowLayout, type XenoRulerTick, type XenoSnapCandidate, type XenoSnapConfig, type XenoSnapMode, type XenoSnapResult, type XenoTickWeight, XenoTileCache, type XenoTileCacheOptions, XenoTimeScale, type XenoTimeScaleGeometry, type XenoTimeScaleState, type XenoTimelineOp, type XenoTimelineSelection, type XenoTimelineTool, type XenoTimelineViewport, type XenoTrack, type XenoTrackKind, type XenoTrimMode, type XenoVisibleTrack, type XenoZoomBounds, addDays, addMonths, alignToTileGrid, applyTransportUi, beginDrag, blitTile, buildCells, buildRowLayout, calendarManifest, calendarPanel, chooseRung, clampScroll, clipDuration, clipsInMarquee, clipsOverlap, collectSnapTargets, commitDrag, computeVisible, createCalendarPanel, createTimelinePanel, createTransportPanel, dayKey, daysInMonth, dedupeByColumn, deriveEvents, edgeZone, gridStart, gridTicksFor, hasSourceWindow, isZoomGesture, isoWeekday, packOverlaps, parseDayKey, passedThreshold, previewDrag, renderTier, rowAtY, rowInWindow, rulerTicks, scrollToReveal, snapDelta, snapTick, snapWouldFight, sourceRangeFor, statusTone, ticksPerStep, tileKey, tileWidthTicks, timelineManifest, timelinePanel, todayKey, transportManifest, transportPanel, transportPanelView, transportViewManifest, transportViewState, trimModeFor, visibleClips, visibleRows, weekStart, wheelZoomFactor, withSnapModifier, zoomAboutCursor, zoomBucket, zoomToFit };
2543
+ export { ALL_CALENDAR_MODES, type BeginDragOptions, type BuildCellsOptions, BEHAVIOURS as CALENDAR_BEHAVIOURS, CALENDAR_DECLARATION, CALENDAR_PANEL_ID, CALENDAR_RUNTIME_UNITS, CalendarController, type CalendarControllerOptions, type CalendarHostBridge, type CalendarPanelState, CalendarPanelView, type CalendarPanelViewProps, type CalendarRenderContext, type CalendarUiIntent, type CalendarViewAgendaRow, type CalendarViewCell, type CalendarViewChip, type CalendarViewModel, type CalendarViewOptions, type CalendarViewState, type CreateCalendarPanelOptions, type CreateTimelinePanelOptions, type CreateTransportPanelOptions, DEFAULT_SNAP, DEFAULT_ZOOM, DRAG_THRESHOLD_PX, type DeriveOptions, EDGE_ZONE_MIN_CLIP_PX, EDGE_ZONE_PX, MIN_MAJOR_PX, MIN_MINOR_PX, TIMELINE_PANEL_ID, BEHAVIOURS$1 as TRANSPORT_BEHAVIOURS, TRANSPORT_DECLARATION, TRANSPORT_ICONS, TRANSPORT_RUNTIME_UNITS, TRIM_SNAP_PX, TimelineController, type TimelineControllerOptions, type TimelineHostBridge, type TimelinePanelState, TimelinePanelView, type TimelinePanelViewProps, type TimelineRenderConfig, type TimelineRenderContext, type TimelineViewState, type TransportKeyEvent, TransportPanelController, type TransportPanelControllerOptions, type TransportPanelSerialized, TransportPanelView, type TransportPanelViewModel, type TransportPanelViewProps, type TransportUiIntent, type TransportViewState, type XenoArrangement, type XenoCachedTile, type XenoCalendarCell, type XenoCalendarEdit, type XenoCalendarEvent, type XenoCalendarSlotActivate, type XenoCalendarViewMode, type XenoCalendarWindow, type XenoClip, type XenoClipFade, type XenoDragKind, type XenoDragModifiers, type XenoDragPreview, type XenoDragState, type XenoHitTarget, type XenoLaneTile, type XenoLaneTileRequest, type XenoMarker, type XenoOverlaySpan, type XenoRenderTier, type XenoRowLayout, type XenoRulerTick, type XenoSnapCandidate, type XenoSnapConfig, type XenoSnapMode, type XenoSnapResult, type XenoTickWeight, XenoTileCache, type XenoTileCacheOptions, XenoTimeScale, type XenoTimeScaleGeometry, type XenoTimeScaleState, type XenoTimelineOp, type XenoTimelineSelection, type XenoTimelineTool, type XenoTimelineViewport, type XenoTrack, type XenoTrackKind, type XenoTrimMode, type XenoVisibleTrack, type XenoZoomBounds, addDays, addMonths, alignToTileGrid, applyCalendarUi, applyTransportUi, beginDrag, blitTile, buildCells, buildRowLayout, calendarManifest, calendarPanel, calendarViewManifest, calendarViewState, chooseRung, clampScroll, clipDuration, clipsInMarquee, clipsOverlap, collectSnapTargets, commitDrag, computeVisible, createCalendarPanel, createTimelinePanel, createTransportPanel, dayKey, daysInMonth, dedupeByColumn, deriveEvents, edgeZone, formatMinutes, gridStart, gridTicksFor, hasSourceWindow, isZoomGesture, isoWeekday, packOverlaps, parseDayKey, passedThreshold, previewDrag, renderTier, rowAtY, rowInWindow, rulerTicks, scrollToReveal, snapDelta, snapTick, snapWouldFight, sourceRangeFor, statusTone, ticksPerStep, tileKey, tileWidthTicks, timelineManifest, timelinePanel, todayKey, transportManifest, transportPanel, transportPanelView, transportViewManifest, transportViewState, trimModeFor, visibleClips, visibleRows, weekStart, wheelZoomFactor, withSnapModifier, zoomAboutCursor, zoomBucket, zoomToFit };
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  EndIcon,
3
+ ICONS,
3
4
  LoopIcon,
4
5
  MetronomeIcon,
5
6
  PlayPauseIcon,
@@ -12,10 +13,8 @@ import {
12
13
  StopIcon,
13
14
  TRANSPORT_ICONS,
14
15
  TRANSPORT_RUNTIME_UNITS
15
- } from "../chunk-GTN5EDY3.js";
16
- import {
17
- ChevronGlyph
18
- } from "../chunk-K7YLLV2W.js";
16
+ } from "../chunk-W4PTX2Y4.js";
17
+ import "../chunk-K7YLLV2W.js";
19
18
  import {
20
19
  __reExport
21
20
  } from "../chunk-2KG3PWR4.js";
@@ -3436,10 +3435,10 @@ function gridStart(monthKey, firstDayOfWeek) {
3436
3435
  return addDays(first, -offset);
3437
3436
  }
3438
3437
  function statusTone(value) {
3439
- const text2 = String(value ?? "").toLowerCase();
3440
- if (/done|complete|published|paid|ok/.test(text2)) return "success";
3441
- if (/pending|draft|scheduled|review/.test(text2)) return "warning";
3442
- if (/fail|error|cancel|reject|overdue/.test(text2)) return "error";
3438
+ const text3 = String(value ?? "").toLowerCase();
3439
+ if (/done|complete|published|paid|ok/.test(text3)) return "success";
3440
+ if (/pending|draft|scheduled|review/.test(text3)) return "warning";
3441
+ if (/fail|error|cancel|reject|overdue/.test(text3)) return "error";
3443
3442
  return "neutral";
3444
3443
  }
3445
3444
  function columnMap(result) {
@@ -4111,199 +4110,306 @@ var calendarManifest = {
4111
4110
  import { useSyncExternalStore as useSyncExternalStore3 } from "react";
4112
4111
  import {
4113
4112
  Badge,
4113
+ CalendarGrid,
4114
+ Column as Column2,
4115
+ DayCell,
4114
4116
  EmptyState as EmptyState2,
4115
4117
  ErrorState,
4118
+ EventChip,
4116
4119
  IconButton as IconButton2,
4117
4120
  Row,
4118
4121
  RowList,
4119
4122
  ScrollArea,
4120
4123
  SegmentedControl,
4121
4124
  StatusBar as StatusBar2,
4125
+ Text,
4122
4126
  TextButton as TextButton2,
4123
4127
  Toolbar as Toolbar2,
4124
- ToolbarGroup as ToolbarGroup2
4128
+ ToolbarGroup as ToolbarGroup2,
4129
+ WeekdayRow
4125
4130
  } from "@xenosystem/components/chrome";
4126
- import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
4131
+
4132
+ // src/time/calendar/declaration.ts
4127
4133
  var WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
4128
- function CalendarPanelView({
4129
- controller,
4130
- firstDayOfWeek = 1,
4131
- emptyHint
4132
- }) {
4133
- const state = useSyncExternalStore3(controller.subscribe, controller.getState, controller.getState);
4134
- const toolbar = /* @__PURE__ */ jsx3(
4135
- Toolbar2,
4136
- {
4137
- left: /* @__PURE__ */ jsxs3(Fragment, { children: [
4138
- /* @__PURE__ */ jsx3(
4139
- IconButton2,
4140
- {
4141
- icon: /* @__PURE__ */ jsx3(ChevronGlyph, { direction: "left" }),
4142
- label: "Previous",
4143
- onClick: () => controller.navigate(-1)
4134
+ var MODES = [
4135
+ { value: "month", label: "M" },
4136
+ { value: "week", label: "W" },
4137
+ { value: "day", label: "D" },
4138
+ { value: "agenda", label: "Agenda" },
4139
+ { value: "timeline", label: "Timeline" }
4140
+ ];
4141
+ function formatMinutes(minutes) {
4142
+ if (minutes === null) return "";
4143
+ const h = Math.floor(minutes / 60);
4144
+ const m = minutes % 60;
4145
+ return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
4146
+ }
4147
+ function calendarViewState(c, options = {}) {
4148
+ const s = c.getState();
4149
+ const firstDayOfWeek = options.firstDayOfWeek ?? 1;
4150
+ const anchor = c.anchorKey().slice(0, 7);
4151
+ const body = !s.configProblem && !s.errorMessage && !s.empty;
4152
+ const agenda = body && (s.viewMode === "agenda" || s.viewMode === "timeline");
4153
+ const grid = body && !agenda;
4154
+ const columns = s.viewMode === "day" ? 1 : 7;
4155
+ const todayIndex = s.cells.findIndex((cell) => cell.today);
4156
+ const tabIndex = todayIndex >= 0 ? todayIndex : 0;
4157
+ return {
4158
+ anchor,
4159
+ partial: s.partial,
4160
+ timeZone: c.timeZone(),
4161
+ viewMode: s.viewMode,
4162
+ modes: MODES,
4163
+ configProblem: s.configProblem ?? void 0,
4164
+ notConfigured: !!s.configProblem,
4165
+ errorMessage: s.errorMessage ?? void 0,
4166
+ errored: !s.configProblem && !!s.errorMessage,
4167
+ empty: !s.configProblem && !s.errorMessage && s.empty,
4168
+ emptyHint: options.emptyHint ?? "Click a day to schedule something.",
4169
+ agenda,
4170
+ grid,
4171
+ columns,
4172
+ weekHeaded: grid && columns === 7,
4173
+ weekdays: WEEKDAYS.map((_, i) => WEEKDAYS[(firstDayOfWeek - 1 + i) % 7]),
4174
+ gridLabel: `Calendar, ${anchor}`,
4175
+ cells: grid ? s.cells.map((cell, i) => ({
4176
+ key: cell.key,
4177
+ day: cell.day,
4178
+ label: cell.key,
4179
+ today: cell.today,
4180
+ outside: !cell.inPeriod,
4181
+ tabStop: i === tabIndex,
4182
+ overflow: cell.overflow,
4183
+ chips: cell.events.map((event) => ({
4184
+ id: event.id,
4185
+ title: event.title,
4186
+ time: event.allDay ? void 0 : formatMinutes(event.startMinutes),
4187
+ selected: s.selection.includes(event.id),
4188
+ tooltip: event.multiDay ? `${event.startKey} \u2192 ${event.endKey}` : event.title
4189
+ }))
4190
+ })) : [],
4191
+ rows: agenda ? s.events.map((event) => ({
4192
+ id: event.id,
4193
+ title: event.title,
4194
+ meta: event.multiDay ? `${event.startKey} \u2192 ${event.endKey}` : event.startKey,
4195
+ selected: s.selection.includes(event.id),
4196
+ status: event.status !== void 0 ? String(event.status) : void 0,
4197
+ tone: event.status !== void 0 ? statusTone(event.status) : "neutral"
4198
+ })) : [],
4199
+ countLabel: `${s.events.length} event${s.events.length === 1 ? "" : "s"}`,
4200
+ selectionLabel: s.selection.length > 0 ? `${s.selection.length} selected` : void 0
4201
+ };
4202
+ }
4203
+ function applyCalendarUi(c, intent) {
4204
+ switch (intent.kind) {
4205
+ case "navigate":
4206
+ c.navigate(intent.direction);
4207
+ break;
4208
+ case "today":
4209
+ c.goToToday();
4210
+ break;
4211
+ case "mode":
4212
+ c.setViewMode(intent.mode);
4213
+ break;
4214
+ case "activateSlot":
4215
+ c.activateSlot(intent.key);
4216
+ break;
4217
+ case "select":
4218
+ c.select([intent.id], intent.additive === true || intent.meta === true);
4219
+ break;
4220
+ case "activateRow":
4221
+ c.activateRow(intent.id);
4222
+ break;
4223
+ case "contextMenu":
4224
+ c.requestContextMenu([intent.id], intent.x, intent.y);
4225
+ break;
4226
+ }
4227
+ }
4228
+ var calendarViewManifest = {
4229
+ id: calendarManifest.id,
4230
+ version: "1.0.0",
4231
+ title: "Calendar",
4232
+ category: "time",
4233
+ layout: { slot: "center" },
4234
+ inputs: [{ id: "view", type: "object", label: "View state", description: "The CalendarViewModel the runtime derives from the controller on every draw." }],
4235
+ outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind, \u2026 } \u2014 applied by the runtime to the controller." }],
4236
+ commands: []
4237
+ };
4238
+ var EMPTY2 = {
4239
+ anchor: "",
4240
+ partial: false,
4241
+ timeZone: "UTC",
4242
+ viewMode: "month",
4243
+ modes: MODES,
4244
+ notConfigured: false,
4245
+ errored: false,
4246
+ empty: true,
4247
+ emptyHint: "Click a day to schedule something.",
4248
+ agenda: false,
4249
+ grid: false,
4250
+ columns: 7,
4251
+ weekHeaded: false,
4252
+ weekdays: WEEKDAYS,
4253
+ gridLabel: "Calendar",
4254
+ cells: [],
4255
+ rows: [],
4256
+ countLabel: "0 events"
4257
+ };
4258
+ var BEHAVIOURS2 = {
4259
+ "time/calendarPanelView": (inputs) => inputs.view ?? EMPTY2
4260
+ };
4261
+ var CALENDAR_RUNTIME_UNITS = [];
4262
+ var text2 = (b) => ({ component: "text", props: { text: b } });
4263
+ var ui2 = (kind, fields = {}) => ({ emit: "ui", value: { object: { kind: { value: kind }, ...fields } } });
4264
+ var CALENDAR_DECLARATION = {
4265
+ format: "xeno.block@1",
4266
+ manifest: calendarViewManifest,
4267
+ behaviour: "time/calendarPanelView",
4268
+ composition: {
4269
+ component: "chrome/Column",
4270
+ children: [
4271
+ {
4272
+ component: "chrome/Toolbar",
4273
+ props: {
4274
+ left: {
4275
+ node: {
4276
+ component: "fragment",
4277
+ children: [
4278
+ { component: "chrome/IconButton", props: { icon: { node: { component: "icons/Chevron", props: { direction: { value: "left" } } } }, label: { value: "Previous" } }, on: { onClick: ui2("navigate", { direction: { value: -1 } }) } },
4279
+ { component: "chrome/IconButton", props: { icon: { node: { component: "icons/Chevron", props: { direction: { value: "right" } } } }, label: { value: "Next" } }, on: { onClick: ui2("navigate", { direction: { value: 1 } }) } },
4280
+ { component: "chrome/TextButton", on: { onClick: ui2("today") }, children: [text2({ value: "Today" })] },
4281
+ { component: "chrome/Text", props: { role: { value: "meta" } }, children: [text2({ input: "view.anchor" })] }
4282
+ ]
4283
+ }
4284
+ },
4285
+ right: {
4286
+ node: {
4287
+ component: "chrome/ToolbarGroup",
4288
+ props: { end: { value: true } },
4289
+ children: [
4290
+ { component: "chrome/Badge", when: { input: "view.partial" }, props: { tone: { value: "warning" }, title: { value: "Some measures have not finished syncing." } }, children: [text2({ value: "partial" })] },
4291
+ { component: "chrome/Badge", props: { title: { value: "Every date is bucketed in this zone." } }, children: [text2({ input: "view.timeZone" })] },
4292
+ { component: "chrome/SegmentedControl", props: { size: { value: "sm" }, label: { value: "View" }, options: { input: "view.modes" }, value: { input: "view.viewMode" } }, on: { onChange: ui2("mode", { mode: { arg: "" } }) } }
4293
+ ]
4294
+ }
4144
4295
  }
4145
- ),
4146
- /* @__PURE__ */ jsx3(
4147
- IconButton2,
4296
+ }
4297
+ },
4298
+ { component: "chrome/EmptyState", when: { input: "view.notConfigured" }, props: { title: { value: "Not configured" }, hint: { input: "view.configProblem" } } },
4299
+ { component: "chrome/ErrorState", when: { input: "view.errored" }, props: { title: { value: "Could not load events" }, message: { input: "view.errorMessage" } } },
4300
+ { component: "chrome/EmptyState", when: { input: "view.empty" }, props: { title: { value: "Nothing scheduled" }, hint: { input: "view.emptyHint" } } },
4301
+ {
4302
+ component: "chrome/ScrollArea",
4303
+ when: { input: "view.agenda" },
4304
+ children: [
4148
4305
  {
4149
- icon: /* @__PURE__ */ jsx3(ChevronGlyph, { direction: "right" }),
4150
- label: "Next",
4151
- onClick: () => controller.navigate(1)
4306
+ component: "chrome/RowList",
4307
+ props: { role: { value: "listbox" }, "aria-label": { value: "Events" } },
4308
+ children: [
4309
+ {
4310
+ component: "chrome/Row",
4311
+ each: { input: "view.rows", key: "id" },
4312
+ props: { label: { item: "title" }, meta: { item: "meta" }, selected: { item: "selected" }, trailing: { node: { component: "chrome/Badge", when: { item: "status" }, props: { tone: { item: "tone" } }, children: [text2({ item: "status" })] } } },
4313
+ on: { onClick: ui2("select", { id: { item: "id" } }), onDoubleClick: ui2("activateRow", { id: { item: "id" } }) }
4314
+ }
4315
+ ]
4152
4316
  }
4153
- ),
4154
- /* @__PURE__ */ jsx3(TextButton2, { onClick: () => controller.goToToday(), children: "Today" }),
4155
- /* @__PURE__ */ jsx3("span", { style: { fontSize: 11, opacity: 0.8 }, children: controller.anchorKey().slice(0, 7) })
4156
- ] }),
4157
- right: /* @__PURE__ */ jsxs3(ToolbarGroup2, { end: true, children: [
4158
- state.partial ? /* @__PURE__ */ jsx3(Badge, { tone: "warning", title: "Some measures have not finished syncing.", children: "partial" }) : null,
4159
- /* @__PURE__ */ jsx3(Badge, { title: "Every date is bucketed in this zone.", children: controller.timeZone() }),
4160
- /* @__PURE__ */ jsx3(
4161
- SegmentedControl,
4317
+ ]
4318
+ },
4319
+ {
4320
+ component: "chrome/ScrollArea",
4321
+ when: { input: "view.grid" },
4322
+ children: [
4162
4323
  {
4163
- size: "sm",
4164
- label: "View",
4165
- options: [
4166
- { value: "month", label: "M" },
4167
- { value: "week", label: "W" },
4168
- { value: "day", label: "D" },
4169
- { value: "agenda", label: "Agenda" },
4170
- { value: "timeline", label: "Timeline" }
4171
- ],
4172
- value: state.viewMode,
4173
- onChange: (mode) => controller.setViewMode(mode)
4324
+ component: "chrome/CalendarGrid",
4325
+ props: { columns: { input: "view.columns" }, label: { input: "view.gridLabel" } },
4326
+ children: [
4327
+ { component: "chrome/WeekdayRow", when: { input: "view.weekHeaded" }, props: { days: { input: "view.weekdays" } } },
4328
+ {
4329
+ component: "chrome/DayCell",
4330
+ each: { input: "view.cells", key: "key" },
4331
+ props: { day: { item: "day" }, label: { item: "label" }, today: { item: "today" }, outside: { item: "outside" }, tabStop: { item: "tabStop" }, overflow: { item: "overflow" } },
4332
+ on: { onActivate: ui2("activateSlot", { key: { item: "key" } }) },
4333
+ children: [
4334
+ {
4335
+ component: "chrome/EventChip",
4336
+ each: { item: "chips", key: "id" },
4337
+ props: { time: { item: "time" }, selected: { item: "selected" }, title: { item: "tooltip" } },
4338
+ on: {
4339
+ onClick: ui2("select", { id: { item: "id" }, additive: { arg: "ctrlKey", index: 0 }, meta: { arg: "metaKey", index: 0 } }),
4340
+ onDoubleClick: ui2("activateRow", { id: { item: "id" } }),
4341
+ onContextMenuAt: ui2("contextMenu", { id: { item: "id" }, x: { arg: "", index: 0 }, y: { arg: "", index: 1 } })
4342
+ },
4343
+ children: [text2({ item: "title" })]
4344
+ }
4345
+ ]
4346
+ }
4347
+ ]
4174
4348
  }
4175
- )
4176
- ] })
4177
- }
4178
- );
4179
- const body = (() => {
4180
- if (state.configProblem) {
4181
- return /* @__PURE__ */ jsx3(EmptyState2, { title: "Not configured", hint: state.configProblem });
4182
- }
4183
- if (state.errorMessage) {
4184
- return /* @__PURE__ */ jsx3(ErrorState, { title: "Could not load events", message: state.errorMessage });
4185
- }
4186
- if (state.empty) {
4187
- return /* @__PURE__ */ jsx3(
4188
- EmptyState2,
4189
- {
4190
- title: "Nothing scheduled",
4191
- hint: emptyHint ?? "Click a day to schedule something."
4192
- }
4193
- );
4194
- }
4195
- if (state.viewMode === "agenda" || state.viewMode === "timeline") {
4196
- return /* @__PURE__ */ jsx3(ScrollArea, { children: /* @__PURE__ */ jsx3(RowList, { role: "listbox", "aria-label": "Events", children: state.events.map((event) => /* @__PURE__ */ jsx3(
4197
- Row,
4198
- {
4199
- label: event.title,
4200
- meta: event.multiDay ? `${event.startKey} \u2192 ${event.endKey}` : event.startKey,
4201
- selected: state.selection.includes(event.id),
4202
- onClick: () => controller.select([event.id]),
4203
- onDoubleClick: () => controller.activateRow(event.id),
4204
- trailing: event.status !== void 0 ? /* @__PURE__ */ jsx3(Badge, { tone: statusTone(event.status), children: String(event.status) }) : null
4205
- },
4206
- event.id
4207
- )) }) });
4208
- }
4209
- const columns = state.viewMode === "day" ? 1 : 7;
4210
- return /* @__PURE__ */ jsxs3(ScrollArea, { children: [
4211
- columns === 7 ? /* @__PURE__ */ jsx3("div", { style: { display: "grid", gridTemplateColumns: "repeat(7, 1fr)" }, children: WEEKDAYS.map((_, i) => /* @__PURE__ */ jsx3(
4212
- "div",
4213
- {
4214
- style: {
4215
- fontSize: 9,
4216
- textTransform: "uppercase",
4217
- letterSpacing: "0.06em",
4218
- opacity: 0.6,
4219
- padding: "2px 4px"
4220
- },
4221
- children: WEEKDAYS[(firstDayOfWeek - 1 + i) % 7]
4222
- },
4223
- i
4224
- )) }) : null,
4225
- /* @__PURE__ */ jsx3("div", { style: { display: "grid", gridTemplateColumns: `repeat(${columns}, 1fr)`, gap: 1 }, children: state.cells.map((cell) => /* @__PURE__ */ jsxs3(
4226
- "div",
4227
- {
4228
- onClick: () => controller.activateSlot(cell.key),
4229
- style: {
4230
- minHeight: 56,
4231
- padding: 3,
4232
- cursor: "pointer",
4233
- opacity: cell.inPeriod ? 1 : 0.4,
4234
- background: cell.today ? "var(--xeno-border-subtle)" : "var(--xeno-border-subtle)",
4235
- boxShadow: cell.today ? "inset 0 0 0 1px var(--xeno-control)" : void 0
4236
- },
4237
- children: [
4238
- /* @__PURE__ */ jsx3("div", { style: { fontSize: 9, opacity: 0.7, fontVariantNumeric: "tabular-nums" }, children: cell.day }),
4239
- cell.events.map((event) => /* @__PURE__ */ jsx3(Chip, { event, controller, state }, event.id)),
4240
- cell.overflow > 0 ? /* @__PURE__ */ jsxs3("div", { style: { fontSize: 9, opacity: 0.5 }, children: [
4241
- "+",
4242
- cell.overflow,
4243
- " more"
4244
- ] }) : null
4245
- ]
4246
- },
4247
- cell.key
4248
- )) })
4249
- ] });
4250
- })();
4251
- return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, children: [
4252
- toolbar,
4253
- body,
4349
+ ]
4350
+ },
4351
+ { component: "chrome/StatusBar", props: { left: { input: "view.countLabel" }, right: { input: "view.selectionLabel" } } }
4352
+ ]
4353
+ }
4354
+ };
4355
+
4356
+ // src/time/calendar/react/CalendarPanelView.tsx
4357
+ import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
4358
+ var Chevron = ICONS["icons/Chevron"];
4359
+ function CalendarPanelView({ controller, firstDayOfWeek, emptyHint }) {
4360
+ useSyncExternalStore3(controller.subscribe, controller.getState, controller.getState);
4361
+ const view = calendarViewState(controller, { firstDayOfWeek, emptyHint });
4362
+ const ui3 = (intent) => applyCalendarUi(controller, intent);
4363
+ return /* @__PURE__ */ jsxs3(Column2, { children: [
4254
4364
  /* @__PURE__ */ jsx3(
4255
- StatusBar2,
4365
+ Toolbar2,
4256
4366
  {
4257
- left: `${state.events.length} event${state.events.length === 1 ? "" : "s"}`,
4258
- right: state.selection.length > 0 ? `${state.selection.length} selected` : void 0
4367
+ left: /* @__PURE__ */ jsxs3(Fragment, { children: [
4368
+ /* @__PURE__ */ jsx3(IconButton2, { icon: /* @__PURE__ */ jsx3(Chevron, { direction: "left" }), label: "Previous", onClick: () => ui3({ kind: "navigate", direction: -1 }) }),
4369
+ /* @__PURE__ */ jsx3(IconButton2, { icon: /* @__PURE__ */ jsx3(Chevron, { direction: "right" }), label: "Next", onClick: () => ui3({ kind: "navigate", direction: 1 }) }),
4370
+ /* @__PURE__ */ jsx3(TextButton2, { onClick: () => ui3({ kind: "today" }), children: "Today" }),
4371
+ /* @__PURE__ */ jsx3(Text, { role: "meta", children: view.anchor })
4372
+ ] }),
4373
+ right: /* @__PURE__ */ jsxs3(ToolbarGroup2, { end: true, children: [
4374
+ view.partial ? /* @__PURE__ */ jsx3(Badge, { tone: "warning", title: "Some measures have not finished syncing.", children: "partial" }) : null,
4375
+ /* @__PURE__ */ jsx3(Badge, { title: "Every date is bucketed in this zone.", children: view.timeZone }),
4376
+ /* @__PURE__ */ jsx3(SegmentedControl, { size: "sm", label: "View", options: view.modes, value: view.viewMode, onChange: (mode) => ui3({ kind: "mode", mode }) })
4377
+ ] })
4259
4378
  }
4260
- )
4261
- ] });
4262
- }
4263
- function Chip({
4264
- event,
4265
- controller,
4266
- state
4267
- }) {
4268
- const selected = state.selection.includes(event.id);
4269
- return /* @__PURE__ */ jsxs3(
4270
- "div",
4271
- {
4272
- onClick: (e) => {
4273
- e.stopPropagation();
4274
- controller.select([event.id], e.ctrlKey || e.metaKey);
4275
- },
4276
- onDoubleClick: (e) => {
4277
- e.stopPropagation();
4278
- controller.activateRow(event.id);
4279
- },
4280
- onContextMenu: (e) => {
4281
- e.preventDefault();
4282
- e.stopPropagation();
4283
- controller.requestContextMenu([event.id], e.clientX, e.clientY);
4284
- },
4285
- title: event.multiDay ? `${event.startKey} \u2192 ${event.endKey}` : event.title,
4286
- style: {
4287
- fontSize: 9,
4288
- padding: "1px 3px",
4289
- marginTop: 1,
4290
- borderRadius: 2,
4291
- background: selected ? "var(--xeno-control)" : "var(--xeno-border-subtle)",
4292
- overflow: "hidden",
4293
- textOverflow: "ellipsis",
4294
- whiteSpace: "nowrap",
4295
- cursor: "pointer"
4379
+ ),
4380
+ view.notConfigured ? /* @__PURE__ */ jsx3(EmptyState2, { title: "Not configured", hint: view.configProblem }) : null,
4381
+ view.errored ? /* @__PURE__ */ jsx3(ErrorState, { title: "Could not load events", message: view.errorMessage }) : null,
4382
+ view.empty ? /* @__PURE__ */ jsx3(EmptyState2, { title: "Nothing scheduled", hint: view.emptyHint }) : null,
4383
+ view.agenda ? /* @__PURE__ */ jsx3(ScrollArea, { children: /* @__PURE__ */ jsx3(RowList, { role: "listbox", "aria-label": "Events", children: view.rows.map((row) => /* @__PURE__ */ jsx3(
4384
+ Row,
4385
+ {
4386
+ label: row.title,
4387
+ meta: row.meta,
4388
+ selected: row.selected,
4389
+ trailing: row.status ? /* @__PURE__ */ jsx3(Badge, { tone: row.tone, children: row.status }) : null,
4390
+ onClick: () => ui3({ kind: "select", id: row.id }),
4391
+ onDoubleClick: () => ui3({ kind: "activateRow", id: row.id })
4296
4392
  },
4297
- children: [
4298
- event.allDay ? null : /* @__PURE__ */ jsx3("span", { style: { opacity: 0.6, marginRight: 3, fontVariantNumeric: "tabular-nums" }, children: formatMinutes(event.startMinutes) }),
4299
- event.title
4300
- ]
4301
- }
4302
- );
4303
- }
4304
- function formatMinutes(minutes) {
4305
- if (minutes === null) return "";
4306
- return `${String(Math.floor(minutes / 60)).padStart(2, "0")}:${String(minutes % 60).padStart(2, "0")}`;
4393
+ row.id
4394
+ )) }) }) : null,
4395
+ view.grid ? /* @__PURE__ */ jsx3(ScrollArea, { children: /* @__PURE__ */ jsxs3(CalendarGrid, { columns: view.columns, label: view.gridLabel, children: [
4396
+ view.weekHeaded ? /* @__PURE__ */ jsx3(WeekdayRow, { days: view.weekdays }) : null,
4397
+ view.cells.map((cell) => /* @__PURE__ */ jsx3(DayCell, { day: cell.day, label: cell.label, today: cell.today, outside: cell.outside, tabStop: cell.tabStop, overflow: cell.overflow, onActivate: () => ui3({ kind: "activateSlot", key: cell.key }), children: cell.chips.map((chip) => /* @__PURE__ */ jsx3(
4398
+ EventChip,
4399
+ {
4400
+ time: chip.time,
4401
+ selected: chip.selected,
4402
+ title: chip.tooltip,
4403
+ onClick: (e) => ui3({ kind: "select", id: chip.id, additive: e.ctrlKey, meta: e.metaKey }),
4404
+ onDoubleClick: () => ui3({ kind: "activateRow", id: chip.id }),
4405
+ onContextMenuAt: (x, y) => ui3({ kind: "contextMenu", id: chip.id, x, y }),
4406
+ children: chip.title
4407
+ },
4408
+ chip.id
4409
+ )) }, cell.key))
4410
+ ] }) }) : null,
4411
+ /* @__PURE__ */ jsx3(StatusBar2, { left: view.countLabel, right: view.selectionLabel })
4412
+ ] });
4307
4413
  }
4308
4414
 
4309
4415
  // src/time/calendar/panel.ts
@@ -4465,7 +4571,10 @@ var export_wrapIntoLoop = clock_exports.wrapIntoLoop;
4465
4571
  export {
4466
4572
  ALL_CALENDAR_MODES,
4467
4573
  export_BAR_SUBDIVISION as BAR_SUBDIVISION,
4574
+ BEHAVIOURS2 as CALENDAR_BEHAVIOURS,
4575
+ CALENDAR_DECLARATION,
4468
4576
  CALENDAR_PANEL_ID,
4577
+ CALENDAR_RUNTIME_UNITS,
4469
4578
  CalendarController,
4470
4579
  CalendarPanelView,
4471
4580
  DEFAULT_SNAP,
@@ -4493,6 +4602,7 @@ export {
4493
4602
  addDays,
4494
4603
  addMonths,
4495
4604
  alignToTileGrid,
4605
+ applyCalendarUi,
4496
4606
  applyTransportUi,
4497
4607
  beginDrag,
4498
4608
  blitTile,
@@ -4500,6 +4610,8 @@ export {
4500
4610
  buildRowLayout,
4501
4611
  calendarManifest,
4502
4612
  calendarPanel,
4613
+ calendarViewManifest,
4614
+ calendarViewState,
4503
4615
  chooseRung,
4504
4616
  clampScroll,
4505
4617
  export_clampTick as clampTick,
@@ -4524,6 +4636,7 @@ export {
4524
4636
  export_extrapolateTick as extrapolateTick,
4525
4637
  export_formatBars as formatBars,
4526
4638
  export_formatFrames as formatFrames,
4639
+ formatMinutes,
4527
4640
  export_formatSeconds as formatSeconds,
4528
4641
  export_formatTick as formatTick,
4529
4642
  export_formatTimecode as formatTimecode,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenosystem/blocks",
3
- "version": "0.13.8",
3
+ "version": "0.13.9",
4
4
  "description": "XENO Blocks — rung 3 of the front ladder: components composed into a contract-bearing unit (manifest: ports, intents, commands, agent surface), rendered by @xenosystem/workbench. ONE package, one subpath per family (/auth, /edit, /data, /time, /ops, /trust, /agent), one named export per block — XENO PACKAGE NAMING - STANDARD.md.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -64,7 +64,7 @@
64
64
  "peerDependencies": {
65
65
  "@duckdb/duckdb-wasm": ">=1.28.0",
66
66
  "@xenosystem/block-sdk": ">=0.3.4 <1",
67
- "@xenosystem/components": ">=0.19.1 <1",
67
+ "@xenosystem/components": ">=0.20.0 <1",
68
68
  "@xenosystem/data-core": "^0.1.0",
69
69
  "@xenosystem/elements": ">=0.0.1",
70
70
  "@xenosystem/elements-react": ">=0.0.1",
@@ -81,7 +81,7 @@
81
81
  "@types/react": "^19.0.0",
82
82
  "@types/react-dom": "^19.0.0",
83
83
  "@xenosystem/block-sdk": "^0.3.4",
84
- "@xenosystem/components": "^0.19.1",
84
+ "@xenosystem/components": "^0.20.0",
85
85
  "@xenosystem/data-core": "^0.1.0",
86
86
  "@xenosystem/elements": "0.0.1",
87
87
  "@xenosystem/elements-react": "0.0.1",
@@ -1,107 +0,0 @@
1
- import {
2
- fromElement
3
- } from "./chunk-K7YLLV2W.js";
4
-
5
- // src/time/transport/react/icons.tsx
6
- import Pause from "@xenosystem/elements/elements/pause";
7
- import Play from "@xenosystem/elements/elements/play";
8
- import Stop from "@xenosystem/elements/elements/stop";
9
- import { jsx, jsxs } from "react/jsx-runtime";
10
- var base = (size) => ({
11
- width: size,
12
- height: size,
13
- viewBox: "0 0 24 24",
14
- fill: "none",
15
- stroke: "currentColor",
16
- strokeWidth: 1.5,
17
- strokeLinecap: "round",
18
- strokeLinejoin: "round",
19
- "aria-hidden": true
20
- });
21
- var PlayIcon = fromElement(Play, 12);
22
- var PauseIcon = fromElement(Pause, 12);
23
- var StopIcon = fromElement(Stop);
24
- function RecordIcon({ size = 11 }) {
25
- return /* @__PURE__ */ jsx("svg", { ...base(size), fill: "currentColor", stroke: "none", children: /* @__PURE__ */ jsx("rect", { x: "6", y: "6", width: "12", height: "12", rx: "3" }) });
26
- }
27
- function StartIcon({ size = 11 }) {
28
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
29
- /* @__PURE__ */ jsx("path", { d: "M19 20 9 12l10-8z" }),
30
- /* @__PURE__ */ jsx("path", { d: "M5 19V5" })
31
- ] });
32
- }
33
- function EndIcon({ size = 11 }) {
34
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
35
- /* @__PURE__ */ jsx("path", { d: "m5 4 10 8-10 8z" }),
36
- /* @__PURE__ */ jsx("path", { d: "M19 5v14" })
37
- ] });
38
- }
39
- function StepBackIcon({ size = 11 }) {
40
- return /* @__PURE__ */ jsx("svg", { ...base(size), children: /* @__PURE__ */ jsx("path", { d: "M15 18 9 12l6-6" }) });
41
- }
42
- function StepForwardIcon({ size = 11 }) {
43
- return /* @__PURE__ */ jsx("svg", { ...base(size), children: /* @__PURE__ */ jsx("path", { d: "m9 6 6 6-6 6" }) });
44
- }
45
- function ShuttleLeftIcon({ size = 11 }) {
46
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
47
- /* @__PURE__ */ jsx("path", { d: "M11 19 2 12l9-7z" }),
48
- /* @__PURE__ */ jsx("path", { d: "M22 19l-9-7 9-7z" })
49
- ] });
50
- }
51
- function ShuttleRightIcon({ size = 11 }) {
52
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
53
- /* @__PURE__ */ jsx("path", { d: "m13 19 9-7-9-7z" }),
54
- /* @__PURE__ */ jsx("path", { d: "m2 19 9-7-9-7z" })
55
- ] });
56
- }
57
- function LoopIcon({ size = 11 }) {
58
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
59
- /* @__PURE__ */ jsx("path", { d: "m17 2 4 4-4 4" }),
60
- /* @__PURE__ */ jsx("path", { d: "M3 11v-1a4 4 0 0 1 4-4h14" }),
61
- /* @__PURE__ */ jsx("path", { d: "m7 22-4-4 4-4" }),
62
- /* @__PURE__ */ jsx("path", { d: "M21 13v1a4 4 0 0 1-4 4H3" })
63
- ] });
64
- }
65
- function MetronomeIcon({ size = 11 }) {
66
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
67
- /* @__PURE__ */ jsx("path", { d: "M9 3h6l4 18H5z" }),
68
- /* @__PURE__ */ jsx("path", { d: "m12 18 4-11" })
69
- ] });
70
- }
71
- function PlayPauseIcon({ playing, size }) {
72
- return playing ? /* @__PURE__ */ jsx(PauseIcon, { size }) : /* @__PURE__ */ jsx(PlayIcon, { size });
73
- }
74
- var TRANSPORT_ICONS = {
75
- "transport/PlayIcon": PlayIcon,
76
- "transport/PauseIcon": PauseIcon,
77
- "transport/PlayPauseIcon": PlayPauseIcon,
78
- "transport/StopIcon": StopIcon,
79
- "transport/RecordIcon": RecordIcon,
80
- "transport/StartIcon": StartIcon,
81
- "transport/EndIcon": EndIcon,
82
- "transport/StepBackIcon": StepBackIcon,
83
- "transport/StepForwardIcon": StepForwardIcon,
84
- "transport/ShuttleLeftIcon": ShuttleLeftIcon,
85
- "transport/ShuttleRightIcon": ShuttleRightIcon,
86
- "transport/LoopIcon": LoopIcon,
87
- "transport/MetronomeIcon": MetronomeIcon
88
- };
89
- var TRANSPORT_RUNTIME_UNITS = [];
90
-
91
- export {
92
- PlayIcon,
93
- PauseIcon,
94
- StopIcon,
95
- RecordIcon,
96
- StartIcon,
97
- EndIcon,
98
- StepBackIcon,
99
- StepForwardIcon,
100
- ShuttleLeftIcon,
101
- ShuttleRightIcon,
102
- LoopIcon,
103
- MetronomeIcon,
104
- PlayPauseIcon,
105
- TRANSPORT_ICONS,
106
- TRANSPORT_RUNTIME_UNITS
107
- };