@xenosystem/blocks 0.12.8 → 0.13.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.
@@ -1,3 +1,18 @@
1
+ import {
2
+ EndIcon,
3
+ LoopIcon,
4
+ MetronomeIcon,
5
+ PlayPauseIcon,
6
+ RecordIcon,
7
+ ShuttleLeftIcon,
8
+ ShuttleRightIcon,
9
+ StartIcon,
10
+ StepBackIcon,
11
+ StepForwardIcon,
12
+ StopIcon,
13
+ TRANSPORT_ICONS,
14
+ TRANSPORT_RUNTIME_UNITS
15
+ } from "../chunk-BP4EYOCQ.js";
1
16
  import {
2
17
  __reExport
3
18
  } from "../chunk-2KG3PWR4.js";
@@ -908,7 +923,7 @@ var text = (b) => ({ component: "text", props: { text: b } });
908
923
  var button = (icon, label, kind, extra = {}) => ({
909
924
  component: "chrome/IconButton",
910
925
  ...extra.when ? { when: extra.when } : {},
911
- props: { size: { value: "sm" }, icon: { node: { component: `transport/${icon}` } }, label, ...extra.props ?? {} },
926
+ props: { size: { value: "sm" }, icon: { node: { component: `icons/${icon}` } }, label, ...extra.props ?? {} },
912
927
  on: { onClick: ui(kind) }
913
928
  });
