@geomak/ui 6.26.1 → 6.27.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/dist/index.cjs +45 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +45 -7
- package/dist/index.js.map +1 -1
- package/dist/styles.css +8 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2947,6 +2947,7 @@ function Scheduler({
|
|
|
2947
2947
|
onSelectSlot,
|
|
2948
2948
|
onSelectEvent,
|
|
2949
2949
|
onNewEvent,
|
|
2950
|
+
onError,
|
|
2950
2951
|
className = "",
|
|
2951
2952
|
style
|
|
2952
2953
|
}) {
|
|
@@ -2955,9 +2956,11 @@ function Scheduler({
|
|
|
2955
2956
|
const [cursor, setCursor] = React29.useState(() => defaultDate ?? /* @__PURE__ */ new Date());
|
|
2956
2957
|
const [loaded, setLoaded] = React29.useState([]);
|
|
2957
2958
|
const [loading, setLoading] = React29.useState(false);
|
|
2959
|
+
const [error, setError] = React29.useState(null);
|
|
2960
|
+
const [reloadKey, setReloadKey] = React29.useState(0);
|
|
2958
2961
|
const [dir, setDir] = React29.useState(0);
|
|
2959
|
-
const
|
|
2960
|
-
|
|
2962
|
+
const cbRef = React29.useRef({ loadEvents, onError });
|
|
2963
|
+
cbRef.current = { loadEvents, onError };
|
|
2961
2964
|
const range = React29.useMemo(
|
|
2962
2965
|
() => view === "month" ? monthRange(cursor) : weekRange(cursor, weekStartsOn),
|
|
2963
2966
|
[view, cursor, weekStartsOn]
|
|
@@ -2965,21 +2968,26 @@ function Scheduler({
|
|
|
2965
2968
|
const fromKey = range.from.getTime();
|
|
2966
2969
|
const toKey = range.to.getTime();
|
|
2967
2970
|
React29.useEffect(() => {
|
|
2968
|
-
const loader =
|
|
2971
|
+
const { loadEvents: loader, onError: onErr } = cbRef.current;
|
|
2969
2972
|
if (!loader) return;
|
|
2970
2973
|
let cancelled = false;
|
|
2971
2974
|
setLoading(true);
|
|
2975
|
+
setError(null);
|
|
2972
2976
|
Promise.resolve(loader({ from: new Date(fromKey), to: new Date(toKey) }, view)).then((evts) => {
|
|
2973
2977
|
if (!cancelled) setLoaded(evts);
|
|
2974
|
-
}).catch(() => {
|
|
2975
|
-
if (!cancelled)
|
|
2978
|
+
}).catch((err) => {
|
|
2979
|
+
if (!cancelled) {
|
|
2980
|
+
setError(err ?? new Error("Failed to load events"));
|
|
2981
|
+
onErr?.(err);
|
|
2982
|
+
}
|
|
2976
2983
|
}).finally(() => {
|
|
2977
2984
|
if (!cancelled) setLoading(false);
|
|
2978
2985
|
});
|
|
2979
2986
|
return () => {
|
|
2980
2987
|
cancelled = true;
|
|
2981
2988
|
};
|
|
2982
|
-
}, [fromKey, toKey, view]);
|
|
2989
|
+
}, [fromKey, toKey, view, reloadKey]);
|
|
2990
|
+
const retry = React29.useCallback(() => setReloadKey((k) => k + 1), []);
|
|
2983
2991
|
const events = React29.useMemo(
|
|
2984
2992
|
() => (controlledEvents ?? loaded).map(normalize),
|
|
2985
2993
|
[controlledEvents, loaded]
|
|
@@ -3032,7 +3040,7 @@ function Scheduler({
|
|
|
3032
3040
|
onNewEvent && /* @__PURE__ */ jsxRuntime.jsx(Button_default, { size: "sm", icon: /* @__PURE__ */ jsxRuntime.jsx(Plus, {}), content: "New event", onClick: onNewEvent })
|
|
3033
3041
|
] })
|
|
3034
3042
|
] }),
|
|
3035
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3043
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex-1 overflow-hidden", children: error ? /* @__PURE__ */ jsxRuntime.jsx(SchedulerError, { onRetry: retry }) : loadEvents && loading && events.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(SchedulerSkeleton, { view }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3036
3044
|
framerMotion.motion.div,
|
|
3037
3045
|
{
|
|
3038
3046
|
initial: { opacity: 0, x: reduced ? 0 : dir * 24 },
|
|
@@ -3067,6 +3075,36 @@ function Scheduler({
|
|
|
3067
3075
|
}
|
|
3068
3076
|
);
|
|
3069
3077
|
}
|
|
3078
|
+
function SchedulerSkeleton({ view }) {
|
|
3079
|
+
const bar = "rounded bg-background animate-pulse";
|
|
3080
|
+
if (view === "week") {
|
|
3081
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col p-3", "aria-hidden": "true", children: [
|
|
3082
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-3 grid gap-2", style: { gridTemplateColumns: "3.5rem repeat(7, 1fr)" }, children: [
|
|
3083
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
3084
|
+
Array.from({ length: 7 }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} mx-auto h-8 w-8 rounded-full` }, i))
|
|
3085
|
+
] }),
|
|
3086
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col gap-3", children: Array.from({ length: 8 }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} h-6`, style: { width: `${60 + i * 13 % 35}%` } }, i)) })
|
|
3087
|
+
] });
|
|
3088
|
+
}
|
|
3089
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col p-3", "aria-hidden": "true", children: [
|
|
3090
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-3 grid grid-cols-7 gap-2", children: Array.from({ length: 7 }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} h-2.5` }, i)) }),
|
|
3091
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid flex-1 grid-cols-7 grid-rows-5 gap-2", children: Array.from({ length: 35 }, (_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
3092
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} h-5 w-5 rounded-full` }),
|
|
3093
|
+
i % 3 === 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} h-3` }),
|
|
3094
|
+
i % 5 === 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${bar} h-3`, style: { width: "70%" } })
|
|
3095
|
+
] }, i)) })
|
|
3096
|
+
] });
|
|
3097
|
+
}
|
|
3098
|
+
function SchedulerError({ onRetry }) {
|
|
3099
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "alert", className: "flex h-full flex-col items-center justify-center gap-3 p-8 text-center", children: [
|
|
3100
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-10 w-10 items-center justify-center rounded-full text-status-error", style: { backgroundColor: "color-mix(in oklab, var(--color-error) 12%, var(--color-surface))" }, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-5 w-5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v4m0 4h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h16.94a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z" }) }) }),
|
|
3101
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3102
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-semibold text-foreground", children: "Couldn\u2019t load events" }),
|
|
3103
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 text-xs text-foreground-muted", children: "Something went wrong fetching this range." })
|
|
3104
|
+
] }),
|
|
3105
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button_default, { size: "sm", variant: "secondary", content: "Retry", onClick: onRetry })
|
|
3106
|
+
] });
|
|
3107
|
+
}
|
|
3070
3108
|
function MonthYearPicker({ label, cursor, onPick }) {
|
|
3071
3109
|
const [open, setOpen] = React29.useState(false);
|
|
3072
3110
|
const [viewYear, setViewYear] = React29.useState(cursor.getFullYear());
|