dialkit 1.4.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vue/index.js CHANGED
@@ -2106,6 +2106,10 @@ var ICON_PAUSE = [
2106
2106
  "M16.75 3C15.2312 3 14 4.23122 14 5.75V18.25C14 19.7688 15.2312 21 16.75 21H17.25C18.7688 21 20 19.7688 20 18.25V5.75C20 4.23122 18.7688 3 17.25 3H16.75Z"
2107
2107
  ];
2108
2108
  var ICON_PLAY = "M9.24394 2.36758C7.41419 1.18362 5 2.49701 5 4.67639V19.3238C5 21.5032 7.41419 22.8166 9.24394 21.6326L20.5624 14.3089C22.2371 13.2253 22.2372 10.775 20.5624 9.69129L9.24394 2.36758Z";
2109
+ var ICON_REPLAY = [
2110
+ "M12 2.5C17.2466 2.50016 21.5 6.7534 21.5 12C21.5 17.2466 17.2466 21.4998 12 21.5C7.52191 21.5 3.76987 18.4025 2.76465 14.2344C2.63517 13.6975 2.96508 13.1578 3.50195 13.0283C4.03883 12.8988 4.57851 13.2288 4.70801 13.7656C5.5016 17.0563 8.46701 19.5 12 19.5C16.142 19.4998 19.5 16.142 19.5 12C19.5 7.85796 16.142 4.50016 12 4.5C9.32981 4.5 6.98389 5.89541 5.6543 8H7.5C8.05228 8 8.5 8.44772 8.5 9C8.5 9.55228 8.05228 10 7.5 10H3.5C2.94772 10 2.5 9.55228 2.5 9V5C2.5 4.44772 2.94772 4 3.5 4C4.05228 4 4.5 4.44772 4.5 5V6.16797C6.2376 3.93677 8.95063 2.5 12 2.5Z",
2111
+ "M10 9.94043C10 9.33379 10.6826 8.97849 11.1797 9.32617L14.1221 11.3857C14.5486 11.6843 14.5486 12.3157 14.1221 12.6143L11.1797 14.6738C10.6826 15.0215 10 14.6662 10 14.0596V9.94043Z"
2112
+ ];
2109
2113
  var ICON_TIMELINE = [
2110
2114
  "M18.868 10C20.8517 10.0003 22.2886 11.8914 21.7577 13.8027L20.369 18.8027C20.0083 20.1012 18.826 20.9999 17.4784 21H6.51941C5.17179 21 3.98948 20.1012 3.62878 18.8027L2.24011 13.8027C1.7092 11.8913 3.14603 10.0003 5.12976 10H18.868Z",
2111
2115
  "M18.9989 6.5C19.5511 6.50007 19.9989 6.94776 19.9989 7.5C19.9989 8.05224 19.5511 8.49993 18.9989 8.5H4.9989C4.44661 8.5 3.9989 8.05228 3.9989 7.5C3.9989 6.94772 4.44661 6.5 4.9989 6.5H18.9989Z",
@@ -2743,6 +2747,7 @@ var Slider = defineComponent2({
2743
2747
  },
2744
2748
  onKeydown: handleInputKeydown,
2745
2749
  onBlur: handleInputSubmit,
2750
+ onPointerdown: (event) => event.stopPropagation(),
2746
2751
  onClick: (event) => event.stopPropagation(),
2747
2752
  onMousedown: (event) => event.stopPropagation()
2748
2753
  }) : h2("span", {
@@ -2755,6 +2760,9 @@ var Slider = defineComponent2({
2755
2760
  isValueHovered.value = false;
2756
2761
  },
2757
2762
  onClick: handleValueClick,
2763
+ onPointerdown: (event) => {
2764
+ if (isValueEditable.value) event.stopPropagation();
2765
+ },
2758
2766
  onMousedown: (event) => {
2759
2767
  if (isValueEditable.value) event.stopPropagation();
2760
2768
  },
@@ -4786,8 +4794,11 @@ var SECOND_TICK_STEPS = [
4786
4794
  ];
4787
4795
  var MIN_TIMELINE_MAX_ZOOM = 8;
4788
4796
  var PLAYHEAD_FLAG_WIDTH = 52;
4797
+ var PLAYHEAD_FLAG_EDGE_OVERHANG = 1;
4789
4798
  var POPOVER_WIDTH = 280;
4790
4799
  var ZOOM_DRAG_DISTANCE = 180;
4800
+ var DEFAULT_DOCK_MAX_HEIGHT = 400;
4801
+ var MIN_DOCK_MAX_HEIGHT = 120;
4791
4802
  var DialTimeline = defineComponent19({
4792
4803
  name: "DialKitTimeline",
4793
4804
  props: {
@@ -4805,10 +4816,36 @@ var DialTimeline = defineComponent19({
4805
4816
  const timelines = ref15(TimelineStore.getTimelines());
4806
4817
  const dockVisible = ref15(TimelineUiStore.getVisible());
4807
4818
  const mounted = ref15(false);
4819
+ const dockMaxHeight = ref15(DEFAULT_DOCK_MAX_HEIGHT);
4820
+ const dockRef = ref15(null);
4808
4821
  const controllerId = /* @__PURE__ */ Symbol("dialkit-timeline-visibility");
4809
4822
  let unsubscribeTimelines;
4810
4823
  let unsubscribeVisibility;
4811
4824
  let unregisterController;
4825
+ let resizeCleanup = null;
4826
+ const handleResizePointerDown = (event) => {
4827
+ if (!dockRef.value) return;
4828
+ event.preventDefault();
4829
+ event.stopPropagation();
4830
+ resizeCleanup?.();
4831
+ const pointerY = event.clientY;
4832
+ const startHeight = dockRef.value.getBoundingClientRect().height;
4833
+ const move = (next) => {
4834
+ next.preventDefault();
4835
+ const viewportMax = Math.max(MIN_DOCK_MAX_HEIGHT, window.innerHeight - 24);
4836
+ dockMaxHeight.value = clamp(startHeight + pointerY - next.clientY, MIN_DOCK_MAX_HEIGHT, viewportMax);
4837
+ };
4838
+ const finish = () => {
4839
+ window.removeEventListener("pointermove", move);
4840
+ window.removeEventListener("pointerup", finish);
4841
+ window.removeEventListener("pointercancel", finish);
4842
+ resizeCleanup = null;
4843
+ };
4844
+ window.addEventListener("pointermove", move, { passive: false });
4845
+ window.addEventListener("pointerup", finish);
4846
+ window.addEventListener("pointercancel", finish);
4847
+ resizeCleanup = finish;
4848
+ };
4812
4849
  onMounted13(() => {
4813
4850
  mounted.value = true;
4814
4851
  unsubscribeVisibility = TimelineUiStore.subscribe(() => {
@@ -4835,6 +4872,7 @@ var DialTimeline = defineComponent19({
4835
4872
  unregisterController?.();
4836
4873
  unsubscribeTimelines?.();
4837
4874
  unsubscribeVisibility?.();
4875
+ resizeCleanup?.();
4838
4876
  });
4839
4877
  return () => {
4840
4878
  if (!props.productionEnabled || !mounted.value || timelines.value.length === 0) return null;
@@ -4844,7 +4882,19 @@ var DialTimeline = defineComponent19({
4844
4882
  "data-theme": props.theme,
4845
4883
  hidden: !dockVisible.value
4846
4884
  }, [
4847
- h19("div", { class: "dialkit-timeline-dock" }, timelines.value.map((meta) => h19(TimelineSection, {
4885
+ h19("div", {
4886
+ class: "dialkit-timeline-resize-handle",
4887
+ role: "separator",
4888
+ "aria-label": "Resize timeline height",
4889
+ "aria-orientation": "horizontal",
4890
+ title: "Drag to resize timeline",
4891
+ onPointerdown: handleResizePointerDown
4892
+ }),
4893
+ h19("div", {
4894
+ ref: dockRef,
4895
+ class: "dialkit-timeline-dock",
4896
+ style: { maxHeight: `min(${dockMaxHeight.value}px, calc(100vh - 24px))` }
4897
+ }, timelines.value.map((meta) => h19(TimelineSection, {
4848
4898
  key: meta.id,
4849
4899
  meta,
4850
4900
  defaultOpen: props.defaultOpen,
@@ -4885,6 +4935,23 @@ var PlayPauseButton = defineComponent19({
4885
4935
  };
4886
4936
  }
4887
4937
  });
4938
+ var ReplayButton = defineComponent19({
4939
+ props: { onReplay: { type: Function, required: true } },
4940
+ setup(props) {
4941
+ return () => h19("button", {
4942
+ class: "dialkit-toolbar-add",
4943
+ title: "Replay",
4944
+ "aria-label": "Replay",
4945
+ onClick: props.onReplay
4946
+ }, [
4947
+ h19(
4948
+ "svg",
4949
+ { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true" },
4950
+ ICON_REPLAY.map((path) => h19("path", { d: path, fill: "currentColor" }))
4951
+ )
4952
+ ]);
4953
+ }
4954
+ });
4888
4955
  var iconStyle = {
4889
4956
  position: "absolute",
4890
4957
  inset: 0,
@@ -4961,8 +5028,6 @@ var TimelinePlayheadFlag = defineComponent19({
4961
5028
  viewEnd: { type: Number, required: true },
4962
5029
  laneWidth: { type: Number, required: true },
4963
5030
  ruler: Object,
4964
- headerClearStart: { type: Number, required: true },
4965
- headerClearEnd: { type: Number, required: true },
4966
5031
  onResetView: { type: Function, required: true }
4967
5032
  },
4968
5033
  setup(props) {
@@ -4990,13 +5055,20 @@ var TimelinePlayheadFlag = defineComponent19({
4990
5055
  return () => {
4991
5056
  if (time.value < props.viewStart || time.value > props.viewEnd || props.laneWidth <= 0) return null;
4992
5057
  const x = clamp((time.value - props.viewStart) * props.pxPerSecond, 0, props.laneWidth);
4993
- const left = x - PLAYHEAD_FLAG_WIDTH / 2;
4994
- const placement = left >= props.headerClearStart && left + PLAYHEAD_FLAG_WIDTH <= props.headerClearEnd ? "raised" : "lowered";
5058
+ const flagCenter = clamp(
5059
+ x,
5060
+ PLAYHEAD_FLAG_WIDTH / 2 - PLAYHEAD_FLAG_EDGE_OVERHANG,
5061
+ props.laneWidth - PLAYHEAD_FLAG_WIDTH / 2 + PLAYHEAD_FLAG_EDGE_OVERHANG
5062
+ );
5063
+ const flagOffset = flagCenter - x;
5064
+ const edge = flagOffset > 0.5 ? "start" : flagOffset < -0.5 ? "end" : "center";
4995
5065
  return h19("div", {
4996
5066
  class: "dialkit-timeline-playhead-control",
4997
- "data-edge": "center",
4998
- "data-placement": placement,
4999
- style: { left: `calc(var(--dial-timeline-label-w) + ${x}px)` },
5067
+ "data-edge": edge,
5068
+ style: {
5069
+ left: `calc(var(--dial-timeline-label-w) + ${x}px)`,
5070
+ "--dial-timeline-playhead-flag-offset": `${flagOffset}px`
5071
+ },
5000
5072
  role: "slider",
5001
5073
  "aria-label": "Timeline current time",
5002
5074
  "aria-valuemin": 0,
@@ -5037,8 +5109,10 @@ var TimelinePlayheadFlag = defineComponent19({
5037
5109
  cleanup = finish;
5038
5110
  }
5039
5111
  }, [
5040
- h19("div", { class: "dialkit-timeline-playhead-flag" }, time.value.toFixed(2)),
5041
- h19("div", { class: "dialkit-timeline-playhead-stem" })
5112
+ h19("div", { class: "dialkit-timeline-playhead-stem" }),
5113
+ h19("div", { class: "dialkit-timeline-playhead-anchor" }, [
5114
+ h19("div", { class: "dialkit-timeline-playhead-flag" }, time.value.toFixed(2))
5115
+ ])
5042
5116
  ]);
5043
5117
  };
5044
5118
  }
@@ -5070,33 +5144,21 @@ var TimelineSection = defineComponent19({
5070
5144
  const presets = ref15(DialStore.getPresets(props.meta.id));
5071
5145
  const activePresetId = ref15(DialStore.getActivePresetId(props.meta.id));
5072
5146
  const laneAreaRef = ref15(null);
5073
- const titleRef = ref15(null);
5074
- const actionsRef = ref15(null);
5147
+ const horizontalScrollRef = ref15(null);
5075
5148
  const laneWidth = ref15(0);
5076
- const flagClearRange = ref15({ start: 0, end: 0 });
5077
5149
  let unsubscribeValues;
5078
5150
  let resizeObserver;
5079
5151
  const measure = () => {
5080
- if (!laneAreaRef.value || !titleRef.value || !actionsRef.value) return;
5081
- const ruler = laneAreaRef.value.getBoundingClientRect();
5082
- const title = titleRef.value.getBoundingClientRect();
5083
- const actions = actionsRef.value.getBoundingClientRect();
5084
- laneWidth.value = ruler.width;
5085
- flagClearRange.value = {
5086
- start: Math.round(title.right + 10 - ruler.left),
5087
- end: Math.round(actions.left - 10 - ruler.left)
5088
- };
5152
+ if (laneAreaRef.value) laneWidth.value = laneAreaRef.value.getBoundingClientRect().width;
5089
5153
  };
5090
5154
  const connectMeasure = async () => {
5091
5155
  resizeObserver?.disconnect();
5092
5156
  if (!open.value) return;
5093
5157
  await nextTick4();
5094
- if (!laneAreaRef.value || !titleRef.value || !actionsRef.value) return;
5158
+ if (!laneAreaRef.value) return;
5095
5159
  measure();
5096
5160
  resizeObserver = new ResizeObserver(measure);
5097
5161
  resizeObserver.observe(laneAreaRef.value);
5098
- resizeObserver.observe(titleRef.value);
5099
- resizeObserver.observe(actionsRef.value);
5100
5162
  };
5101
5163
  onMounted13(() => {
5102
5164
  unsubscribeValues = DialStore.subscribe(props.meta.id, () => {
@@ -5128,6 +5190,13 @@ var TimelineSection = defineComponent19({
5128
5190
  watch8([() => props.meta.duration, zoom], () => {
5129
5191
  viewStart.value = clampViewStart(viewStart.value, props.meta.duration, props.meta.duration / zoom.value);
5130
5192
  });
5193
+ watch8([open, pxPerSecond, safeViewStart], async () => {
5194
+ await nextTick4();
5195
+ const scroller = horizontalScrollRef.value;
5196
+ if (!scroller || pxPerSecond.value <= 0) return;
5197
+ const next = safeViewStart.value * pxPerSecond.value;
5198
+ if (Math.abs(scroller.scrollLeft - next) > 0.5) scroller.scrollLeft = next;
5199
+ });
5131
5200
  const centerViewAt = (time) => {
5132
5201
  if (zoom.value <= 1 || props.meta.duration <= 0) return;
5133
5202
  const duration = props.meta.duration / zoom.value;
@@ -5137,6 +5206,26 @@ var TimelineSection = defineComponent19({
5137
5206
  zoom.value = 1;
5138
5207
  viewStart.value = 0;
5139
5208
  };
5209
+ const handleReplay = () => {
5210
+ viewStart.value = 0;
5211
+ TimelineStore.replay(props.meta.id);
5212
+ };
5213
+ const handleHorizontalScroll = (event) => {
5214
+ if (pxPerSecond.value <= 0) return;
5215
+ viewStart.value = clampViewStart(
5216
+ event.currentTarget.scrollLeft / pxPerSecond.value,
5217
+ props.meta.duration,
5218
+ visibleDuration.value
5219
+ );
5220
+ };
5221
+ const handleTimelineWheel = (event) => {
5222
+ const scroller = horizontalScrollRef.value;
5223
+ if (!scroller || zoom.value <= 1) return;
5224
+ const delta = Math.abs(event.deltaX) > Math.abs(event.deltaY) ? event.deltaX : event.shiftKey ? event.deltaY : 0;
5225
+ if (delta === 0) return;
5226
+ event.preventDefault();
5227
+ scroller.scrollLeft += delta;
5228
+ };
5140
5229
  let zoomDrag = null;
5141
5230
  let rulerScrub = null;
5142
5231
  let trackScrub = null;
@@ -5320,7 +5409,7 @@ var TimelineSection = defineComponent19({
5320
5409
  return () => h19("div", { class: "dialkit-timeline-section" }, [
5321
5410
  h19("div", { class: "dialkit-timeline-header", "data-open": open.value || void 0 }, [
5322
5411
  h19("div", { class: "dialkit-timeline-identity" }, [
5323
- h19("span", { ref: titleRef, class: "dialkit-timeline-title" }, props.meta.name)
5412
+ h19("span", { class: "dialkit-timeline-title" }, props.meta.name)
5324
5413
  ]),
5325
5414
  !open.value ? h19(TimelineOverview, {
5326
5415
  id: props.meta.id,
@@ -5329,8 +5418,9 @@ var TimelineSection = defineComponent19({
5329
5418
  viewEnd: viewEnd.value,
5330
5419
  onNavigate: centerViewAt
5331
5420
  }) : null,
5332
- h19("div", { ref: actionsRef, class: "dialkit-timeline-actions" }, [
5421
+ h19("div", { class: "dialkit-timeline-actions" }, [
5333
5422
  h19(PlayPauseButton, { id: props.meta.id }),
5423
+ h19(ReplayButton, { onReplay: handleReplay }),
5334
5424
  h19("button", { class: "dialkit-toolbar-add", title: "Add timeline version", "aria-label": "Add timeline version", onClick: handleAddPreset }, [
5335
5425
  h19(
5336
5426
  "svg",
@@ -5364,6 +5454,7 @@ var TimelineSection = defineComponent19({
5364
5454
  ]),
5365
5455
  open.value ? h19("div", {
5366
5456
  class: "dialkit-timeline-body",
5457
+ onWheel: handleTimelineWheel,
5367
5458
  onPointerdown: (event) => {
5368
5459
  const target = event.target;
5369
5460
  if (target.closest(".dialkit-timeline-label, button")) return;
@@ -5457,11 +5548,17 @@ var TimelineSection = defineComponent19({
5457
5548
  viewEnd: viewEnd.value,
5458
5549
  laneWidth: laneWidth.value,
5459
5550
  ruler: laneAreaRef.value ?? void 0,
5460
- headerClearStart: flagClearRange.value.start,
5461
- headerClearEnd: flagClearRange.value.end,
5462
5551
  onResetView: resetView
5463
5552
  }) : null
5464
- ])]) : null,
5553
+ ]), zoom.value > 1 ? h19("div", { class: "dialkit-timeline-scroll-row" }, [
5554
+ h19("div", { class: "dialkit-timeline-label" }),
5555
+ h19("div", {
5556
+ ref: horizontalScrollRef,
5557
+ class: "dialkit-timeline-horizontal-scroll",
5558
+ "aria-label": "Timeline horizontal scroll",
5559
+ onScroll: handleHorizontalScroll
5560
+ }, [h19("div", { style: { width: `${laneWidth.value * zoom.value}px` } })])
5561
+ ]) : null]) : null,
5465
5562
  popover.value ? h19(ClipPopover, {
5466
5563
  panelId: props.meta.id,
5467
5564
  popover: popover.value,