914
929
  var TRANSPORT_DECLARATION = {
@@ -923,27 +938,27 @@ var TRANSPORT_DECLARATION = {
923
938
  component: "chrome/Stack",
924
939
  props: { direction: { value: "row" }, gap: { value: 3 }, pad: { value: "gutter" } },
925
940
  children: [
926
- button("StartIcon", { value: "Go to start" }, "goToStart"),
927
- button("StepBackIcon", { value: "Step back" }, "stepBack"),
928
- button("ShuttleLeftIcon", { value: "Shuttle reverse (J)" }, "shuttleBack", { when: { input: "view.show.shuttle" } }),
941
+ button("Start", { value: "Go to start" }, "goToStart"),
942
+ button("StepBack", { value: "Step back" }, "stepBack"),
943
+ button("ShuttleLeft", { value: "Shuttle reverse (J)" }, "shuttleBack", { when: { input: "view.show.shuttle" } }),
929
944
  {
930
945
  component: "chrome/IconButton",
931
946
  props: {
932
947
  size: { value: "sm" },
933
948
  variant: { value: "primary" },
934
- icon: { node: { component: "transport/PlayPauseIcon", props: { playing: { input: "view.playing" } } } },
949
+ icon: { node: { component: "icons/PlayPause", props: { playing: { input: "view.playing" } } } },
935
950
  label: { input: "view.playLabel" },
936
951
  active: { input: "view.playing" }
937
952
  },
938
953
  on: { onClick: ui("togglePlay") }
939
954
  },
940
- button("StopIcon", { value: "Stop" }, "stop"),
941
- button("ShuttleRightIcon", { value: "Shuttle forward (L)" }, "shuttleForward", { when: { input: "view.show.shuttle" } }),
942
- button("StepForwardIcon", { value: "Step forward" }, "stepForward"),
943
- button("EndIcon", { value: "Go to end" }, "goToEnd"),
944
- button("RecordIcon", { value: "Record" }, "record", { when: { input: "view.show.record" }, props: { variant: { value: "danger" }, active: { input: "view.recording" } } }),
945
- button("LoopIcon", { value: "Loop" }, "toggleLoop", { when: { input: "view.show.loop" }, props: { active: { input: "view.loopEnabled" } } }),
946
- button("MetronomeIcon", { value: "Metronome" }, "toggleMetronome", { when: { input: "view.show.metronome" }, props: { active: { input: "view.metronome" } } }),
955
+ button("Stop", { value: "Stop" }, "stop"),
956
+ button("ShuttleRight", { value: "Shuttle forward (L)" }, "shuttleForward", { when: { input: "view.show.shuttle" } }),
957
+ button("StepForward", { value: "Step forward" }, "stepForward"),
958
+ button("End", { value: "Go to end" }, "goToEnd"),
959
+ button("Record", { value: "Record" }, "record", { when: { input: "view.show.record" }, props: { variant: { value: "danger" }, active: { input: "view.recording" } } }),
960
+ button("Loop", { value: "Loop" }, "toggleLoop", { when: { input: "view.show.loop" }, props: { active: { input: "view.loopEnabled" } } }),
961
+ button("Metronome", { value: "Metronome" }, "toggleMetronome", { when: { input: "view.show.metronome" }, props: { active: { input: "view.metronome" } } }),
947
962
  { component: "chrome/TextButton", when: { input: "view.show.punch" }, props: { strong: { input: "view.punch" } }, children: [text({ value: "PUNCH" })] },
948
963
  {
949
964
  component: "chrome/Readout",
@@ -985,100 +1000,8 @@ var TRANSPORT_DECLARATION = {
985
1000
  }
986
1001
  };
987
1002
 
988
- // src/time/transport/react/icons.tsx
989
- import { jsx, jsxs } from "react/jsx-runtime";
990
- var base = (size) => ({
991
- width: size,
992
- height: size,
993
- viewBox: "0 0 24 24",
994
- fill: "none",
995
- stroke: "currentColor",
996
- strokeWidth: 1.5,
997
- strokeLinecap: "round",
998
- strokeLinejoin: "round",
999
- "aria-hidden": true
1000
- });
1001
- function PlayIcon({ size = 12 }) {
1002
- return /* @__PURE__ */ jsx("svg", { ...base(size), fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M7 4.5v15l13-7.5z" }) });
1003
- }
1004
- function PauseIcon({ size = 12 }) {
1005
- return /* @__PURE__ */ jsxs("svg", { ...base(size), fill: "currentColor", stroke: "none", children: [
1006
- /* @__PURE__ */ jsx("rect", { x: "6", y: "4", width: "4", height: "16", rx: "1" }),
1007
- /* @__PURE__ */ jsx("rect", { x: "14", y: "4", width: "4", height: "16", rx: "1" })
1008
- ] });
1009
- }
1010
- function StopIcon({ size = 11 }) {
1011
- return /* @__PURE__ */ jsx("svg", { ...base(size), fill: "currentColor", stroke: "none", children: /* @__PURE__ */ jsx("rect", { x: "5", y: "5", width: "14", height: "14", rx: "2" }) });
1012
- }
1013
- function RecordIcon({ size = 11 }) {
1014
- return /* @__PURE__ */ jsx("svg", { ...base(size), fill: "currentColor", stroke: "none", children: /* @__PURE__ */ jsx("rect", { x: "6", y: "6", width: "12", height: "12", rx: "3" }) });
1015
- }
1016
- function StartIcon({ size = 11 }) {
1017
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
1018
- /* @__PURE__ */ jsx("path", { d: "M19 20 9 12l10-8z" }),
1019
- /* @__PURE__ */ jsx("path", { d: "M5 19V5" })
1020
- ] });
1021
- }
1022
- function EndIcon({ size = 11 }) {
1023
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
1024
- /* @__PURE__ */ jsx("path", { d: "m5 4 10 8-10 8z" }),
1025
- /* @__PURE__ */ jsx("path", { d: "M19 5v14" })
1026
- ] });
1027
- }
1028
- function StepBackIcon({ size = 11 }) {
1029
- return /* @__PURE__ */ jsx("svg", { ...base(size), children: /* @__PURE__ */ jsx("path", { d: "M15 18 9 12l6-6" }) });
1030
- }
1031
- function StepForwardIcon({ size = 11 }) {
1032
- return /* @__PURE__ */ jsx("svg", { ...base(size), children: /* @__PURE__ */ jsx("path", { d: "m9 6 6 6-6 6" }) });
1033
- }
1034
- function ShuttleLeftIcon({ size = 11 }) {
1035
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
1036
- /* @__PURE__ */ jsx("path", { d: "M11 19 2 12l9-7z" }),
1037
- /* @__PURE__ */ jsx("path", { d: "M22 19l-9-7 9-7z" })
1038
- ] });
1039
- }
1040
- function ShuttleRightIcon({ size = 11 }) {
1041
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
1042
- /* @__PURE__ */ jsx("path", { d: "m13 19 9-7-9-7z" }),
1043
- /* @__PURE__ */ jsx("path", { d: "m2 19 9-7-9-7z" })
1044
- ] });
1045
- }
1046
- function LoopIcon({ size = 11 }) {
1047
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
1048
- /* @__PURE__ */ jsx("path", { d: "m17 2 4 4-4 4" }),
1049
- /* @__PURE__ */ jsx("path", { d: "M3 11v-1a4 4 0 0 1 4-4h14" }),
1050
- /* @__PURE__ */ jsx("path", { d: "m7 22-4-4 4-4" }),
1051
- /* @__PURE__ */ jsx("path", { d: "M21 13v1a4 4 0 0 1-4 4H3" })
1052
- ] });
1053
- }
1054
- function MetronomeIcon({ size = 11 }) {
1055
- return /* @__PURE__ */ jsxs("svg", { ...base(size), children: [
1056
- /* @__PURE__ */ jsx("path", { d: "M9 3h6l4 18H5z" }),
1057
- /* @__PURE__ */ jsx("path", { d: "m12 18 4-11" })
1058
- ] });
1059
- }
1060
- function PlayPauseIcon({ playing, size }) {
1061
- return playing ? /* @__PURE__ */ jsx(PauseIcon, { size }) : /* @__PURE__ */ jsx(PlayIcon, { size });
1062
- }
1063
- var TRANSPORT_ICONS = {
1064
- "transport/PlayIcon": PlayIcon,
1065
- "transport/PauseIcon": PauseIcon,
1066
- "transport/PlayPauseIcon": PlayPauseIcon,
1067
- "transport/StopIcon": StopIcon,
1068
- "transport/RecordIcon": RecordIcon,
1069
- "transport/StartIcon": StartIcon,
1070
- "transport/EndIcon": EndIcon,
1071
- "transport/StepBackIcon": StepBackIcon,
1072
- "transport/StepForwardIcon": StepForwardIcon,
1073
- "transport/ShuttleLeftIcon": ShuttleLeftIcon,
1074
- "transport/ShuttleRightIcon": ShuttleRightIcon,
1075
- "transport/LoopIcon": LoopIcon,
1076
- "transport/MetronomeIcon": MetronomeIcon
1077
- };
1078
- var TRANSPORT_RUNTIME_UNITS = Object.keys(TRANSPORT_ICONS);
1079
-
1080
1003
  // src/time/transport/react/TransportPanelView.tsx
