@tensor_1/react 2.31.0 → 2.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +367 -0
- package/dist/SchedulingCalendar-C4XVbqZr.d.ts +339 -0
- package/dist/attachment-labels.d.ts +16 -0
- package/dist/attachment-labels.js +9 -0
- package/dist/calendar-model.d.ts +141 -1
- package/dist/calendar-model.js +200 -11
- package/dist/chart-preset.cjs +127 -7
- package/dist/chart-preset.d.cts +2 -2
- package/dist/chart-preset.d.ts +1 -0
- package/dist/chart-preset.js +6 -1
- package/dist/chart-theme-Cl0IrkKQ.d.cts +112 -0
- package/dist/chart-theme.d.ts +51 -0
- package/dist/chart-theme.js +99 -0
- package/dist/chart.cjs +127 -7
- package/dist/chart.d.cts +2 -2
- package/dist/chart.d.ts +1 -0
- package/dist/chart.js +6 -2
- package/dist/components/Alert.d.ts +17 -1
- package/dist/components/Alert.js +9 -4
- package/dist/components/AlertDismiss.d.ts +14 -0
- package/dist/components/AlertDismiss.js +11 -0
- package/dist/components/Attachment.d.ts +15 -12
- package/dist/components/Attachment.js +17 -17
- package/dist/components/AttachmentParts.d.ts +24 -0
- package/dist/components/AttachmentParts.js +20 -0
- package/dist/components/Chart.d.ts +1 -0
- package/dist/components/Chart.js +6 -1
- package/dist/components/ChartCore.d.ts +6 -1
- package/dist/components/ChartCore.js +23 -5
- package/dist/components/Chip.d.ts +17 -2
- package/dist/components/Chip.js +35 -11
- package/dist/components/ChipRemove.d.ts +17 -0
- package/dist/components/ChipRemove.js +13 -0
- package/dist/components/CollapsibleParts.d.ts +29 -0
- package/dist/components/CollapsibleParts.js +20 -0
- package/dist/components/CollapsibleSection.d.ts +30 -3
- package/dist/components/CollapsibleSection.js +7 -11
- package/dist/components/CollapsibleSectionState.d.ts +1 -1
- package/dist/components/CollapsibleSectionState.js +54 -27
- package/dist/components/DashboardGrid.d.ts +60 -0
- package/dist/components/DashboardGrid.js +40 -0
- package/dist/components/DateRangePicker.d.ts +7 -1
- package/dist/components/DateRangePicker.js +5 -1
- package/dist/components/DescriptionList.d.ts +12 -1
- package/dist/components/DescriptionList.js +5 -5
- package/dist/components/Dialogs.d.ts +24 -3
- package/dist/components/Dialogs.js +74 -16
- package/dist/components/FileUpload.d.ts +10 -2
- package/dist/components/FileUpload.js +10 -4
- package/dist/components/FilterEditor.d.ts +4 -0
- package/dist/components/FilterEditor.js +13 -2
- package/dist/components/Heartbeat.d.ts +31 -0
- package/dist/components/Heartbeat.js +28 -0
- package/dist/components/Menu.d.ts +53 -5
- package/dist/components/Menu.js +104 -4
- package/dist/components/Meter.d.ts +7 -3
- package/dist/components/Meter.js +2 -1
- package/dist/components/Popover.d.ts +21 -2
- package/dist/components/Popover.js +94 -17
- package/dist/components/Prose.d.ts +6 -2
- package/dist/components/Prose.js +1 -1
- package/dist/components/RuleBuilder.d.ts +52 -4
- package/dist/components/RuleBuilder.js +109 -24
- package/dist/components/SchedulingCalendar.d.ts +4 -110
- package/dist/components/SchedulingCalendar.js +299 -63
- package/dist/components/SchedulingTimeGrid.d.ts +4 -0
- package/dist/components/SchedulingTimeGrid.js +521 -0
- package/dist/components/SchedulingTimeline.d.ts +2 -1
- package/dist/components/Segmented.d.ts +17 -3
- package/dist/components/Segmented.js +59 -5
- package/dist/components/Select.d.ts +66 -2
- package/dist/components/Select.js +800 -10
- package/dist/components/Spinner.d.ts +2 -1
- package/dist/components/Spinner.js +1 -1
- package/dist/components/StatusPill.d.ts +8 -2
- package/dist/components/StatusPill.js +2 -2
- package/dist/components/Steps.d.ts +28 -4
- package/dist/components/Steps.js +46 -16
- package/dist/components/TableControls.js +4 -3
- package/dist/components/Tabs.d.ts +7 -2
- package/dist/components/Tabs.js +14 -1
- package/dist/components/TextDiff.d.ts +49 -0
- package/dist/components/TextDiff.js +124 -0
- package/dist/{emoji-image-6mPZ15Zy.d.cts → emoji-image-DjCKpdwE.d.cts} +1 -1
- package/dist/emoji.cjs +169 -27
- package/dist/emoji.d.cts +3 -3
- package/dist/file-model.d.ts +22 -3
- package/dist/file-model.js +6 -4
- package/dist/filter-model.d.ts +26 -2
- package/dist/filter-model.js +13 -1
- package/dist/hooks/useAnchoredPosition.d.ts +24 -1
- package/dist/hooks/useAnchoredPosition.js +58 -8
- package/dist/hooks/useVirtualRows.d.ts +17 -2
- package/dist/hooks/useVirtualRows.js +6 -5
- package/dist/icons/Icon.d.ts +14 -14
- package/dist/index.cjs +4888 -1714
- package/dist/index.d.cts +1871 -658
- package/dist/index.d.ts +16 -9
- package/dist/index.js +67 -4
- package/dist/labels-context.d.ts +29 -1
- package/dist/{overlay-position-Cjv5E7mn.d.cts → overlay-position-2Afke51l.d.cts} +20 -0
- package/dist/overlay-position.d.ts +20 -0
- package/dist/overlay-position.js +17 -2
- package/dist/rich-text.cjs +169 -27
- package/dist/rich-text.d.cts +3 -3
- package/dist/rule-builder-model.d.ts +34 -2
- package/dist/rule-builder-model.js +48 -12
- package/dist/scheduling-calendar-model.d.ts +169 -0
- package/dist/scheduling-calendar-model.js +176 -0
- package/dist/select-model.d.ts +80 -0
- package/dist/select-model.js +109 -0
- package/dist/table-engine.d.ts +7 -0
- package/dist/table-engine.js +2 -1
- package/dist/text-diff-model.d.ts +71 -0
- package/dist/text-diff-model.js +261 -0
- package/package.json +1 -1
- package/dist/ChartCore-DzWe10bN.d.cts +0 -59
package/dist/rich-text.cjs
CHANGED
|
@@ -79,7 +79,7 @@ function fitsOn(side, a, f, vp, offset, padding) {
|
|
|
79
79
|
return spaceOn(side, a, vp, offset) >= need + padding;
|
|
80
80
|
}
|
|
81
81
|
function computePosition(anchor, floating, viewport, options = {}) {
|
|
82
|
-
const { placement = "bottom-start", offset = 6, padding = 8, flip = true, shift = true, stickySide } = options;
|
|
82
|
+
const { placement = "bottom-start", offset = 6, padding = 8, flip = true, shift = true, shiftMainAxis = true, stickySide } = options;
|
|
83
83
|
const { side: preferred, align } = parsePlacement(placement);
|
|
84
84
|
let side = preferred;
|
|
85
85
|
const sticky = stickySide === preferred || stickySide === OPPOSITE[preferred] ? stickySide : void 0;
|
|
@@ -112,12 +112,27 @@ function computePosition(anchor, floating, viewport, options = {}) {
|
|
|
112
112
|
y = align === "start" ? start : align === "end" ? end : center;
|
|
113
113
|
if (shift) y = clamp(y, padding, Math.max(padding, viewport.height - floating.height - padding));
|
|
114
114
|
}
|
|
115
|
+
const mainAxisNatural = horizontal ? y : x;
|
|
116
|
+
const anchorInView = horizontal ? anchor.y + anchor.height > 0 && anchor.y < viewport.height : anchor.x + anchor.width > 0 && anchor.x < viewport.width;
|
|
117
|
+
let mainAxisRange = null;
|
|
118
|
+
if (shiftMainAxis && anchorInView) {
|
|
119
|
+
const extent = horizontal ? viewport.height - floating.height : viewport.width - floating.width;
|
|
120
|
+
mainAxisRange = [padding, Math.max(padding, extent - padding)];
|
|
121
|
+
if (horizontal) y = clamp(y, mainAxisRange[0], mainAxisRange[1]);
|
|
122
|
+
else x = clamp(x, mainAxisRange[0], mainAxisRange[1]);
|
|
123
|
+
}
|
|
115
124
|
return {
|
|
116
125
|
x,
|
|
117
126
|
y,
|
|
118
127
|
placement: align === "center" ? side : `${side}-${align}`,
|
|
119
128
|
side,
|
|
120
|
-
align
|
|
129
|
+
align,
|
|
130
|
+
mainAxisNatural,
|
|
131
|
+
mainAxisRange,
|
|
132
|
+
available: {
|
|
133
|
+
width: Math.max(0, viewport.width - 2 * padding),
|
|
134
|
+
height: Math.max(0, viewport.height - 2 * padding)
|
|
135
|
+
}
|
|
121
136
|
};
|
|
122
137
|
}
|
|
123
138
|
|
|
@@ -780,6 +795,7 @@ function supportsAnchoring() {
|
|
|
780
795
|
}
|
|
781
796
|
return anchoringSupported;
|
|
782
797
|
}
|
|
798
|
+
var ANCHOR_BAND = 64;
|
|
783
799
|
var anchorCount = 0;
|
|
784
800
|
var namesOf = (value) => value.split(",").map((n) => n.trim()).filter((n) => n.startsWith("--"));
|
|
785
801
|
function addAnchorName(el, name) {
|
|
@@ -804,9 +820,12 @@ function translationOf(el) {
|
|
|
804
820
|
}
|
|
805
821
|
var signed = (n) => `${n < 0 ? "-" : "+"} ${Math.round(Math.abs(n) * 100) / 100}px`;
|
|
806
822
|
var prepared = /* @__PURE__ */ new WeakSet();
|
|
807
|
-
function useAnchoredPosition(anchor, floatingRef, { open, placement = "bottom-start", offset = 6, padding = 8 }) {
|
|
808
|
-
const opts = (0, import_react3.useRef)({ placement, offset, padding });
|
|
809
|
-
opts.current = { placement, offset, padding };
|
|
823
|
+
function useAnchoredPosition(anchor, floatingRef, { open, placement = "bottom-start", offset = 6, padding = 8, shiftMainAxis = true, capHeight = false, onAnchorHidden }) {
|
|
824
|
+
const opts = (0, import_react3.useRef)({ placement, offset, padding, shiftMainAxis, capHeight });
|
|
825
|
+
opts.current = { placement, offset, padding, shiftMainAxis, capHeight };
|
|
826
|
+
const onAnchorHiddenRef = (0, import_react3.useRef)(onAnchorHidden);
|
|
827
|
+
onAnchorHiddenRef.current = onAnchorHidden;
|
|
828
|
+
const heightCap = (0, import_react3.useRef)(null);
|
|
810
829
|
const session = (0, import_react3.useRef)(false);
|
|
811
830
|
const side = (0, import_react3.useRef)(null);
|
|
812
831
|
const written = (0, import_react3.useRef)("");
|
|
@@ -830,6 +849,15 @@ function useAnchoredPosition(anchor, floatingRef, { open, placement = "bottom-st
|
|
|
830
849
|
}
|
|
831
850
|
removeAnchorName(current.anchor, current.name);
|
|
832
851
|
}, [floatingRef]);
|
|
852
|
+
const uncap = (0, import_react3.useCallback)(() => {
|
|
853
|
+
const cap = heightCap.current;
|
|
854
|
+
if (!cap) return;
|
|
855
|
+
heightCap.current = null;
|
|
856
|
+
const floating = floatingRef.current;
|
|
857
|
+
if (!floating) return;
|
|
858
|
+
floating.style.maxHeight = cap.inlineMaxHeight;
|
|
859
|
+
if (cap.setOverflow) floating.style.overflowY = cap.inlineOverflowY;
|
|
860
|
+
}, [floatingRef]);
|
|
833
861
|
const reposition = (0, import_react3.useCallback)(() => {
|
|
834
862
|
const anchorEl = resolveAnchor(anchor);
|
|
835
863
|
const floating = floatingRef.current;
|
|
@@ -842,14 +870,36 @@ function useAnchoredPosition(anchor, floatingRef, { open, placement = "bottom-st
|
|
|
842
870
|
prepared.add(floating);
|
|
843
871
|
written.current = "";
|
|
844
872
|
}
|
|
873
|
+
const { placement: p, offset: o, padding: pad, shiftMainAxis: keepInView, capHeight: cap } = opts.current;
|
|
874
|
+
if (cap) {
|
|
875
|
+
if (!heightCap.current) {
|
|
876
|
+
const own = getComputedStyle(floating);
|
|
877
|
+
const setOverflow = !own.overflowY || own.overflowY === "visible";
|
|
878
|
+
heightCap.current = {
|
|
879
|
+
inlineMaxHeight: s.maxHeight,
|
|
880
|
+
inlineOverflowY: s.overflowY,
|
|
881
|
+
ownMaxHeight: own.maxHeight && own.maxHeight !== "none" ? own.maxHeight : "",
|
|
882
|
+
setOverflow,
|
|
883
|
+
written: ""
|
|
884
|
+
};
|
|
885
|
+
if (setOverflow) s.overflowY = "auto";
|
|
886
|
+
}
|
|
887
|
+
const room = `${Math.max(0, window.innerHeight - 2 * pad)}px`;
|
|
888
|
+
const max = heightCap.current.ownMaxHeight ? `min(${room}, ${heightCap.current.ownMaxHeight})` : room;
|
|
889
|
+
if (max !== heightCap.current.written) {
|
|
890
|
+
s.maxHeight = max;
|
|
891
|
+
heightCap.current.written = max;
|
|
892
|
+
}
|
|
893
|
+
} else if (heightCap.current) {
|
|
894
|
+
uncap();
|
|
895
|
+
}
|
|
845
896
|
const a = anchorEl.getBoundingClientRect();
|
|
846
897
|
const size = { width: floating.offsetWidth, height: floating.offsetHeight };
|
|
847
|
-
const { placement: p, offset: o, padding: pad } = opts.current;
|
|
848
898
|
const pos = computePosition(
|
|
849
899
|
{ x: a.x, y: a.y, width: a.width, height: a.height },
|
|
850
900
|
size,
|
|
851
901
|
{ width: window.innerWidth, height: window.innerHeight },
|
|
852
|
-
{ placement: p, offset: o, padding: pad, stickySide: side.current ?? void 0 }
|
|
902
|
+
{ placement: p, offset: o, padding: pad, shiftMainAxis: keepInView, stickySide: side.current ?? void 0 }
|
|
853
903
|
);
|
|
854
904
|
const measured = size.width > 0 || size.height > 0;
|
|
855
905
|
if (measured && session.current) side.current = pos.side;
|
|
@@ -863,7 +913,10 @@ function useAnchoredPosition(anchor, floatingRef, { open, placement = "bottom-st
|
|
|
863
913
|
s.top = top2;
|
|
864
914
|
written.current = key2;
|
|
865
915
|
};
|
|
866
|
-
|
|
916
|
+
const limit = pos.mainAxisRange;
|
|
917
|
+
const nearLimit = limit !== null && (pos.mainAxisNatural < limit[0] + ANCHOR_BAND || pos.mainAxisNatural > limit[1] - ANCHOR_BAND);
|
|
918
|
+
if (anchoringFailed.current || nearLimit || !supportsAnchoring()) {
|
|
919
|
+
if (anchoring.current) release(false);
|
|
867
920
|
writeFixed(pos);
|
|
868
921
|
return;
|
|
869
922
|
}
|
|
@@ -900,7 +953,7 @@ function useAnchoredPosition(anchor, floatingRef, { open, placement = "bottom-st
|
|
|
900
953
|
writeFixed(pos);
|
|
901
954
|
}
|
|
902
955
|
}
|
|
903
|
-
}, [anchor, floatingRef, release]);
|
|
956
|
+
}, [anchor, floatingRef, release, uncap]);
|
|
904
957
|
useIsomorphicLayoutEffect(() => {
|
|
905
958
|
if (!open) return;
|
|
906
959
|
session.current = true;
|
|
@@ -929,8 +982,20 @@ function useAnchoredPosition(anchor, floatingRef, { open, placement = "bottom-st
|
|
|
929
982
|
side.current = null;
|
|
930
983
|
anchoringFailed.current = false;
|
|
931
984
|
release(true);
|
|
985
|
+
uncap();
|
|
932
986
|
};
|
|
933
|
-
}, [open, reposition, anchor, floatingRef, release]);
|
|
987
|
+
}, [open, reposition, anchor, floatingRef, release, uncap]);
|
|
988
|
+
const watchAnchor = open && !!onAnchorHidden;
|
|
989
|
+
(0, import_react3.useEffect)(() => {
|
|
990
|
+
const anchorEl = resolveAnchor(anchor);
|
|
991
|
+
if (!watchAnchor || !anchorEl || typeof IntersectionObserver !== "function") return;
|
|
992
|
+
const observer = new IntersectionObserver((entries) => {
|
|
993
|
+
const latest = entries[entries.length - 1];
|
|
994
|
+
if (latest && !latest.isIntersecting) onAnchorHiddenRef.current?.();
|
|
995
|
+
});
|
|
996
|
+
observer.observe(anchorEl);
|
|
997
|
+
return () => observer.disconnect();
|
|
998
|
+
}, [watchAnchor, anchor]);
|
|
934
999
|
(0, import_react3.useEffect)(() => () => release(false), [release]);
|
|
935
1000
|
return reposition;
|
|
936
1001
|
}
|
|
@@ -952,16 +1017,22 @@ var settle = (el) => {
|
|
|
952
1017
|
el.removeAttribute(PLACING);
|
|
953
1018
|
};
|
|
954
1019
|
function Popover({
|
|
955
|
-
popover
|
|
1020
|
+
popover: popoverProp,
|
|
956
1021
|
anchor,
|
|
957
1022
|
placement = "bottom-start",
|
|
958
1023
|
offset = 6,
|
|
959
1024
|
closeWhenAnchorHidden = false,
|
|
960
1025
|
onAnchorHidden,
|
|
1026
|
+
capHeight = false,
|
|
1027
|
+
openOnHover = false,
|
|
961
1028
|
className,
|
|
962
1029
|
children,
|
|
963
1030
|
...props
|
|
964
1031
|
}) {
|
|
1032
|
+
const hover = !!openOnHover && !!anchor;
|
|
1033
|
+
const popover = popoverProp ?? (hover ? "manual" : "auto");
|
|
1034
|
+
const openDelay = typeof openOnHover === "object" ? openOnHover.openDelay ?? 300 : 300;
|
|
1035
|
+
const closeDelay = typeof openOnHover === "object" ? openOnHover.closeDelay ?? 150 : 150;
|
|
965
1036
|
const ref = (0, import_react4.useRef)(null);
|
|
966
1037
|
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
967
1038
|
const openRef = (0, import_react4.useRef)(false);
|
|
@@ -971,7 +1042,16 @@ function Popover({
|
|
|
971
1042
|
const reposition = useAnchoredPosition(anchor ?? null, ref, {
|
|
972
1043
|
open: open && !!anchor,
|
|
973
1044
|
placement,
|
|
974
|
-
offset
|
|
1045
|
+
offset,
|
|
1046
|
+
capHeight,
|
|
1047
|
+
onAnchorHidden: closeWhenAnchorHidden ? () => {
|
|
1048
|
+
const el = ref.current;
|
|
1049
|
+
if (!el || !isPopoverOpen(el)) return;
|
|
1050
|
+
onAnchorHiddenRef.current?.();
|
|
1051
|
+
const active = el.ownerDocument.activeElement;
|
|
1052
|
+
if (active && el.contains(active)) active.blur();
|
|
1053
|
+
el.hidePopover();
|
|
1054
|
+
} : void 0
|
|
975
1055
|
});
|
|
976
1056
|
(0, import_react4.useEffect)(() => {
|
|
977
1057
|
const el = ref.current;
|
|
@@ -1006,25 +1086,87 @@ function Popover({
|
|
|
1006
1086
|
el.removeAttribute(PLACING);
|
|
1007
1087
|
};
|
|
1008
1088
|
}, [anchor, reposition]);
|
|
1089
|
+
(0, import_react4.useEffect)(() => {
|
|
1090
|
+
const el = ref.current;
|
|
1091
|
+
const anchorEl = resolveAnchor(anchor);
|
|
1092
|
+
if (!hover || !el || !anchorEl) return;
|
|
1093
|
+
let timer;
|
|
1094
|
+
const inside = (node) => !!node && (anchorEl.contains(node) || el.contains(node));
|
|
1095
|
+
const stillWanted = () => {
|
|
1096
|
+
try {
|
|
1097
|
+
return anchorEl.matches(":hover") || el.matches(":hover") || inside(el.ownerDocument.activeElement);
|
|
1098
|
+
} catch {
|
|
1099
|
+
return false;
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
const show = (delay) => {
|
|
1103
|
+
window.clearTimeout(timer);
|
|
1104
|
+
timer = window.setTimeout(() => {
|
|
1105
|
+
if (!isPopoverOpen(el)) {
|
|
1106
|
+
try {
|
|
1107
|
+
el.showPopover?.();
|
|
1108
|
+
} catch {
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
}, delay);
|
|
1112
|
+
};
|
|
1113
|
+
const hide = (delay) => {
|
|
1114
|
+
window.clearTimeout(timer);
|
|
1115
|
+
timer = window.setTimeout(() => {
|
|
1116
|
+
if (isPopoverOpen(el) && !stillWanted()) {
|
|
1117
|
+
try {
|
|
1118
|
+
el.hidePopover?.();
|
|
1119
|
+
} catch {
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
}, delay);
|
|
1123
|
+
};
|
|
1124
|
+
const onEnter = (event) => {
|
|
1125
|
+
if (event.pointerType !== "touch") show(openDelay);
|
|
1126
|
+
};
|
|
1127
|
+
const onLeave = (event) => {
|
|
1128
|
+
if (event.pointerType !== "touch") hide(closeDelay);
|
|
1129
|
+
};
|
|
1130
|
+
const onFocusIn = () => show(0);
|
|
1131
|
+
const onFocusOut = (event) => {
|
|
1132
|
+
if (!inside(event.relatedTarget)) hide(closeDelay);
|
|
1133
|
+
};
|
|
1134
|
+
const onKeyDown = (event) => {
|
|
1135
|
+
if (event.key !== "Escape" || !isPopoverOpen(el)) return;
|
|
1136
|
+
window.clearTimeout(timer);
|
|
1137
|
+
const hadFocus = el.contains(el.ownerDocument.activeElement);
|
|
1138
|
+
try {
|
|
1139
|
+
el.hidePopover?.();
|
|
1140
|
+
} catch {
|
|
1141
|
+
}
|
|
1142
|
+
if (hadFocus) {
|
|
1143
|
+
anchorEl.removeEventListener("focusin", onFocusIn);
|
|
1144
|
+
anchorEl.focus();
|
|
1145
|
+
anchorEl.addEventListener("focusin", onFocusIn);
|
|
1146
|
+
}
|
|
1147
|
+
};
|
|
1148
|
+
for (const node of [anchorEl, el]) {
|
|
1149
|
+
node.addEventListener("pointerenter", onEnter);
|
|
1150
|
+
node.addEventListener("pointerleave", onLeave);
|
|
1151
|
+
node.addEventListener("focusout", onFocusOut);
|
|
1152
|
+
node.addEventListener("keydown", onKeyDown);
|
|
1153
|
+
}
|
|
1154
|
+
anchorEl.addEventListener("focusin", onFocusIn);
|
|
1155
|
+
return () => {
|
|
1156
|
+
window.clearTimeout(timer);
|
|
1157
|
+
for (const node of [anchorEl, el]) {
|
|
1158
|
+
node.removeEventListener("pointerenter", onEnter);
|
|
1159
|
+
node.removeEventListener("pointerleave", onLeave);
|
|
1160
|
+
node.removeEventListener("focusout", onFocusOut);
|
|
1161
|
+
node.removeEventListener("keydown", onKeyDown);
|
|
1162
|
+
}
|
|
1163
|
+
anchorEl.removeEventListener("focusin", onFocusIn);
|
|
1164
|
+
};
|
|
1165
|
+
}, [hover, anchor, openDelay, closeDelay]);
|
|
1009
1166
|
useIsomorphicLayoutEffect2(() => {
|
|
1010
1167
|
openRef.current = open;
|
|
1011
1168
|
if (open && ref.current) settle(ref.current);
|
|
1012
1169
|
}, [open]);
|
|
1013
|
-
(0, import_react4.useEffect)(() => {
|
|
1014
|
-
const el = ref.current;
|
|
1015
|
-
const anchorEl = resolveAnchor(anchor);
|
|
1016
|
-
if (!closeWhenAnchorHidden || !open || !el || !anchorEl || typeof IntersectionObserver !== "function") return;
|
|
1017
|
-
const observer = new IntersectionObserver((entries) => {
|
|
1018
|
-
const latest = entries[entries.length - 1];
|
|
1019
|
-
if (!latest || latest.isIntersecting || !isPopoverOpen(el)) return;
|
|
1020
|
-
onAnchorHiddenRef.current?.();
|
|
1021
|
-
const active = el.ownerDocument.activeElement;
|
|
1022
|
-
if (active && el.contains(active)) active.blur();
|
|
1023
|
-
el.hidePopover();
|
|
1024
|
-
});
|
|
1025
|
-
observer.observe(anchorEl);
|
|
1026
|
-
return () => observer.disconnect();
|
|
1027
|
-
}, [closeWhenAnchorHidden, open, anchor]);
|
|
1028
1170
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cx("uix-popover", className), ...popoverAttr, ...props, children });
|
|
1029
1171
|
}
|
|
1030
1172
|
|
package/dist/rich-text.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { E as EmojiPickerLabels, a as EmojiLocale } from './emoji-image-
|
|
4
|
-
export { l as emojiImageFileName } from './emoji-image-
|
|
5
|
-
import './overlay-position-
|
|
3
|
+
import { E as EmojiPickerLabels, a as EmojiLocale } from './emoji-image-DjCKpdwE.cjs';
|
|
4
|
+
export { l as emojiImageFileName } from './emoji-image-DjCKpdwE.cjs';
|
|
5
|
+
import './overlay-position-2Afke51l.cjs';
|
|
6
6
|
|
|
7
7
|
type RichTextFeatures = 'full' | 'comment' | 'template';
|
|
8
8
|
type RichTextHeadingLevel = 1 | 2 | 3;
|
|
@@ -20,9 +20,24 @@ interface RuleDefinition {
|
|
|
20
20
|
when: RuleGroup;
|
|
21
21
|
then: RuleAction[];
|
|
22
22
|
}
|
|
23
|
+
/** The built-in checks of `validateRuleDefinition`; each can be reworded or turned off (HAR-1618). */
|
|
24
|
+
type RuleCheck = 'duplicateId' | 'maxDepth' | 'emptyGroup' | 'missingField' | 'missingOperator' | 'noActions' | 'missingActionType';
|
|
23
25
|
interface RuleValidationIssue {
|
|
24
26
|
path: string;
|
|
25
27
|
message: string;
|
|
28
|
+
/** Which built-in check raised it. Absent on issues from the consumer's own `validate`. */
|
|
29
|
+
check?: RuleCheck;
|
|
30
|
+
}
|
|
31
|
+
/** The built-in messages. `{id}` is the duplicated id, `{max}` the depth limit. */
|
|
32
|
+
declare const DEFAULT_RULE_VALIDATION_MESSAGES: Record<RuleCheck, string>;
|
|
33
|
+
interface RuleValidationOptions {
|
|
34
|
+
/** Replace individual messages (a translation). */
|
|
35
|
+
messages?: Partial<Record<RuleCheck, string>>;
|
|
36
|
+
/**
|
|
37
|
+
* `false` turns a check off: `{ emptyGroup: false }` for a rule that may have no condition
|
|
38
|
+
* (a catch-all), `{ noActions: false, missingActionType: false }` for conditions without actions.
|
|
39
|
+
*/
|
|
40
|
+
checks?: Partial<Record<RuleCheck, boolean>>;
|
|
26
41
|
}
|
|
27
42
|
declare function isRuleGroup(node: RuleCondition | RuleGroup): node is RuleGroup;
|
|
28
43
|
declare function ruleDepth(group: RuleGroup): number;
|
|
@@ -31,11 +46,28 @@ declare function mapRuleGroup(group: RuleGroup, id: string, update: (node: RuleC
|
|
|
31
46
|
declare function appendRuleNode(group: RuleGroup, parentId: string, node: RuleCondition | RuleGroup, maxDepth?: number): RuleGroup;
|
|
32
47
|
declare function removeRuleNode(group: RuleGroup, id: string): RuleGroup;
|
|
33
48
|
declare function moveRuleNode(group: RuleGroup, id: string, direction: -1 | 1): RuleGroup;
|
|
34
|
-
|
|
49
|
+
/** Set `combinator` on a group and on every group nested in it. */
|
|
50
|
+
declare function setRuleCombinator(group: RuleGroup, combinator: 'and' | 'or'): RuleGroup;
|
|
51
|
+
declare function validateRuleDefinition(value: RuleDefinition, maxDepth?: number, options?: RuleValidationOptions): RuleValidationIssue[];
|
|
52
|
+
/** The words of the `summarizeRule` sentence. `{conditions}` and `{actions}` are filled in. */
|
|
53
|
+
interface RuleSummaryWords {
|
|
54
|
+
sentence: string;
|
|
55
|
+
/** For a rule with no actions to name (a conditions-only rule). */
|
|
56
|
+
sentenceConditionsOnly: string;
|
|
57
|
+
noConditions: string;
|
|
58
|
+
noActions: string;
|
|
59
|
+
and: string;
|
|
60
|
+
or: string;
|
|
61
|
+
}
|
|
62
|
+
declare const DEFAULT_RULE_SUMMARY_WORDS: RuleSummaryWords;
|
|
35
63
|
declare function summarizeRule(value: RuleDefinition, labels?: {
|
|
36
64
|
fields?: Record<string, string>;
|
|
37
65
|
operators?: Record<string, string>;
|
|
38
66
|
actions?: Record<string, string>;
|
|
67
|
+
/** Translate the sentence itself. Default: English. */
|
|
68
|
+
words?: Partial<RuleSummaryWords>;
|
|
69
|
+
/** Leave the actions out of the sentence. */
|
|
70
|
+
conditionsOnly?: boolean;
|
|
39
71
|
}): string;
|
|
40
72
|
|
|
41
|
-
export { type RuleAction, type RuleCondition, type RuleDefinition, type RuleGroup, type RuleValidationIssue, appendRuleNode, findRuleNodeDepth, isRuleGroup, mapRuleGroup, moveRuleNode, removeRuleNode, ruleDepth, summarizeRule, validateRuleDefinition };
|
|
73
|
+
export { DEFAULT_RULE_SUMMARY_WORDS, DEFAULT_RULE_VALIDATION_MESSAGES, type RuleAction, type RuleCheck, type RuleCondition, type RuleDefinition, type RuleGroup, type RuleSummaryWords, type RuleValidationIssue, type RuleValidationOptions, appendRuleNode, findRuleNodeDepth, isRuleGroup, mapRuleGroup, moveRuleNode, removeRuleNode, ruleDepth, setRuleCombinator, summarizeRule, validateRuleDefinition };
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
const fillLabel = (template, values) => template.replace(/\{(\w+)\}/g, (match, key) => Object.prototype.hasOwnProperty.call(values, key) ? String(values[key]) : match);
|
|
2
|
+
const DEFAULT_RULE_VALIDATION_MESSAGES = {
|
|
3
|
+
duplicateId: "Duplicate id \u201C{id}\u201D.",
|
|
4
|
+
maxDepth: "Nesting exceeds {max} levels.",
|
|
5
|
+
emptyGroup: "Add at least one condition.",
|
|
6
|
+
missingField: "Choose a field.",
|
|
7
|
+
missingOperator: "Choose an operator.",
|
|
8
|
+
noActions: "Add at least one action.",
|
|
9
|
+
missingActionType: "Choose an action."
|
|
10
|
+
};
|
|
1
11
|
function isRuleGroup(node) {
|
|
2
12
|
return "conditions" in node;
|
|
3
13
|
}
|
|
@@ -52,43 +62,68 @@ function moveRuleNode(group, id, direction) {
|
|
|
52
62
|
conditions: group.conditions.map((node) => isRuleGroup(node) ? moveRuleNode(node, id, direction) : node)
|
|
53
63
|
};
|
|
54
64
|
}
|
|
55
|
-
function
|
|
65
|
+
function setRuleCombinator(group, combinator) {
|
|
66
|
+
return {
|
|
67
|
+
...group,
|
|
68
|
+
combinator,
|
|
69
|
+
conditions: group.conditions.map((node) => isRuleGroup(node) ? setRuleCombinator(node, combinator) : node)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function validateRuleDefinition(value, maxDepth = 3, options = {}) {
|
|
56
73
|
const issues = [];
|
|
74
|
+
const messages = { ...DEFAULT_RULE_VALIDATION_MESSAGES, ...options.messages };
|
|
75
|
+
const report = (check, path, values = {}) => {
|
|
76
|
+
if (options.checks?.[check] === false) return;
|
|
77
|
+
issues.push({ path, message: fillLabel(messages[check], values), check });
|
|
78
|
+
};
|
|
57
79
|
const ids = /* @__PURE__ */ new Set();
|
|
58
80
|
const visit = (group, path, depth) => {
|
|
59
|
-
if (ids.has(group.id))
|
|
81
|
+
if (ids.has(group.id)) report("duplicateId", path, { id: group.id });
|
|
60
82
|
ids.add(group.id);
|
|
61
|
-
if (depth > maxDepth)
|
|
62
|
-
if (group.conditions.length === 0)
|
|
83
|
+
if (depth > maxDepth) report("maxDepth", path, { max: maxDepth });
|
|
84
|
+
if (group.conditions.length === 0) report("emptyGroup", path);
|
|
63
85
|
group.conditions.forEach((node, index) => {
|
|
64
86
|
const nodePath = `${path}.conditions[${index}]`;
|
|
65
|
-
if (ids.has(node.id))
|
|
87
|
+
if (ids.has(node.id)) report("duplicateId", nodePath, { id: node.id });
|
|
66
88
|
if (isRuleGroup(node)) visit(node, nodePath, depth + 1);
|
|
67
89
|
else {
|
|
68
90
|
ids.add(node.id);
|
|
69
|
-
if (!node.field)
|
|
70
|
-
if (!node.operator)
|
|
91
|
+
if (!node.field) report("missingField", nodePath);
|
|
92
|
+
if (!node.operator) report("missingOperator", nodePath);
|
|
71
93
|
}
|
|
72
94
|
});
|
|
73
95
|
};
|
|
74
96
|
visit(value.when, "when", 1);
|
|
75
|
-
if (value.then.length === 0)
|
|
97
|
+
if (value.then.length === 0) report("noActions", "then");
|
|
76
98
|
value.then.forEach((action, index) => {
|
|
77
|
-
if (ids.has(action.id))
|
|
99
|
+
if (ids.has(action.id)) report("duplicateId", `then[${index}]`, { id: action.id });
|
|
78
100
|
ids.add(action.id);
|
|
79
|
-
if (!action.type)
|
|
101
|
+
if (!action.type) report("missingActionType", `then[${index}]`);
|
|
80
102
|
});
|
|
81
103
|
return issues;
|
|
82
104
|
}
|
|
105
|
+
const DEFAULT_RULE_SUMMARY_WORDS = {
|
|
106
|
+
sentence: "When {conditions}, then {actions}.",
|
|
107
|
+
sentenceConditionsOnly: "When {conditions}.",
|
|
108
|
+
noConditions: "no conditions",
|
|
109
|
+
noActions: "no actions",
|
|
110
|
+
and: "AND",
|
|
111
|
+
or: "OR"
|
|
112
|
+
};
|
|
83
113
|
function summarizeRule(value, labels = {}) {
|
|
114
|
+
const words = { ...DEFAULT_RULE_SUMMARY_WORDS, ...labels.words };
|
|
84
115
|
const formatValue = (input) => input === void 0 ? "" : ` ${JSON.stringify(input)}`;
|
|
85
116
|
const formatGroup = (group) => group.conditions.map(
|
|
86
117
|
(node) => isRuleGroup(node) ? `(${formatGroup(node)})` : `${labels.fields?.[node.field] ?? node.field} ${labels.operators?.[node.operator] ?? node.operator}${formatValue(node.value)}`
|
|
87
|
-
).join(` ${group.combinator.
|
|
118
|
+
).join(` ${group.combinator === "or" ? words.or : words.and} `);
|
|
119
|
+
const conditions = formatGroup(value.when) || words.noConditions;
|
|
120
|
+
if (labels.conditionsOnly) return fillLabel(words.sentenceConditionsOnly, { conditions });
|
|
88
121
|
const actions = value.then.map((action) => labels.actions?.[action.type] ?? action.type).join(", ");
|
|
89
|
-
return
|
|
122
|
+
return fillLabel(words.sentence, { conditions, actions: actions || words.noActions });
|
|
90
123
|
}
|
|
91
124
|
export {
|
|
125
|
+
DEFAULT_RULE_SUMMARY_WORDS,
|
|
126
|
+
DEFAULT_RULE_VALIDATION_MESSAGES,
|
|
92
127
|
appendRuleNode,
|
|
93
128
|
findRuleNodeDepth,
|
|
94
129
|
isRuleGroup,
|
|
@@ -96,6 +131,7 @@ export {
|
|
|
96
131
|
moveRuleNode,
|
|
97
132
|
removeRuleNode,
|
|
98
133
|
ruleDepth,
|
|
134
|
+
setRuleCombinator,
|
|
99
135
|
summarizeRule,
|
|
100
136
|
validateRuleDefinition
|
|
101
137
|
};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { CalendarWeekday, ZonedDaySpan } from './calendar-model.js';
|
|
2
|
+
|
|
3
|
+
/** Which lane group a span is drawn in: windows sit above multi-day items, and neither takes a chip slot. */
|
|
4
|
+
type MonthSpanGroup = 'window' | 'item';
|
|
5
|
+
interface MonthSpanInput {
|
|
6
|
+
id: string;
|
|
7
|
+
/** Half-open `[start, end)` instants (ISO 8601, epoch ms or Date). */
|
|
8
|
+
start: string | number | Date;
|
|
9
|
+
end: string | number | Date;
|
|
10
|
+
/** Defaults to `'item'`. */
|
|
11
|
+
group?: MonthSpanGroup;
|
|
12
|
+
}
|
|
13
|
+
interface PlacedMonthSpan {
|
|
14
|
+
id: string;
|
|
15
|
+
group: MonthSpanGroup;
|
|
16
|
+
/** 0-based week row of the grid `days` the layout was computed for. */
|
|
17
|
+
weekRow: number;
|
|
18
|
+
/** 0-based lane inside its group. */
|
|
19
|
+
lane: number;
|
|
20
|
+
/** First and last column (0–6, inclusive) the span covers in this row. */
|
|
21
|
+
startCol: number;
|
|
22
|
+
endCol: number;
|
|
23
|
+
/** The span started in an earlier row (or before the grid). */
|
|
24
|
+
continuesBefore: boolean;
|
|
25
|
+
/** The span goes on in a later row (or past the grid). */
|
|
26
|
+
continuesAfter: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface MonthSpanLayout {
|
|
29
|
+
/** One entry per span per week row it got a lane in. Render exactly these; never re-pack. */
|
|
30
|
+
placed: PlacedMonthSpan[];
|
|
31
|
+
/** Per week row, the ids that got no lane, in input order (windows first). An id may name a window and an item. */
|
|
32
|
+
hiddenByRow: Record<number, string[]>;
|
|
33
|
+
/** Per week row with a hidden span, the first day (`YYYY-MM-DD`) a hidden span covers. */
|
|
34
|
+
firstHiddenDayByRow: Record<number, string>;
|
|
35
|
+
}
|
|
36
|
+
interface LayoutMonthSpansOptions {
|
|
37
|
+
/** The display zone that decides which days a span covers. */
|
|
38
|
+
timeZone: string;
|
|
39
|
+
/** When set, `days[0]` must fall on this weekday (a guard against a grid built for another week start). */
|
|
40
|
+
weekStartsOn?: CalendarWeekday;
|
|
41
|
+
/** Lanes per group (default 2). A number applies to both groups. */
|
|
42
|
+
laneCap?: number | Partial<Record<MonthSpanGroup, number>>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The calendar days an item covers in `timeZone`, end-exclusive (`end` is the first day not
|
|
46
|
+
* covered): a 22:00–00:00 item covers only its start day, a 23:00 → 02:00 item two days. A
|
|
47
|
+
* zero-length item covers the day of its start. Throws a `RangeError` when `end` is before
|
|
48
|
+
* `start`; it never swaps them.
|
|
49
|
+
*/
|
|
50
|
+
declare function itemDaySpan(start: string | number | Date, end: string | number | Date, timeZone: string): ZonedDaySpan;
|
|
51
|
+
/**
|
|
52
|
+
* The date keys a `SchedulingCalendar` grid shows, in order: six week rows for `'month'`
|
|
53
|
+
* (from the week holding the 1st), one for `'week'` (the week holding `anchorDate`). Pass the
|
|
54
|
+
* result to `layoutMonthSpans` so the layout and the rendered grid agree.
|
|
55
|
+
*/
|
|
56
|
+
declare function schedulingGridDays(anchorDate: string, view: 'month' | 'week', weekStartsOn?: CalendarWeekday): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Places multi-day spans as one continuous bar per week row. Spans are taken **in the order
|
|
59
|
+
* given** (the consumer's salience order): in each row and group, the first spans to ask get
|
|
60
|
+
* the lanes, the rest are listed in `hiddenByRow`. Windows and items pack in separate groups,
|
|
61
|
+
* each capped by `laneCap`. Day membership is the end-exclusive zoned span in `timeZone`
|
|
62
|
+
* (never a UTC date). `days` are the grid's date keys, a whole number of weeks.
|
|
63
|
+
*/
|
|
64
|
+
declare function layoutMonthSpans(spans: readonly MonthSpanInput[], days: readonly string[], options: LayoutMonthSpansOptions): MonthSpanLayout;
|
|
65
|
+
/** How far past its first local midnight an entry may run and still be drawn in the grid (operator decision E12). */
|
|
66
|
+
declare const TOP_LANE_CROSS_MIDNIGHT_MINUTES = 360;
|
|
67
|
+
interface TimeGridEntryInput {
|
|
68
|
+
id: string;
|
|
69
|
+
/** Half-open `[start, end)` instants (ISO 8601, epoch ms or Date). */
|
|
70
|
+
start: string | number | Date;
|
|
71
|
+
end: string | number | Date;
|
|
72
|
+
/** An entry with no time of day: always drawn in the top lane. */
|
|
73
|
+
allDay?: boolean;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Whether an entry is drawn in the top lane of the time grid instead of in the day columns:
|
|
77
|
+
* it is all-day, it is longer than one day (it ends after the same wall-clock time on the
|
|
78
|
+
* next day), or it runs more than `crossMidnightMinutes` past its first local midnight. A
|
|
79
|
+
* shorter midnight-crosser stays in the grid as a start segment and a continuation segment.
|
|
80
|
+
*/
|
|
81
|
+
declare function placesInTopLane(entry: Pick<TimeGridEntryInput, 'start' | 'end' | 'allDay'>, timeZone: string, options?: {
|
|
82
|
+
crossMidnightMinutes?: number;
|
|
83
|
+
}): boolean;
|
|
84
|
+
/** Which part of an entry a grid segment is: all of it, its first day, or the rest on the next day. */
|
|
85
|
+
type TimeGridPart = 'whole' | 'start' | 'continuation';
|
|
86
|
+
interface TimeGridSegment {
|
|
87
|
+
id: string;
|
|
88
|
+
part: TimeGridPart;
|
|
89
|
+
/** The segment, clipped to the day (epoch ms). */
|
|
90
|
+
start: number;
|
|
91
|
+
end: number;
|
|
92
|
+
/** Real hours from the start of the day to the segment. Multiply by the hour height. */
|
|
93
|
+
offsetHours: number;
|
|
94
|
+
/** The length of the segment in real hours. */
|
|
95
|
+
lengthHours: number;
|
|
96
|
+
/** 0-based lane inside its overlap cluster. */
|
|
97
|
+
lane: number;
|
|
98
|
+
/** Lanes its cluster uses: the segment is this fraction of the column wide. */
|
|
99
|
+
laneCount: number;
|
|
100
|
+
}
|
|
101
|
+
interface TimeGridDayLayout {
|
|
102
|
+
date: string;
|
|
103
|
+
/** The first instant of the day (epoch ms) and its length in real hours. */
|
|
104
|
+
dayStart: number;
|
|
105
|
+
dayHours: number;
|
|
106
|
+
/** One per entry part that got a lane, by start. */
|
|
107
|
+
segments: TimeGridSegment[];
|
|
108
|
+
/** Entries on this day that got no lane, by start. */
|
|
109
|
+
hidden: string[];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Lays one day column out: every entry that is not in the top lane and touches the day, clipped
|
|
113
|
+
* to it and packed into at most `maxLanes` lanes with `packLanes`. An entry that crosses
|
|
114
|
+
* midnight gives a `'start'` segment on its first day and a `'continuation'` on the next.
|
|
115
|
+
*/
|
|
116
|
+
declare function layoutTimeGridDay(entries: readonly TimeGridEntryInput[], date: string, timeZone: string, options?: {
|
|
117
|
+
maxLanes?: number;
|
|
118
|
+
crossMidnightMinutes?: number;
|
|
119
|
+
}): TimeGridDayLayout;
|
|
120
|
+
interface PlacedDaySpan {
|
|
121
|
+
id: string;
|
|
122
|
+
lane: number;
|
|
123
|
+
/** First and last column (inclusive) of `days` the span covers. */
|
|
124
|
+
startCol: number;
|
|
125
|
+
endCol: number;
|
|
126
|
+
continuesBefore: boolean;
|
|
127
|
+
continuesAfter: boolean;
|
|
128
|
+
}
|
|
129
|
+
interface DaySpanLayout {
|
|
130
|
+
placed: PlacedDaySpan[];
|
|
131
|
+
/** Ids that got no lane, in input order. */
|
|
132
|
+
hidden: string[];
|
|
133
|
+
/** The first day a hidden span covers, when there is one. */
|
|
134
|
+
firstHiddenDay?: string;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Places spans over one row of consecutive `days` (a week, or the single day of the Day
|
|
138
|
+
* view), in the order given, in at most `laneCap` lanes. Day membership is the end-exclusive
|
|
139
|
+
* zoned span. The time grid uses it for its top lane and its window strip.
|
|
140
|
+
*/
|
|
141
|
+
declare function layoutDaySpans(spans: readonly MonthSpanInput[], days: readonly string[], options: {
|
|
142
|
+
timeZone: string;
|
|
143
|
+
laneCap?: number;
|
|
144
|
+
}): DaySpanLayout;
|
|
145
|
+
/** A move the user asks for. The component never applies it: the consumer decides. */
|
|
146
|
+
interface MoveProposal {
|
|
147
|
+
/** ISO 8601 instants of the proposed window. */
|
|
148
|
+
start: string;
|
|
149
|
+
end: string;
|
|
150
|
+
/** `'gap_forward'` when the wall-clock time asked for does not exist that day and moved past the gap. */
|
|
151
|
+
adjusted: 'gap_forward' | null;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The window `[start, end)` moved by `minutes` of real time and then by `days` calendar days.
|
|
155
|
+
* A day move keeps the wall-clock start and end (`addZonedDays`), whatever the length of the
|
|
156
|
+
* days in between. Compute it from the original window every time, so that a time falling in
|
|
157
|
+
* a clock-change gap moves forward once, never twice. When a clock change on the target day
|
|
158
|
+
* would put the wall-clock end at or before the start (a window that sits on the skipped or
|
|
159
|
+
* repeated hour), the end keeps the real length of the window instead.
|
|
160
|
+
*/
|
|
161
|
+
declare function proposeMove(span: {
|
|
162
|
+
start: string | number | Date;
|
|
163
|
+
end: string | number | Date;
|
|
164
|
+
}, delta: {
|
|
165
|
+
days?: number;
|
|
166
|
+
minutes?: number;
|
|
167
|
+
}, timeZone: string): MoveProposal;
|
|
168
|
+
|
|
169
|
+
export { type DaySpanLayout, type LayoutMonthSpansOptions, type MonthSpanGroup, type MonthSpanInput, type MonthSpanLayout, type MoveProposal, type PlacedDaySpan, type PlacedMonthSpan, TOP_LANE_CROSS_MIDNIGHT_MINUTES, type TimeGridDayLayout, type TimeGridEntryInput, type TimeGridPart, type TimeGridSegment, itemDaySpan, layoutDaySpans, layoutMonthSpans, layoutTimeGridDay, placesInTopLane, proposeMove, schedulingGridDays };
|