@geomak/ui 6.26.0 → 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 +87 -52
- 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 +87 -52
- package/dist/index.js.map +1 -1
- package/dist/styles.css +36 -3
- 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());
|
|
@@ -5766,48 +5804,45 @@ function Pagination({
|
|
|
5766
5804
|
if (next) setPerPageKey(next.key);
|
|
5767
5805
|
}
|
|
5768
5806
|
}, [serverSide, options.perPage, picker]);
|
|
5769
|
-
const navBtn = (icon, disabled, onClick) => /* @__PURE__ */ jsxRuntime.jsx(IconButton, { disabled, onClick, icon });
|
|
5770
|
-
const chevronRight = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-
|
|
5771
|
-
const doubleChevronRight = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-
|
|
5772
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex
|
|
5773
|
-
|
|
5774
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
activePage === maxPage,
|
|
5792
|
-
() => onPageChange(maxPage)
|
|
5793
|
-
),
|
|
5794
|
-
options.withPicker && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5795
|
-
Dropdown,
|
|
5796
|
-
{
|
|
5797
|
-
style: { width: 80, position: "relative", bottom: 4 },
|
|
5798
|
-
hasSearch: false,
|
|
5799
|
-
items: picker,
|
|
5800
|
-
isMultiselect: false,
|
|
5801
|
-
value: displayPerPageKey,
|
|
5802
|
-
onChange: ({ target: { value } }) => {
|
|
5803
|
-
if (Array.isArray(value)) return;
|
|
5804
|
-
const numKey = typeof value === "number" ? value : Number(value);
|
|
5805
|
-
if (!serverSide) setPerPageKey(numKey);
|
|
5806
|
-
const opt = picker.find((o) => o.key === numKey);
|
|
5807
|
-
onPerPageChange(opt?.label ?? opt?.value ?? numKey);
|
|
5807
|
+
const navBtn = (icon, disabled, onClick, title) => /* @__PURE__ */ jsxRuntime.jsx(IconButton, { type: "bordered", size: "sm", disabled, onClick, icon, title });
|
|
5808
|
+
const chevronRight = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) });
|
|
5809
|
+
const doubleChevronRight = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M13 5l7 7-7 7M5 5l7 7-7 7" }) });
|
|
5810
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-end gap-x-4 gap-y-3 pt-3", children: [
|
|
5811
|
+
options.withPicker && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mr-auto flex items-center gap-2", children: [
|
|
5812
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap text-xs text-foreground-muted", children: "Rows per page" }),
|
|
5813
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5814
|
+
Dropdown,
|
|
5815
|
+
{
|
|
5816
|
+
size: "sm",
|
|
5817
|
+
style: { width: 76 },
|
|
5818
|
+
hasSearch: false,
|
|
5819
|
+
items: picker,
|
|
5820
|
+
isMultiselect: false,
|
|
5821
|
+
value: displayPerPageKey,
|
|
5822
|
+
onChange: ({ target: { value } }) => {
|
|
5823
|
+
if (Array.isArray(value)) return;
|
|
5824
|
+
const numKey = typeof value === "number" ? value : Number(value);
|
|
5825
|
+
if (!serverSide) setPerPageKey(numKey);
|
|
5826
|
+
const opt = picker.find((o) => o.key === numKey);
|
|
5827
|
+
onPerPageChange(opt?.label ?? opt?.value ?? numKey);
|
|
5828
|
+
}
|
|
5808
5829
|
}
|
|
5809
|
-
|
|
5810
|
-
)
|
|
5830
|
+
)
|
|
5831
|
+
] }),
|
|
5832
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
5833
|
+
navBtn(/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex rotate-180", children: doubleChevronRight }), activePage === 0, () => onPageChange(0), "First page"),
|
|
5834
|
+
navBtn(/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex rotate-180", children: chevronRight }), activePage === 0, () => activePage > 0 && onPageChange(activePage - 1), "Previous page"),
|
|
5835
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-2 text-sm tabular-nums text-foreground-secondary select-none", children: [
|
|
5836
|
+
activePage + 1,
|
|
5837
|
+
" ",
|
|
5838
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-foreground-muted", children: [
|
|
5839
|
+
"/ ",
|
|
5840
|
+
maxPage + 1
|
|
5841
|
+
] })
|
|
5842
|
+
] }),
|
|
5843
|
+
navBtn(chevronRight, activePage === maxPage, () => activePage < maxPage && onPageChange(activePage + 1), "Next page"),
|
|
5844
|
+
navBtn(doubleChevronRight, activePage === maxPage, () => onPageChange(maxPage), "Last page")
|
|
5845
|
+
] })
|
|
5811
5846
|
] });
|
|
5812
5847
|
}
|
|
5813
5848
|
function Table({
|
|
@@ -8535,7 +8570,7 @@ function OtpInput({
|
|
|
8535
8570
|
emit(valid.join(""));
|
|
8536
8571
|
focusBox(valid.length);
|
|
8537
8572
|
};
|
|
8538
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
8573
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
8539
8574
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8540
8575
|
"input",
|
|
8541
8576
|
{
|
|
@@ -8946,9 +8981,9 @@ function DateRangePicker({
|
|
|
8946
8981
|
{
|
|
8947
8982
|
align: "start",
|
|
8948
8983
|
sideOffset: 4,
|
|
8949
|
-
className: "bg-surface text-foreground border border-border rounded-lg shadow-md z-50 p-3 flex gap-3 animate-in fade-in-0 zoom-in-95",
|
|
8984
|
+
className: "bg-surface text-foreground border border-border rounded-lg shadow-md z-50 p-3 flex flex-col gap-3 sm:flex-row max-w-[calc(100vw-1rem)] max-h-[calc(100vh-2rem)] overflow-auto animate-in fade-in-0 zoom-in-95",
|
|
8950
8985
|
children: [
|
|
8951
|
-
presets && presets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-1 pr-3 border-r border-border
|
|
8986
|
+
presets && presets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-1 min-w-[120px] sm:pr-3 sm:border-r sm:border-border", children: presets.map((p) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
8952
8987
|
"button",
|
|
8953
8988
|
{
|
|
8954
8989
|
type: "button",
|
|
@@ -8961,7 +8996,7 @@ function DateRangePicker({
|
|
|
8961
8996
|
},
|
|
8962
8997
|
p.label
|
|
8963
8998
|
)) }),
|
|
8964
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4", children: [
|
|
8999
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 sm:flex-row", children: [
|
|
8965
9000
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
8966
9001
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8967
9002
|
"button",
|