1081
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1004
+ import { jsx, jsxs } from "react/jsx-runtime";
1082
1005
  function TransportPanelView({ controller }) {
1083
1006
  const subscribe = useCallback((cb) => controller.subscribe(cb), [controller]);
1084
1007
  const getSnapshot = useCallback(() => controller.getRevision(), [controller]);
@@ -1118,7 +1041,7 @@ function TransportPanelView({ controller }) {
1118
1041
  },
1119
1042
  [controller]
1120
1043
  );
1121
- return /* @__PURE__ */ jsxs2(
1044
+ return /* @__PURE__ */ jsxs(
1122
1045
  Column,
1123
1046
  {
1124
1047
  className: "xeno-transport-panel",
@@ -1128,28 +1051,28 @@ function TransportPanelView({ controller }) {
1128
1051
  role: "group",
1129
1052
  "aria-label": "Transport",
1130
1053
  children: [
1131
- /* @__PURE__ */ jsxs2(Stack, { direction: "row", gap: 3, pad: "gutter", children: [
1132
- /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(StartIcon, {}), label: "Go to start", onClick: () => controller.goToStart() }),
1133
- /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(StepBackIcon, {}), label: "Step back", onClick: () => controller.step(-1) }),
1134
- view.show.shuttle && /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(ShuttleLeftIcon, {}), label: "Shuttle reverse (J)", onClick: () => controller.shuttleStep(-1) }),
1135
- /* @__PURE__ */ jsx2(IconButton, { size: "sm", variant: "primary", icon: /* @__PURE__ */ jsx2(PlayPauseIcon, { playing: view.playing }), label: view.playLabel, active: view.playing, onClick: () => controller.togglePlay() }),
1136
- /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(StopIcon, {}), label: "Stop", onClick: () => controller.stop() }),
1137
- view.show.shuttle && /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(ShuttleRightIcon, {}), label: "Shuttle forward (L)", onClick: () => controller.shuttleStep(1) }),
1138
- /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(StepForwardIcon, {}), label: "Step forward", onClick: () => controller.step(1) }),
1139
- /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(EndIcon, {}), label: "Go to end", onClick: () => controller.goToEnd() }),
1140
- view.show.record && /* @__PURE__ */ jsx2(IconButton, { size: "sm", variant: "danger", icon: /* @__PURE__ */ jsx2(RecordIcon, {}), label: "Record", active: view.recording, onClick: () => controller.record() }),
1141
- view.show.loop && /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(LoopIcon, {}), label: "Loop", active: view.loopEnabled, onClick: () => controller.toggleLoop() }),
1142
- view.show.metronome && /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(MetronomeIcon, {}), label: "Metronome", active: view.metronome, onClick: () => controller.toggleMetronome() }),
1143
- view.show.punch && /* @__PURE__ */ jsx2(TextButton, { strong: view.punch, children: "PUNCH" }),
1144
- /* @__PURE__ */ jsx2(Readout, { value: view.readout, unit: view.displayLabel, label: view.positionLabel, title: "Click to change time display", onClick: () => controller.cycleDisplay() }),
1145
- /* @__PURE__ */ jsx2(Readout, { size: "sm", value: view.durationReadout }),
1146
- view.show.bpm && /* @__PURE__ */ jsx2(NumberInput, { caption: "BPM", label: "Tempo", value: view.bpm, onChange: (bpm) => controller.setTempo(bpm) }),
1147
- view.show.inOut && /* @__PURE__ */ jsxs2(Stack, { direction: "row", gap: 2, pad: "none", children: [
1148
- /* @__PURE__ */ jsx2(TextButton, { onClick: () => controller.setInPoint(), children: "IN" }),
1149
- /* @__PURE__ */ jsx2(TextButton, { onClick: () => controller.setOutPoint(), children: "OUT" })
1054
+ /* @__PURE__ */ jsxs(Stack, { direction: "row", gap: 3, pad: "gutter", children: [
1055
+ /* @__PURE__ */ jsx(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx(StartIcon, {}), label: "Go to start", onClick: () => controller.goToStart() }),
1056
+ /* @__PURE__ */ jsx(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx(StepBackIcon, {}), label: "Step back", onClick: () => controller.step(-1) }),
1057
+ view.show.shuttle && /* @__PURE__ */ jsx(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx(ShuttleLeftIcon, {}), label: "Shuttle reverse (J)", onClick: () => controller.shuttleStep(-1) }),
1058
+ /* @__PURE__ */ jsx(IconButton, { size: "sm", variant: "primary", icon: /* @__PURE__ */ jsx(PlayPauseIcon, { playing: view.playing }), label: view.playLabel, active: view.playing, onClick: () => controller.togglePlay() }),
1059
+ /* @__PURE__ */ jsx(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx(StopIcon, {}), label: "Stop", onClick: () => controller.stop() }),
1060
+ view.show.shuttle && /* @__PURE__ */ jsx(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx(ShuttleRightIcon, {}), label: "Shuttle forward (L)", onClick: () => controller.shuttleStep(1) }),
1061
+ /* @__PURE__ */ jsx(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx(StepForwardIcon, {}), label: "Step forward", onClick: () => controller.step(1) }),
1062
+ /* @__PURE__ */ jsx(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx(EndIcon, {}), label: "Go to end", onClick: () => controller.goToEnd() }),
1063
+ view.show.record && /* @__PURE__ */ jsx(IconButton, { size: "sm", variant: "danger", icon: /* @__PURE__ */ jsx(RecordIcon, {}), label: "Record", active: view.recording, onClick: () => controller.record() }),
1064
+ view.show.loop && /* @__PURE__ */ jsx(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx(LoopIcon, {}), label: "Loop", active: view.loopEnabled, onClick: () => controller.toggleLoop() }),
1065
+ view.show.metronome && /* @__PURE__ */ jsx(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx(MetronomeIcon, {}), label: "Metronome", active: view.metronome, onClick: () => controller.toggleMetronome() }),
1066
+ view.show.punch && /* @__PURE__ */ jsx(TextButton, { strong: view.punch, children: "PUNCH" }),
1067
+ /* @__PURE__ */ jsx(Readout, { value: view.readout, unit: view.displayLabel, label: view.positionLabel, title: "Click to change time display", onClick: () => controller.cycleDisplay() }),
1068
+ /* @__PURE__ */ jsx(Readout, { size: "sm", value: view.durationReadout }),
1069
+ view.show.bpm && /* @__PURE__ */ jsx(NumberInput, { caption: "BPM", label: "Tempo", value: view.bpm, onChange: (bpm) => controller.setTempo(bpm) }),
1070
+ view.show.inOut && /* @__PURE__ */ jsxs(Stack, { direction: "row", gap: 2, pad: "none", children: [
1071
+ /* @__PURE__ */ jsx(TextButton, { onClick: () => controller.setInPoint(), children: "IN" }),
1072
+ /* @__PURE__ */ jsx(TextButton, { onClick: () => controller.setOutPoint(), children: "OUT" })
1150
1073
  ] })
