@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.d.cts
CHANGED
|
@@ -1616,6 +1616,8 @@ interface SchedulerProps {
|
|
|
1616
1616
|
onSelectEvent?: (event: SchedulerEvent) => void;
|
|
1617
1617
|
/** Click the "New event" toolbar button. Omit to hide it. */
|
|
1618
1618
|
onNewEvent?: () => void;
|
|
1619
|
+
/** Called when `loadEvents` rejects. The Scheduler also shows a retry state. */
|
|
1620
|
+
onError?: (error: unknown) => void;
|
|
1619
1621
|
className?: string;
|
|
1620
1622
|
style?: React__default.CSSProperties;
|
|
1621
1623
|
}
|
|
@@ -1634,7 +1636,7 @@ interface SchedulerProps {
|
|
|
1634
1636
|
* onNewEvent={() => create()}
|
|
1635
1637
|
* />
|
|
1636
1638
|
*/
|
|
1637
|
-
declare function Scheduler({ events: controlledEvents, loadEvents, defaultView, defaultDate, weekStartsOn, dayHours, hourHeight, onSelectSlot, onSelectEvent, onNewEvent, className, style, }: SchedulerProps): react_jsx_runtime.JSX.Element;
|
|
1639
|
+
declare function Scheduler({ events: controlledEvents, loadEvents, defaultView, defaultDate, weekStartsOn, dayHours, hourHeight, onSelectSlot, onSelectEvent, onNewEvent, onError, className, style, }: SchedulerProps): react_jsx_runtime.JSX.Element;
|
|
1638
1640
|
|
|
1639
1641
|
interface CartLineItem {
|
|
1640
1642
|
id: string | number;
|
package/dist/index.d.ts
CHANGED
|
@@ -1616,6 +1616,8 @@ interface SchedulerProps {
|
|
|
1616
1616
|
onSelectEvent?: (event: SchedulerEvent) => void;
|
|
1617
1617
|
/** Click the "New event" toolbar button. Omit to hide it. */
|
|
1618
1618
|
onNewEvent?: () => void;
|
|
1619
|
+
/** Called when `loadEvents` rejects. The Scheduler also shows a retry state. */
|
|
1620
|
+
onError?: (error: unknown) => void;
|
|
1619
1621
|
className?: string;
|
|
1620
1622
|
style?: React__default.CSSProperties;
|
|
1621
1623
|
}
|
|
@@ -1634,7 +1636,7 @@ interface SchedulerProps {
|
|
|
1634
1636
|
* onNewEvent={() => create()}
|
|
1635
1637
|
* />
|
|
1636
1638
|
*/
|
|
1637
|
-
declare function Scheduler({ events: controlledEvents, loadEvents, defaultView, defaultDate, weekStartsOn, dayHours, hourHeight, onSelectSlot, onSelectEvent, onNewEvent, className, style, }: SchedulerProps): react_jsx_runtime.JSX.Element;
|
|
1639
|
+
declare function Scheduler({ events: controlledEvents, loadEvents, defaultView, defaultDate, weekStartsOn, dayHours, hourHeight, onSelectSlot, onSelectEvent, onNewEvent, onError, className, style, }: SchedulerProps): react_jsx_runtime.JSX.Element;
|
|
1638
1640
|
|
|
1639
1641
|
interface CartLineItem {
|
|
1640
1642
|
id: string | number;
|
package/dist/index.js
CHANGED
|
@@ -2910,6 +2910,7 @@ function Scheduler({
|
|
|
2910
2910
|
onSelectSlot,
|
|
2911
2911
|
onSelectEvent,
|
|
2912
2912
|
onNewEvent,
|
|
2913
|
+
onError,
|
|
2913
2914
|
className = "",
|
|
2914
2915
|
style
|
|
2915
2916
|
}) {
|
|
@@ -2918,9 +2919,11 @@ function Scheduler({
|
|
|
2918
2919
|
const [cursor, setCursor] = useState(() => defaultDate ?? /* @__PURE__ */ new Date());
|
|
2919
2920
|
const [loaded, setLoaded] = useState([]);
|
|
2920
2921
|
const [loading, setLoading] = useState(false);
|
|
2922
|
+
const [error, setError] = useState(null);
|
|
2923
|
+
const [reloadKey, setReloadKey] = useState(0);
|
|
2921
2924
|
const [dir, setDir] = useState(0);
|
|
2922
|
-
const
|
|
2923
|
-
|
|
2925
|
+
const cbRef = useRef({ loadEvents, onError });
|
|
2926
|
+
cbRef.current = { loadEvents, onError };
|
|
2924
2927
|
const range = useMemo(
|
|
2925
2928
|
() => view === "month" ? monthRange(cursor) : weekRange(cursor, weekStartsOn),
|
|
2926
2929
|
[view, cursor, weekStartsOn]
|
|
@@ -2928,21 +2931,26 @@ function Scheduler({
|
|
|
2928
2931
|
const fromKey = range.from.getTime();
|
|
2929
2932
|
const toKey = range.to.getTime();
|
|
2930
2933
|
useEffect(() => {
|
|
2931
|
-
const loader =
|
|
2934
|
+
const { loadEvents: loader, onError: onErr } = cbRef.current;
|
|
2932
2935
|
if (!loader) return;
|
|
2933
2936
|
let cancelled = false;
|
|
2934
2937
|
setLoading(true);
|
|
2938
|
+
setError(null);
|
|
2935
2939
|
Promise.resolve(loader({ from: new Date(fromKey), to: new Date(toKey) }, view)).then((evts) => {
|
|
2936
2940
|
if (!cancelled) setLoaded(evts);
|
|
2937
|
-
}).catch(() => {
|
|
2938
|
-
if (!cancelled)
|
|
2941
|
+
}).catch((err) => {
|
|
2942
|
+
if (!cancelled) {
|
|
2943
|
+
setError(err ?? new Error("Failed to load events"));
|
|
2944
|
+
onErr?.(err);
|
|
2945
|
+
}
|
|
2939
2946
|
}).finally(() => {
|
|
2940
2947
|
if (!cancelled) setLoading(false);
|
|
2941
2948
|
});
|
|
2942
2949
|
return () => {
|
|
2943
2950
|
cancelled = true;
|
|
2944
2951
|
};
|
|
2945
|
-
}, [fromKey, toKey, view]);
|
|
2952
|
+
}, [fromKey, toKey, view, reloadKey]);
|
|
2953
|
+
const retry = useCallback(() => setReloadKey((k) => k + 1), []);
|
|
2946
2954
|
const events = useMemo(
|
|
2947
2955
|
() => (controlledEvents ?? loaded).map(normalize),
|
|
2948
2956
|
[controlledEvents, loaded]
|
|
@@ -2995,7 +3003,7 @@ function Scheduler({
|
|
|
2995
3003
|
onNewEvent && /* @__PURE__ */ jsx(Button_default, { size: "sm", icon: /* @__PURE__ */ jsx(Plus, {}), content: "New event", onClick: onNewEvent })
|
|
2996
3004
|
] })
|
|
2997
3005
|
] }),
|
|
2998
|
-
/* @__PURE__ */ jsx("div", { className: "relative flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
3006
|
+
/* @__PURE__ */ jsx("div", { className: "relative flex-1 overflow-hidden", children: error ? /* @__PURE__ */ jsx(SchedulerError, { onRetry: retry }) : loadEvents && loading && events.length === 0 ? /* @__PURE__ */ jsx(SchedulerSkeleton, { view }) : /* @__PURE__ */ jsx(
|
|
2999
3007
|
motion.div,
|
|
3000
3008
|
{
|
|
3001
3009
|
initial: { opacity: 0, x: reduced ? 0 : dir * 24 },
|
|
@@ -3030,6 +3038,36 @@ function Scheduler({
|
|
|
3030
3038
|
}
|
|
3031
3039
|
);
|
|
3032
3040
|
}
|
|
3041
|
+
function SchedulerSkeleton({ view }) {
|
|
3042
|
+
const bar = "rounded bg-background animate-pulse";
|
|
3043
|
+
if (view === "week") {
|
|
3044
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col p-3", "aria-hidden": "true", children: [
|
|
3045
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3 grid gap-2", style: { gridTemplateColumns: "3.5rem repeat(7, 1fr)" }, children: [
|
|
3046
|
+
/* @__PURE__ */ jsx("span", {}),
|
|
3047
|
+
Array.from({ length: 7 }, (_, i) => /* @__PURE__ */ jsx("span", { className: `${bar} mx-auto h-8 w-8 rounded-full` }, i))
|
|
3048
|
+
] }),
|
|
3049
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col gap-3", children: Array.from({ length: 8 }, (_, i) => /* @__PURE__ */ jsx("span", { className: `${bar} h-6`, style: { width: `${60 + i * 13 % 35}%` } }, i)) })
|
|
3050
|
+
] });
|
|
3051
|
+
}
|
|
3052
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col p-3", "aria-hidden": "true", children: [
|
|
3053
|
+
/* @__PURE__ */ jsx("div", { className: "mb-3 grid grid-cols-7 gap-2", children: Array.from({ length: 7 }, (_, i) => /* @__PURE__ */ jsx("span", { className: `${bar} h-2.5` }, i)) }),
|
|
3054
|
+
/* @__PURE__ */ jsx("div", { className: "grid flex-1 grid-cols-7 grid-rows-5 gap-2", children: Array.from({ length: 35 }, (_, i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
3055
|
+
/* @__PURE__ */ jsx("span", { className: `${bar} h-5 w-5 rounded-full` }),
|
|
3056
|
+
i % 3 === 0 && /* @__PURE__ */ jsx("span", { className: `${bar} h-3` }),
|
|
3057
|
+
i % 5 === 0 && /* @__PURE__ */ jsx("span", { className: `${bar} h-3`, style: { width: "70%" } })
|
|
3058
|
+
] }, i)) })
|
|
3059
|
+
] });
|
|
3060
|
+
}
|
|
3061
|
+
function SchedulerError({ onRetry }) {
|
|
3062
|
+
return /* @__PURE__ */ jsxs("div", { role: "alert", className: "flex h-full flex-col items-center justify-center gap-3 p-8 text-center", children: [
|
|
3063
|
+
/* @__PURE__ */ 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__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-5 w-5", children: /* @__PURE__ */ 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" }) }) }),
|
|
3064
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
3065
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-foreground", children: "Couldn\u2019t load events" }),
|
|
3066
|
+
/* @__PURE__ */ jsx("div", { className: "mt-0.5 text-xs text-foreground-muted", children: "Something went wrong fetching this range." })
|
|
3067
|
+
] }),
|
|
3068
|
+
/* @__PURE__ */ jsx(Button_default, { size: "sm", variant: "secondary", content: "Retry", onClick: onRetry })
|
|
3069
|
+
] });
|
|
3070
|
+
}
|
|
3033
3071
|
function MonthYearPicker({ label, cursor, onPick }) {
|
|
3034
3072
|
const [open, setOpen] = useState(false);
|
|
3035
3073
|
const [viewYear, setViewYear] = useState(cursor.getFullYear());
|