@xenosystem/blocks 0.13.7 → 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,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.7",
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.0 <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.0",
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",