1151
1074
  ] }),
1152
- view.show.scrubber && /* @__PURE__ */ jsx2(Slider, { progress: view.progress, label: "Playhead", valueMin: 0, valueMax: view.duration, valueNow: view.currentTick, valueText: view.readout, onScrub: scrub })
1075
+ view.show.scrubber && /* @__PURE__ */ jsx(Slider, { progress: view.progress, label: "Playhead", valueMin: 0, valueMax: view.duration, valueNow: view.currentTick, valueText: view.readout, onScrub: scrub })
1153
1076
  ]
1154
1077
  }
1155
1078
  );
@@ -1705,7 +1628,7 @@ function beginDrag(options) {
1705
1628
  for (const clip of options.clips) {
1706
1629
  origin[clip.id] = { startTick: clip.startTick, endTick: clip.endTick, trackId: clip.trackId };
1707
1630
  }
1708
- const base2 = {
1631
+ const base = {
1709
1632
  tool,
1710
1633
  startX: options.x,
1711
1634
  startY: options.y,
@@ -1718,24 +1641,24 @@ function beginDrag(options) {
1718
1641
  deltaTicks: 0,
1719
1642
  deltaTracks: 0
1720
1643
  };
1721
- if (tool === "hand") return { ...base2, kind: "pan" };
1644
+ if (tool === "hand") return { ...base, kind: "pan" };
1722
1645
  if (tool === "razor") return null;
1723
1646
  switch (target.kind) {
1724
1647
  case "ruler":
1725
- return { ...base2, kind: "scrub" };
1648
+ return { ...base, kind: "scrub" };
1726
1649
  case "marker":
1727
- return { ...base2, kind: "marker", markerId: target.markerId };
1650
+ return { ...base, kind: "marker", markerId: target.markerId };
1728
1651
  case "trackDivider":
1729
- return { ...base2, kind: "trackHeight", trackId: target.trackId, startHeightPx: options.startHeightPx };
1652
+ return { ...base, kind: "trackHeight", trackId: target.trackId, startHeightPx: options.startHeightPx };
1730
1653
  case "clipEdgeStart":
1731
- return { ...base2, kind: "trimStart", edgeTick: options.tick };
1654
+ return { ...base, kind: "trimStart", edgeTick: options.tick };
1732
1655
  case "clipEdgeEnd":
1733
- return { ...base2, kind: "trimEnd", edgeTick: options.tick };
1656
+ return { ...base, kind: "trimEnd", edgeTick: options.tick };
1734
1657
  case "clip":
1735
- return { ...base2, kind: "move" };
1658
+ return { ...base, kind: "move" };
1736
1659
  case "lane":
1737
1660
  return {
1738
- ...base2,
1661
+ ...base,
1739
1662
  kind: "marquee",
1740
1663
  clipIds: [],
1741
1664
  marquee: { fromTick: options.tick, toTick: options.tick, fromY: options.y, toY: options.y }
@@ -2930,7 +2853,7 @@ var timelineManifest = {
2930
2853
  import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useSyncExternalStore as useSyncExternalStore2 } from "react";
2931
2854
  import { EmptyState, StatusBar, Toolbar, ToolbarGroup } from "@xenosystem/components/chrome";
2932
2855
  import { formatTick as formatTick4 } from "@xenosystem/time-core";
2933
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
2856
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2934
2857
  var RULER_PX = 22;
2935
2858
  var TOOLS = [
2936
2859
  { id: "select", label: "Select", key: "V" },
@@ -3038,11 +2961,11 @@ function TimelinePanelView({ controller }) {
3038
2961
  const ticks = state.arrangement ? rulerTicks(scale, state.timebase) : [];
3039
2962
  const selected = new Set(state.selection.clipIds);
3040
2963
  const preview = state.preview;
3041
- return /* @__PURE__ */ jsxs3("div", { style: SHELL, children: [
3042
- /* @__PURE__ */ jsx3(
2964
+ return /* @__PURE__ */ jsxs2("div", { style: SHELL, children: [
2965
+ /* @__PURE__ */ jsx2(
3043
2966
  Toolbar,
3044
2967
  {
3045
- left: /* @__PURE__ */ jsx3(ToolbarGroup, { children: TOOLS.map((tool) => /* @__PURE__ */ jsx3(
2968
+ left: /* @__PURE__ */ jsx2(ToolbarGroup, { children: TOOLS.map((tool) => /* @__PURE__ */ jsx2(
3046
2969
  "button",
3047
2970
  {
3048
2971
  type: "button",
@@ -3054,8 +2977,8 @@ function TimelinePanelView({ controller }) {
3054
2977
  },
3055
2978
  tool.id
3056
2979
  )) }),
3057
- right: /* @__PURE__ */ jsxs3(ToolbarGroup, { end: true, children: [
3058
- /* @__PURE__ */ jsx3(
2980
+ right: /* @__PURE__ */ jsxs2(ToolbarGroup, { end: true, children: [
2981
+ /* @__PURE__ */ jsx2(
3059
2982
  "button",
3060
2983
  {
3061
2984
  type: "button",
@@ -3066,11 +2989,11 @@ function TimelinePanelView({ controller }) {
3066
2989
  children: "Snap"
3067
2990
  }
3068
2991
  ),
3069
- /* @__PURE__ */ jsx3("button", { type: "button", title: "Zoom to fit", onClick: () => controller.zoomToFitRange(), style: toolButton(false), children: "Fit" })
2992
+ /* @__PURE__ */ jsx2("button", { type: "button", title: "Zoom to fit", onClick: () => controller.zoomToFitRange(), style: toolButton(false), children: "Fit" })
3070
2993
  ] })
3071
2994
  }
3072
2995
  ),
3073
- !state.arrangement || state.arrangement.tracks.length === 0 ? /* @__PURE__ */ jsx3(EmptyState, { title: "No arrangement", hint: "Wire a host arrangement into this panel's input." }) : /* @__PURE__ */ jsxs3(
2996
+ !state.arrangement || state.arrangement.tracks.length === 0 ? /* @__PURE__ */ jsx2(EmptyState, { title: "No arrangement", hint: "Wire a host arrangement into this panel's input." }) : /* @__PURE__ */ jsxs2(
3074
2997
  "div",
3075
2998
  {
3076
2999
  ref: containerRef,
@@ -3085,7 +3008,7 @@ function TimelinePanelView({ controller }) {
3085
3008
  onPointerCancel: onPointerUp,
3086
3009
  onKeyDown,
3087
3010
  children: [
3088
- /* @__PURE__ */ jsx3("div", { style: { ...RULER, height: RULER_PX }, children: ticks.map((tick) => /* @__PURE__ */ jsx3(
3011
+ /* @__PURE__ */ jsx2("div", { style: { ...RULER, height: RULER_PX }, children: ticks.map((tick) => /* @__PURE__ */ jsx2(
3089
3012
  "div",
3090
3013
  {
3091
3014
  style: {
@@ -3096,20 +3019,20 @@ function TimelinePanelView({ controller }) {
3096
3019
  height: tick.weight === "major" ? 8 : tick.weight === "medium" ? 5 : 3,
3097
3020
  background: "var(--xeno-active)"
3098
3021
  },
3099
- children: tick.label ? /* @__PURE__ */ jsx3("span", { style: TICK_LABEL, className: "tabular-nums", children: tick.label }) : null
3022
+ children: tick.label ? /* @__PURE__ */ jsx2("span", { style: TICK_LABEL, className: "tabular-nums", children: tick.label }) : null
3100
3023
  },
3101
3024
  tick.tick
3102
3025
  )) }),
3103
- /* @__PURE__ */ jsxs3("div", { style: { position: "absolute", inset: `${RULER_PX}px 0 0 0`, overflow: "hidden" }, children: [
3026
+ /* @__PURE__ */ jsxs2("div", { style: { position: "absolute", inset: `${RULER_PX}px 0 0 0`, overflow: "hidden" }, children: [
3104
3027
  state.visible.map((row) => {
3105
3028
  const top = row.topPx - scale.scrollTopPx;
3106
- return /* @__PURE__ */ jsxs3("div", { style: { position: "absolute", left: 0, right: 0, top, height: row.heightPx }, children: [
3107
- /* @__PURE__ */ jsx3("div", { style: { ...GUTTER, width: scale.gutterPx }, children: /* @__PURE__ */ jsx3("span", { style: TRACK_NAME, children: row.track.name }) }),
3108
- /* @__PURE__ */ jsx3("div", { "data-canvas": "timeline-lane", style: { ...LANE, left: scale.gutterPx }, children: row.clips.map((clip) => {
3029
+ return /* @__PURE__ */ jsxs2("div", { style: { position: "absolute", left: 0, right: 0, top, height: row.heightPx }, children: [
3030
+ /* @__PURE__ */ jsx2("div", { style: { ...GUTTER, width: scale.gutterPx }, children: /* @__PURE__ */ jsx2("span", { style: TRACK_NAME, children: row.track.name }) }),
3031
+ /* @__PURE__ */ jsx2("div", { "data-canvas": "timeline-lane", style: { ...LANE, left: scale.gutterPx }, children: row.clips.map((clip) => {
3109
3032
  const shown = preview?.clips[clip.id] ?? clip;
3110
3033
  const x = scale.tickToX(shown.startTick);
3111
3034
  const width = Math.max(1, scale.durationToPx(shown.endTick - shown.startTick));
3112
- return /* @__PURE__ */ jsx3(
3035
+ return /* @__PURE__ */ jsx2(
3113
3036
  ClipRect,
3114
3037
  {
3115
3038
  clip,
@@ -3122,7 +3045,7 @@ function TimelinePanelView({ controller }) {
3122
3045
  }) })
3123
3046
  ] }, row.track.id);
3124
3047
  }),
3125
- preview?.marquee ? /* @__PURE__ */ jsx3(
3048
+ preview?.marquee ? /* @__PURE__ */ jsx2(
3126
3049
  "div",
3127
3050
  {
3128
3051
  style: {
@@ -3137,15 +3060,15 @@ function TimelinePanelView({ controller }) {
3137
3060
  }
3138
3061
  ) : null
3139
3062
  ] }),
3140
- /* @__PURE__ */ jsx3("div", { style: { ...PLAYHEAD, left: Math.floor(scale.tickToX(state.playheadTick)) } })
3063
+ /* @__PURE__ */ jsx2("div", { style: { ...PLAYHEAD, left: Math.floor(scale.tickToX(state.playheadTick)) } })
3141
3064
  ]
3142
3065
  }
3143
3066
  ),
3144
- /* @__PURE__ */ jsx3(
3067
+ /* @__PURE__ */ jsx2(
3145
3068
  StatusBar,
3146
3069
  {
3147
3070
  left: state.arrangement ? `${state.arrangement.tracks.length} tracks` : void 0,
3148
- right: /* @__PURE__ */ jsx3("span", { className: "tabular-nums", children: formatTick4(state.playheadTick, state.timebase) })
3071
+ right: /* @__PURE__ */ jsx2("span", { className: "tabular-nums", children: formatTick4(state.playheadTick, state.timebase) })
3149
3072
  }
3150
3073
  )
3151
3074
  ] });
@@ -3156,7 +3079,7 @@ function ClipRect({
3156
3079
  width,
3157
3080
  selected
3158
3081
  }) {
3159
- return /* @__PURE__ */ jsx3(
3082
+ return /* @__PURE__ */ jsx2(
3160
3083
  "div",
3161
3084
  {
3162
3085
  "data-clip-id": clip.id,
@@ -4194,9 +4117,9 @@ import {
4194
4117
  } from "@xenosystem/components/chrome";
4195
4118
 
4196
4119
  // src/time/calendar/react/icons.tsx
4197
- import { jsx as jsx4 } from "react/jsx-runtime";
4120
+ import { jsx as jsx3 } from "react/jsx-runtime";
4198
4121
  function ChevronGlyph({ direction }) {
4199
- return /* @__PURE__ */ jsx4(
4122
+ return /* @__PURE__ */ jsx3(
4200
4123
  "svg",
4201
4124
  {
4202
4125
  width: 11,
@@ -4208,13 +4131,13 @@ function ChevronGlyph({ direction }) {
4208
4131
  strokeLinecap: "round",
4209
4132
  strokeLinejoin: "round",
4210
4133
  "aria-hidden": "true",
4211
- children: direction === "left" ? /* @__PURE__ */ jsx4("path", { d: "m15 18-6-6 6-6" }) : /* @__PURE__ */ jsx4("path", { d: "m9 18 6-6-6-6" })
4134
+ children: direction === "left" ? /* @__PURE__ */ jsx3("path", { d: "m15 18-6-6 6-6" }) : /* @__PURE__ */ jsx3("path", { d: "m9 18 6-6-6-6" })
4212
4135
  }
4213
4136
  );
4214
4137
  }
4215
4138
 
4216
4139
  // src/time/calendar/react/CalendarPanelView.tsx
4217
- import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
4140
+ import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
4218
4141
  var WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
4219
4142
  function CalendarPanelView({
4220
4143
  controller,
@@ -4222,33 +4145,33 @@ function CalendarPanelView({
4222
4145
  emptyHint
4223
4146
  }) {
4224
4147
  const state = useSyncExternalStore3(controller.subscribe, controller.getState, controller.getState);
4225
- const toolbar = /* @__PURE__ */ jsx5(
4148
+ const toolbar = /* @__PURE__ */ jsx4(
4226
4149
  Toolbar2,
4227
4150
  {
4228
- left: /* @__PURE__ */ jsxs4(Fragment, { children: [
4229
- /* @__PURE__ */ jsx5(
4151
+ left: /* @__PURE__ */ jsxs3(Fragment, { children: [
4152
+ /* @__PURE__ */ jsx4(
4230
4153
  IconButton2,
4231
4154
  {
4232
- icon: /* @__PURE__ */ jsx5(ChevronGlyph, { direction: "left" }),
4155
+ icon: /* @__PURE__ */ jsx4(ChevronGlyph, { direction: "left" }),
4233
4156
  label: "Previous",
4234
4157
  onClick: () => controller.navigate(-1)
4235
4158
  }
4236
4159
  ),
4237
- /* @__PURE__ */ jsx5(
4160
+ /* @__PURE__ */ jsx4(
4238
4161
  IconButton2,
4239
4162
  {
4240
- icon: /* @__PURE__ */ jsx5(ChevronGlyph, { direction: "right" }),
4163
+ icon: /* @__PURE__ */ jsx4(ChevronGlyph, { direction: "right" }),
4241
4164
  label: "Next",
4242
4165
  onClick: () => controller.navigate(1)
4243
4166
  }
4244
4167
  ),
4245
- /* @__PURE__ */ jsx5(TextButton2, { onClick: () => controller.goToToday(), children: "Today" }),
4246
- /* @__PURE__ */ jsx5("span", { style: { fontSize: 11, opacity: 0.8 }, children: controller.anchorKey().slice(0, 7) })
4168
+ /* @__PURE__ */ jsx4(TextButton2, { onClick: () => controller.goToToday(), children: "Today" }),
4169
+ /* @__PURE__ */ jsx4("span", { style: { fontSize: 11, opacity: 0.8 }, children: controller.anchorKey().slice(0, 7) })
4247
4170
  ] }),
4248
- right: /* @__PURE__ */ jsxs4(ToolbarGroup2, { end: true, children: [
4249
- state.partial ? /* @__PURE__ */ jsx5(Badge, { tone: "warning", title: "Some measures have not finished syncing.", children: "partial" }) : null,
4250
- /* @__PURE__ */ jsx5(Badge, { title: "Every date is bucketed in this zone.", children: controller.timeZone() }),
4251
- /* @__PURE__ */ jsx5(
4171
+ right: /* @__PURE__ */ jsxs3(ToolbarGroup2, { end: true, children: [
4172
+ state.partial ? /* @__PURE__ */ jsx4(Badge, { tone: "warning", title: "Some measures have not finished syncing.", children: "partial" }) : null,
4173
+ /* @__PURE__ */ jsx4(Badge, { title: "Every date is bucketed in this zone.", children: controller.timeZone() }),
4174
+ /* @__PURE__ */ jsx4(
4252
4175
  SegmentedControl,
4253
4176
  {
4254
4177
  size: "sm",
@@ -4269,13 +4192,13 @@ function CalendarPanelView({
4269
4192
  );
4270
4193
  const body = (() => {
4271
4194
  if (state.configProblem) {
4272
- return /* @__PURE__ */ jsx5(EmptyState2, { title: "Not configured", hint: state.configProblem });
4195
+ return /* @__PURE__ */ jsx4(EmptyState2, { title: "Not configured", hint: state.configProblem });
4273
4196
  }
4274
4197
  if (state.errorMessage) {
4275
- return /* @__PURE__ */ jsx5(ErrorState, { title: "Could not load events", message: state.errorMessage });
4198
+ return /* @__PURE__ */ jsx4(ErrorState, { title: "Could not load events", message: state.errorMessage });
4276
4199
  }
4277
4200
  if (state.empty) {
4278
- return /* @__PURE__ */ jsx5(
4201
+ return /* @__PURE__ */ jsx4(
4279
4202
  EmptyState2,
4280
4203
  {
4281
4204
  title: "Nothing scheduled",
@@ -4284,7 +4207,7 @@ function CalendarPanelView({
4284
4207
  );
4285
4208
  }
4286
4209
  if (state.viewMode === "agenda" || state.viewMode === "timeline") {
4287
- return /* @__PURE__ */ jsx5(ScrollArea, { children: /* @__PURE__ */ jsx5(RowList, { role: "listbox", "aria-label": "Events", children: state.events.map((event) => /* @__PURE__ */ jsx5(
4210
+ return /* @__PURE__ */ jsx4(ScrollArea, { children: /* @__PURE__ */ jsx4(RowList, { role: "listbox", "aria-label": "Events", children: state.events.map((event) => /* @__PURE__ */ jsx4(
4288
4211
  Row,
4289
4212
  {
4290
4213
  label: event.title,
@@ -4292,14 +4215,14 @@ function CalendarPanelView({
4292
4215
  selected: state.selection.includes(event.id),
4293
4216
  onClick: () => controller.select([event.id]),
4294
4217
  onDoubleClick: () => controller.activateRow(event.id),
4295
- trailing: event.status !== void 0 ? /* @__PURE__ */ jsx5(Badge, { tone: statusTone(event.status), children: String(event.status) }) : null
4218
+ trailing: event.status !== void 0 ? /* @__PURE__ */ jsx4(Badge, { tone: statusTone(event.status), children: String(event.status) }) : null
4296
4219
  },
4297
4220
  event.id
4298
4221
  )) }) });
4299
4222
  }
4300
4223
  const columns = state.viewMode === "day" ? 1 : 7;
4301
- return /* @__PURE__ */ jsxs4(ScrollArea, { children: [
4302
- columns === 7 ? /* @__PURE__ */ jsx5("div", { style: { display: "grid", gridTemplateColumns: "repeat(7, 1fr)" }, children: WEEKDAYS.map((_, i) => /* @__PURE__ */ jsx5(
4224
+ return /* @__PURE__ */ jsxs3(ScrollArea, { children: [
4225
+ columns === 7 ? /* @__PURE__ */ jsx4("div", { style: { display: "grid", gridTemplateColumns: "repeat(7, 1fr)" }, children: WEEKDAYS.map((_, i) => /* @__PURE__ */ jsx4(
4303
4226
  "div",
4304
4227
  {
4305
4228
  style: {
@@ -4313,7 +4236,7 @@ function CalendarPanelView({
4313
4236
  },
4314
4237
  i
4315
4238
  )) }) : null,
4316
- /* @__PURE__ */ jsx5("div", { style: { display: "grid", gridTemplateColumns: `repeat(${columns}, 1fr)`, gap: 1 }, children: state.cells.map((cell) => /* @__PURE__ */ jsxs4(
4239
+ /* @__PURE__ */ jsx4("div", { style: { display: "grid", gridTemplateColumns: `repeat(${columns}, 1fr)`, gap: 1 }, children: state.cells.map((cell) => /* @__PURE__ */ jsxs3(
4317
4240
  "div",
4318
4241
  {
4319
4242
  onClick: () => controller.activateSlot(cell.key),
@@ -4326,9 +4249,9 @@ function CalendarPanelView({
4326
4249
  boxShadow: cell.today ? "inset 0 0 0 1px var(--xeno-control)" : void 0
4327
4250
  },
4328
4251
  children: [
4329
- /* @__PURE__ */ jsx5("div", { style: { fontSize: 9, opacity: 0.7, fontVariantNumeric: "tabular-nums" }, children: cell.day }),
4330
- cell.events.map((event) => /* @__PURE__ */ jsx5(Chip, { event, controller, state }, event.id)),
4331
- cell.overflow > 0 ? /* @__PURE__ */ jsxs4("div", { style: { fontSize: 9, opacity: 0.5 }, children: [
4252
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: 9, opacity: 0.7, fontVariantNumeric: "tabular-nums" }, children: cell.day }),
4253
+ cell.events.map((event) => /* @__PURE__ */ jsx4(Chip, { event, controller, state }, event.id)),
4254
+ cell.overflow > 0 ? /* @__PURE__ */ jsxs3("div", { style: { fontSize: 9, opacity: 0.5 }, children: [
4332
4255
  "+",
4333
4256
  cell.overflow,
4334
4257
  " more"
@@ -4339,10 +4262,10 @@ function CalendarPanelView({
4339
4262
  )) })
4340
4263
  ] });
4341
4264
  })();
4342
- return /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, children: [
4265
+ return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, children: [
4343
4266
  toolbar,
4344
4267
  body,
4345
- /* @__PURE__ */ jsx5(
4268
+ /* @__PURE__ */ jsx4(
4346
4269
  StatusBar2,
4347
4270
  {
4348
4271
  left: `${state.events.length} event${state.events.length === 1 ? "" : "s"}`,
@@ -4357,7 +4280,7 @@ function Chip({
4357
4280
  state
4358
4281
  }) {
4359
4282
  const selected = state.selection.includes(event.id);
4360
- return /* @__PURE__ */ jsxs4(
4283
+ return /* @__PURE__ */ jsxs3(
4361
4284
  "div",
4362
4285
  {
4363
4286
  onClick: (e) => {
@@ -4386,7 +4309,7 @@ function Chip({
4386
4309
  cursor: "pointer"
4387
4310
  },
4388
4311
  children: [
4389
- event.allDay ? null : /* @__PURE__ */ jsx5("span", { style: { opacity: 0.6, marginRight: 3, fontVariantNumeric: "tabular-nums" }, children: formatMinutes(event.startMinutes) }),
4312
+ event.allDay ? null : /* @__PURE__ */ jsx4("span", { style: { opacity: 0.6, marginRight: 3, fontVariantNumeric: "tabular-nums" }, children: formatMinutes(event.startMinutes) }),
4390
4313
  event.title
4391
4314
  ]
4392
4315
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenosystem/blocks",
3
- "version": "0.12.8",
3
+ "version": "0.13.0",
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",
@@ -34,6 +34,10 @@
34
34
  "types": "./dist/data/duckdb.d.ts",
35
35
  "import": "./dist/data/duckdb.js"
36
36
  },
37
+ "./icons": {
38
+ "types": "./dist/icons/index.d.ts",
39
+ "import": "./dist/icons/index.js"
40
+ },
37
41
  "./edit": {
38
42
  "types": "./dist/edit/index.d.ts",
39
43
  "import": "./dist/edit/index.js"
@@ -60,7 +64,7 @@
60
64
  "peerDependencies": {
61
65
  "@duckdb/duckdb-wasm": ">=1.28.0",
62
66
  "@xenosystem/block-sdk": ">=0.3.3 <1",
63
- "@xenosystem/components": ">=0.17.0 <1",
67
+ "@xenosystem/components": ">=0.17.1 <1",
64
68
  "@xenosystem/data-core": "^0.1.0",
65
69
  "@xenosystem/elements-react": ">=0.0.1",
66
70
  "@xenosystem/time-core": "^0.1.0",
@@ -76,7 +80,7 @@
76
80
  "@types/react": "^19.0.0",
77
81
  "@types/react-dom": "^19.0.0",
78
82
  "@xenosystem/block-sdk": "^0.3.3",
79
- "@xenosystem/components": "^0.17.0",
83
+ "@xenosystem/components": "^0.17.1",
80
84
  "@xenosystem/data-core": "^0.1.0",
81
85
  "@xenosystem/elements-react": "0.0.1",
82
86
  "@xenosystem/time-core": "^0.1.0",