@pos-360/horizon 0.28.1 → 0.29.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/{chunk-QJMRQP66.mjs → chunk-PXBJSQUY.mjs} +480 -13
- package/dist/chunk-PXBJSQUY.mjs.map +1 -0
- package/dist/{chunk-JI2LA5FH.js → chunk-TINY76JI.js} +480 -11
- package/dist/chunk-TINY76JI.js.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +112 -104
- package/dist/index.mjs +1 -1
- package/dist/primitives.d.mts +171 -119
- package/dist/primitives.d.ts +171 -119
- package/dist/primitives.js +112 -104
- package/dist/primitives.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-JI2LA5FH.js.map +0 -1
- package/dist/chunk-QJMRQP66.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cn, Label, Tooltip, mergeRefs } from './chunk-EZDGMHS7.mjs';
|
|
1
|
+
import { cn, Label, Tooltip, Text, mergeRefs } from './chunk-EZDGMHS7.mjs';
|
|
2
2
|
import * as React10 from 'react';
|
|
3
3
|
import { useState, useEffect, useCallback } from 'react';
|
|
4
4
|
import { Slot } from '@radix-ui/react-slot';
|
|
@@ -2122,16 +2122,16 @@ function TimeInput({
|
|
|
2122
2122
|
setEditValue(raw);
|
|
2123
2123
|
return;
|
|
2124
2124
|
}
|
|
2125
|
+
if (raw.length === 1) {
|
|
2126
|
+
setEditValue(raw);
|
|
2127
|
+
return;
|
|
2128
|
+
}
|
|
2125
2129
|
const parsed = parseInt(raw, 10);
|
|
2126
2130
|
const clamped = clamp(parsed, min, max);
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
onChange(clamped);
|
|
2132
|
-
setEditValue(null);
|
|
2133
|
-
onComplete?.();
|
|
2134
|
-
}
|
|
2131
|
+
committedRef.current = true;
|
|
2132
|
+
onChange(clamped);
|
|
2133
|
+
setEditValue(null);
|
|
2134
|
+
onComplete?.();
|
|
2135
2135
|
};
|
|
2136
2136
|
const commit = () => {
|
|
2137
2137
|
if (committedRef.current) {
|
|
@@ -2250,7 +2250,7 @@ function TimeField({
|
|
|
2250
2250
|
const focusMinute = () => {
|
|
2251
2251
|
minuteInputRef.current?.focus();
|
|
2252
2252
|
};
|
|
2253
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2253
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 justify-between", children: [
|
|
2254
2254
|
/* @__PURE__ */ jsx(
|
|
2255
2255
|
"span",
|
|
2256
2256
|
{
|
|
@@ -2309,6 +2309,80 @@ function TimeField({
|
|
|
2309
2309
|
] })
|
|
2310
2310
|
] });
|
|
2311
2311
|
}
|
|
2312
|
+
function TimePickerColumn({ value, onChange, disabled = false }) {
|
|
2313
|
+
const toHourRef = React10.useRef(null);
|
|
2314
|
+
const fromSet = isTimeSet(value.from);
|
|
2315
|
+
const toSet = isTimeSet(value.to);
|
|
2316
|
+
const bothSet = fromSet && toSet;
|
|
2317
|
+
const fromMinutes = (value.from.hour ?? 0) * 60 + (value.from.minute ?? 0);
|
|
2318
|
+
const toMinutes = (value.to.hour ?? 0) * 60 + (value.to.minute ?? 0);
|
|
2319
|
+
const bothEqual = fromMinutes === toMinutes;
|
|
2320
|
+
const isOvernight = bothSet && toMinutes < fromMinutes;
|
|
2321
|
+
const durationMinutes = bothSet && !bothEqual ? isOvernight ? 24 * 60 - fromMinutes + toMinutes : toMinutes - fromMinutes : 0;
|
|
2322
|
+
const durationHours = Math.floor(durationMinutes / 60);
|
|
2323
|
+
const durationRemaining = durationMinutes % 60;
|
|
2324
|
+
const showDuration = bothSet && !bothEqual;
|
|
2325
|
+
const durationLabel = durationRemaining > 0 ? `${durationHours}h ${durationRemaining}m window${isOvernight ? " (overnight)" : ""}` : `${durationHours}h window${isOvernight ? " (overnight)" : ""}`;
|
|
2326
|
+
return /* @__PURE__ */ jsxs(
|
|
2327
|
+
"div",
|
|
2328
|
+
{
|
|
2329
|
+
className: cn(
|
|
2330
|
+
"flex flex-col px-2 pt-2 pb-2 gap-1",
|
|
2331
|
+
"border-t border-gray-100 dark:border-neutral-700"
|
|
2332
|
+
),
|
|
2333
|
+
children: [
|
|
2334
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2335
|
+
/* @__PURE__ */ jsx(
|
|
2336
|
+
Clock,
|
|
2337
|
+
{
|
|
2338
|
+
className: cn(
|
|
2339
|
+
"w-4 h-4 shrink-0",
|
|
2340
|
+
disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
|
|
2341
|
+
)
|
|
2342
|
+
}
|
|
2343
|
+
),
|
|
2344
|
+
/* @__PURE__ */ jsx(
|
|
2345
|
+
"span",
|
|
2346
|
+
{
|
|
2347
|
+
className: cn(
|
|
2348
|
+
"text-xs font-semibold uppercase tracking-wider",
|
|
2349
|
+
disabled ? "text-gray-300 dark:text-gray-600" : "text-gray-400 dark:text-gray-500"
|
|
2350
|
+
),
|
|
2351
|
+
children: "Time"
|
|
2352
|
+
}
|
|
2353
|
+
),
|
|
2354
|
+
/* @__PURE__ */ jsx("span", { className: "text-[9px] font-medium text-gray-400 dark:text-gray-600 tracking-wide", children: "(Optional)" })
|
|
2355
|
+
] }),
|
|
2356
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 pl-6", children: [
|
|
2357
|
+
/* @__PURE__ */ jsx(
|
|
2358
|
+
TimeField,
|
|
2359
|
+
{
|
|
2360
|
+
label: "From",
|
|
2361
|
+
value: value.from,
|
|
2362
|
+
onChange: (from) => onChange({ ...value, from }),
|
|
2363
|
+
onMinuteComplete: () => toHourRef.current?.focus(),
|
|
2364
|
+
disabled
|
|
2365
|
+
}
|
|
2366
|
+
),
|
|
2367
|
+
/* @__PURE__ */ jsx(
|
|
2368
|
+
TimeField,
|
|
2369
|
+
{
|
|
2370
|
+
label: "To",
|
|
2371
|
+
value: value.to,
|
|
2372
|
+
onChange: (to) => onChange({ ...value, to }),
|
|
2373
|
+
hourRef: toHourRef,
|
|
2374
|
+
disabled
|
|
2375
|
+
}
|
|
2376
|
+
),
|
|
2377
|
+
showDuration && /* @__PURE__ */ jsx("span", { className: cn(
|
|
2378
|
+
"text-[10px] font-medium",
|
|
2379
|
+
isOvernight ? "text-amber-500 dark:text-amber-400" : "text-gray-400 dark:text-gray-500"
|
|
2380
|
+
), children: durationLabel })
|
|
2381
|
+
] })
|
|
2382
|
+
]
|
|
2383
|
+
}
|
|
2384
|
+
);
|
|
2385
|
+
}
|
|
2312
2386
|
function TimePickerRow({ value, onChange, disabled = false }) {
|
|
2313
2387
|
const toHourRef = React10.useRef(null);
|
|
2314
2388
|
const fromSet = isTimeSet(value.from);
|
|
@@ -2775,6 +2849,399 @@ function DateRangePicker({
|
|
|
2775
2849
|
] }) })
|
|
2776
2850
|
] });
|
|
2777
2851
|
}
|
|
2852
|
+
function formatTime2(tv) {
|
|
2853
|
+
if (tv.hour === null || tv.minute === null) return "";
|
|
2854
|
+
const period = tv.hour >= 12 ? "PM" : "AM";
|
|
2855
|
+
const h = tv.hour % 12 || 12;
|
|
2856
|
+
const m = tv.minute.toString().padStart(2, "0");
|
|
2857
|
+
return `${h}:${m} ${period}`;
|
|
2858
|
+
}
|
|
2859
|
+
function formatDateWithTime(date, dateFmt, time) {
|
|
2860
|
+
const dateStr = format(date, dateFmt);
|
|
2861
|
+
const timeStr = time ? formatTime2(time) : "";
|
|
2862
|
+
return timeStr ? `${dateStr}, ${timeStr}` : dateStr;
|
|
2863
|
+
}
|
|
2864
|
+
function formatDateRange2(range, placeholder, time) {
|
|
2865
|
+
if (!range?.from) return placeholder;
|
|
2866
|
+
const hasTime = time && time.from.hour !== null && time.to.hour !== null;
|
|
2867
|
+
if (!range.to || isSameDay(range.from, range.to)) {
|
|
2868
|
+
return formatDateWithTime(range.from, "MMMM d, yyyy", hasTime ? time.from : void 0);
|
|
2869
|
+
}
|
|
2870
|
+
const sameYear = range.from.getFullYear() === range.to.getFullYear();
|
|
2871
|
+
const fromFmt = sameYear ? "MMMM d" : "MMMM d, yyyy";
|
|
2872
|
+
const fromStr = formatDateWithTime(range.from, fromFmt, hasTime ? time.from : void 0);
|
|
2873
|
+
const toStr = formatDateWithTime(range.to, "MMMM d, yyyy", hasTime ? time.to : void 0);
|
|
2874
|
+
return `${fromStr} \u2013 ${toStr}`;
|
|
2875
|
+
}
|
|
2876
|
+
function DateRangePickerMobile({
|
|
2877
|
+
label,
|
|
2878
|
+
value,
|
|
2879
|
+
onChange,
|
|
2880
|
+
presets = DEFAULT_PRESETS,
|
|
2881
|
+
presetSections,
|
|
2882
|
+
placeholder = "Select date range",
|
|
2883
|
+
disabled = false,
|
|
2884
|
+
className,
|
|
2885
|
+
showTimePicker = false,
|
|
2886
|
+
timeValue,
|
|
2887
|
+
onTimeChange
|
|
2888
|
+
}) {
|
|
2889
|
+
const [open, setOpen] = React10.useState(false);
|
|
2890
|
+
const [internalRange, setInternalRange] = React10.useState({
|
|
2891
|
+
from: void 0,
|
|
2892
|
+
to: void 0
|
|
2893
|
+
});
|
|
2894
|
+
const [draft, setDraft] = React10.useState({
|
|
2895
|
+
from: void 0,
|
|
2896
|
+
to: void 0
|
|
2897
|
+
});
|
|
2898
|
+
const [hoverDate, setHoverDate] = React10.useState();
|
|
2899
|
+
const [viewMonth, setViewMonth] = React10.useState(
|
|
2900
|
+
() => startOfMonth(value?.from ?? /* @__PURE__ */ new Date())
|
|
2901
|
+
);
|
|
2902
|
+
const [activePreset, setActivePreset] = React10.useState();
|
|
2903
|
+
const [internalTime, setInternalTime] = React10.useState(DEFAULT_TIME_RANGE);
|
|
2904
|
+
const committedRange = value ?? internalRange;
|
|
2905
|
+
const currentTime = timeValue ?? internalTime;
|
|
2906
|
+
const handleTimeChange = (newTime) => {
|
|
2907
|
+
if (onTimeChange) onTimeChange(newTime);
|
|
2908
|
+
else setInternalTime(newTime);
|
|
2909
|
+
};
|
|
2910
|
+
const timeVisible = !!(draft.from && draft.to);
|
|
2911
|
+
const handleOpenChange = (newOpen) => {
|
|
2912
|
+
if (newOpen) {
|
|
2913
|
+
setDraft(committedRange);
|
|
2914
|
+
if (committedRange.from) setViewMonth(startOfMonth(committedRange.from));
|
|
2915
|
+
if (!onTimeChange) setInternalTime(currentTime);
|
|
2916
|
+
}
|
|
2917
|
+
setOpen(newOpen);
|
|
2918
|
+
};
|
|
2919
|
+
const handleDayClick = (date) => {
|
|
2920
|
+
const { from, to } = draft;
|
|
2921
|
+
if (!from || from && to) {
|
|
2922
|
+
setDraft({ from: date, to: void 0 });
|
|
2923
|
+
setActivePreset(void 0);
|
|
2924
|
+
return;
|
|
2925
|
+
}
|
|
2926
|
+
const [start, end] = isBefore(from, date) ? [from, date] : [date, from];
|
|
2927
|
+
setDraft({ from: start, to: end });
|
|
2928
|
+
setHoverDate(void 0);
|
|
2929
|
+
};
|
|
2930
|
+
const handlePreset = (preset) => {
|
|
2931
|
+
const newRange = preset.getRange();
|
|
2932
|
+
if (showTimePicker) {
|
|
2933
|
+
setDraft(newRange);
|
|
2934
|
+
setActivePreset(preset.label);
|
|
2935
|
+
if (newRange.from) setViewMonth(startOfMonth(newRange.from));
|
|
2936
|
+
} else {
|
|
2937
|
+
if (onChange) onChange(newRange);
|
|
2938
|
+
else setInternalRange(newRange);
|
|
2939
|
+
setActivePreset(preset.label);
|
|
2940
|
+
if (newRange.from) setViewMonth(startOfMonth(newRange.from));
|
|
2941
|
+
setOpen(false);
|
|
2942
|
+
}
|
|
2943
|
+
};
|
|
2944
|
+
const handleApply = () => {
|
|
2945
|
+
if (draft.from && !draft.to) return;
|
|
2946
|
+
const newRange = draft.from && draft.to ? draft : void 0;
|
|
2947
|
+
if (onChange) onChange(newRange);
|
|
2948
|
+
else setInternalRange(newRange ?? { from: void 0, to: void 0 });
|
|
2949
|
+
setOpen(false);
|
|
2950
|
+
};
|
|
2951
|
+
const handleClear = () => {
|
|
2952
|
+
setDraft({ from: void 0, to: void 0 });
|
|
2953
|
+
setActivePreset(void 0);
|
|
2954
|
+
if (showTimePicker) handleTimeChange(DEFAULT_TIME_RANGE);
|
|
2955
|
+
};
|
|
2956
|
+
const canClear = !!(draft.from || committedRange.from);
|
|
2957
|
+
const canApply = !(draft.from && !draft.to) && !!(draft.from || committedRange.from);
|
|
2958
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-1.5", className), children: [
|
|
2959
|
+
label && /* @__PURE__ */ jsx(Label, { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: label }),
|
|
2960
|
+
/* @__PURE__ */ jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
|
|
2961
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
2962
|
+
"button",
|
|
2963
|
+
{
|
|
2964
|
+
disabled,
|
|
2965
|
+
className: cn(
|
|
2966
|
+
"inline-flex w-full items-center gap-2 rounded-md border border-gray-300 bg-white px-3 py-2 text-sm shadow-sm transition-colors",
|
|
2967
|
+
"hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2",
|
|
2968
|
+
"dark:border-neutral-600 dark:bg-neutral-800 dark:hover:bg-neutral-700",
|
|
2969
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
2970
|
+
committedRange.from ? "text-gray-900 dark:text-gray-100" : "text-gray-400 dark:text-gray-500"
|
|
2971
|
+
),
|
|
2972
|
+
children: [
|
|
2973
|
+
/* @__PURE__ */ jsx(CalendarIcon, { className: "w-4 h-4 shrink-0 text-gray-400 dark:text-gray-500" }),
|
|
2974
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: formatDateRange2(
|
|
2975
|
+
committedRange,
|
|
2976
|
+
placeholder,
|
|
2977
|
+
showTimePicker ? currentTime : void 0
|
|
2978
|
+
) })
|
|
2979
|
+
]
|
|
2980
|
+
}
|
|
2981
|
+
) }),
|
|
2982
|
+
/* @__PURE__ */ jsx(PopoverContent, { align: "center", className: "w-auto p-0 overflow-hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex divide-x divide-gray-100 dark:divide-neutral-700", children: [
|
|
2983
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col p-2 gap-0.5 min-w-[110px] max-h-[360px] overflow-y-auto", children: (presetSections ?? [{ title: "Presets", options: presets }]).map(
|
|
2984
|
+
(section, si) => /* @__PURE__ */ jsxs(React10.Fragment, { children: [
|
|
2985
|
+
si > 0 && /* @__PURE__ */ jsx("div", { className: "my-2 border-t border-gray-100 dark:border-neutral-700" }),
|
|
2986
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider mb-1 px-2", children: section.title }),
|
|
2987
|
+
section.options.map((preset) => /* @__PURE__ */ jsx(
|
|
2988
|
+
"button",
|
|
2989
|
+
{
|
|
2990
|
+
onClick: () => handlePreset(preset),
|
|
2991
|
+
className: cn(
|
|
2992
|
+
"w-full text-left px-2 py-1.5 rounded-md text-sm transition-colors",
|
|
2993
|
+
activePreset === preset.label ? "bg-blue-50 text-blue-600 font-medium dark:bg-blue-950/50 dark:text-blue-400" : "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700"
|
|
2994
|
+
),
|
|
2995
|
+
children: preset.label
|
|
2996
|
+
},
|
|
2997
|
+
preset.label
|
|
2998
|
+
))
|
|
2999
|
+
] }, section.title)
|
|
3000
|
+
) }),
|
|
3001
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
3002
|
+
/* @__PURE__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsx(
|
|
3003
|
+
CalendarMonth,
|
|
3004
|
+
{
|
|
3005
|
+
month: viewMonth,
|
|
3006
|
+
range: draft,
|
|
3007
|
+
hoverDate,
|
|
3008
|
+
onDayClick: handleDayClick,
|
|
3009
|
+
onDayHover: setHoverDate,
|
|
3010
|
+
onPrevMonth: () => setViewMonth(subMonths(viewMonth, 1)),
|
|
3011
|
+
onNextMonth: () => setViewMonth(addMonths(viewMonth, 1)),
|
|
3012
|
+
showPrevNav: true,
|
|
3013
|
+
showNextNav: true
|
|
3014
|
+
}
|
|
3015
|
+
) }),
|
|
3016
|
+
showTimePicker && /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: timeVisible && /* @__PURE__ */ jsx(
|
|
3017
|
+
motion.div,
|
|
3018
|
+
{
|
|
3019
|
+
initial: { height: 0, opacity: 0 },
|
|
3020
|
+
animate: { height: "auto", opacity: 1 },
|
|
3021
|
+
exit: { height: 0, opacity: 0 },
|
|
3022
|
+
transition: {
|
|
3023
|
+
height: {
|
|
3024
|
+
type: "spring",
|
|
3025
|
+
stiffness: 400,
|
|
3026
|
+
damping: 30,
|
|
3027
|
+
mass: 0.8
|
|
3028
|
+
},
|
|
3029
|
+
opacity: { duration: 0.2 }
|
|
3030
|
+
},
|
|
3031
|
+
className: "overflow-hidden",
|
|
3032
|
+
children: /* @__PURE__ */ jsx(
|
|
3033
|
+
TimePickerColumn,
|
|
3034
|
+
{
|
|
3035
|
+
value: currentTime,
|
|
3036
|
+
onChange: handleTimeChange
|
|
3037
|
+
}
|
|
3038
|
+
)
|
|
3039
|
+
},
|
|
3040
|
+
"time-picker"
|
|
3041
|
+
) }),
|
|
3042
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2 px-2 py-3 border-t border-gray-100 dark:border-neutral-700", children: [
|
|
3043
|
+
/* @__PURE__ */ jsx(
|
|
3044
|
+
"button",
|
|
3045
|
+
{
|
|
3046
|
+
onClick: handleClear,
|
|
3047
|
+
disabled: !canClear,
|
|
3048
|
+
className: cn(
|
|
3049
|
+
"px-3 py-1.5 rounded-md text-sm transition-colors",
|
|
3050
|
+
canClear ? "text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-neutral-700" : "text-gray-300 dark:text-gray-600 cursor-not-allowed"
|
|
3051
|
+
),
|
|
3052
|
+
children: "Clear"
|
|
3053
|
+
}
|
|
3054
|
+
),
|
|
3055
|
+
/* @__PURE__ */ jsx(
|
|
3056
|
+
"button",
|
|
3057
|
+
{
|
|
3058
|
+
onClick: handleApply,
|
|
3059
|
+
disabled: !canApply,
|
|
3060
|
+
className: cn(
|
|
3061
|
+
"px-3 py-1.5 rounded-md text-sm font-medium transition-colors",
|
|
3062
|
+
canApply ? "bg-blue-600 text-white hover:bg-blue-700 dark:hover:bg-blue-500" : "bg-blue-100 text-blue-300 cursor-not-allowed dark:bg-blue-950/30 dark:text-blue-800"
|
|
3063
|
+
),
|
|
3064
|
+
children: "Apply"
|
|
3065
|
+
}
|
|
3066
|
+
)
|
|
3067
|
+
] })
|
|
3068
|
+
] })
|
|
3069
|
+
] }) })
|
|
3070
|
+
] })
|
|
3071
|
+
] });
|
|
3072
|
+
}
|
|
3073
|
+
var colsClass = {
|
|
3074
|
+
2: "grid-cols-2",
|
|
3075
|
+
3: "grid-cols-3",
|
|
3076
|
+
4: "grid-cols-4",
|
|
3077
|
+
5: "grid-cols-5"
|
|
3078
|
+
};
|
|
3079
|
+
function MobileDataCard({
|
|
3080
|
+
title,
|
|
3081
|
+
subtitle,
|
|
3082
|
+
image,
|
|
3083
|
+
contentRows,
|
|
3084
|
+
onPress,
|
|
3085
|
+
showChevron,
|
|
3086
|
+
selectBar,
|
|
3087
|
+
stats,
|
|
3088
|
+
statColumns,
|
|
3089
|
+
statsRenderer,
|
|
3090
|
+
details,
|
|
3091
|
+
extraContent,
|
|
3092
|
+
className
|
|
3093
|
+
}) {
|
|
3094
|
+
const isSelected = selectBar?.isSelected ?? false;
|
|
3095
|
+
const chevronVisible = showChevron ?? !!onPress;
|
|
3096
|
+
const contentBody = /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 px-3 py-3", children: [
|
|
3097
|
+
image && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: image }),
|
|
3098
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-2", children: [
|
|
3099
|
+
/* @__PURE__ */ jsx(
|
|
3100
|
+
Text,
|
|
3101
|
+
{
|
|
3102
|
+
size: "sm",
|
|
3103
|
+
weight: "semibold",
|
|
3104
|
+
className: "truncate leading-tight text-neutral-900 dark:text-neutral-100",
|
|
3105
|
+
children: title
|
|
3106
|
+
}
|
|
3107
|
+
),
|
|
3108
|
+
subtitle && /* @__PURE__ */ jsx(Text, { size: "xs", className: "text-neutral-400 dark:text-neutral-500", children: subtitle }),
|
|
3109
|
+
contentRows && contentRows.length > 0 && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-x-4 gap-y-1 text-xs", children: contentRows.map((row) => /* @__PURE__ */ jsxs("div", { className: "truncate", children: [
|
|
3110
|
+
/* @__PURE__ */ jsxs("span", { className: "text-neutral-400 dark:text-neutral-500", children: [
|
|
3111
|
+
row.label,
|
|
3112
|
+
" "
|
|
3113
|
+
] }),
|
|
3114
|
+
/* @__PURE__ */ jsx("span", { className: "text-neutral-700 dark:text-neutral-300", children: row.value })
|
|
3115
|
+
] }, row.label)) })
|
|
3116
|
+
] }),
|
|
3117
|
+
chevronVisible && /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 flex-shrink-0 self-center text-neutral-300 dark:text-neutral-600" })
|
|
3118
|
+
] });
|
|
3119
|
+
const hasStats = stats && stats.length > 0 || !!statsRenderer;
|
|
3120
|
+
const hasDetails = details && details.length > 0;
|
|
3121
|
+
const cols = statColumns ?? stats?.length ?? 2;
|
|
3122
|
+
return /* @__PURE__ */ jsxs(
|
|
3123
|
+
"div",
|
|
3124
|
+
{
|
|
3125
|
+
className: cn(
|
|
3126
|
+
"overflow-hidden rounded-lg border transition-colors",
|
|
3127
|
+
isSelected ? "border-blue-500 bg-blue-50/50 dark:border-blue-400 dark:bg-blue-900/10" : "border-neutral-200 bg-white dark:border-neutral-700 dark:bg-neutral-800/30",
|
|
3128
|
+
className
|
|
3129
|
+
),
|
|
3130
|
+
children: [
|
|
3131
|
+
selectBar && /* @__PURE__ */ jsxs(
|
|
3132
|
+
"div",
|
|
3133
|
+
{
|
|
3134
|
+
role: "button",
|
|
3135
|
+
tabIndex: 0,
|
|
3136
|
+
"aria-label": isSelected ? "Deselect item" : "Select item",
|
|
3137
|
+
onClick: selectBar.onToggle,
|
|
3138
|
+
onKeyDown: (e) => {
|
|
3139
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3140
|
+
e.preventDefault();
|
|
3141
|
+
selectBar.onToggle(e);
|
|
3142
|
+
}
|
|
3143
|
+
},
|
|
3144
|
+
className: "flex w-full cursor-pointer items-center gap-2.5 border-b border-neutral-100 px-3 py-1.5 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-500 dark:border-neutral-700/50",
|
|
3145
|
+
children: [
|
|
3146
|
+
/* @__PURE__ */ jsx(
|
|
3147
|
+
Checkbox,
|
|
3148
|
+
{
|
|
3149
|
+
checked: isSelected,
|
|
3150
|
+
className: "pointer-events-none",
|
|
3151
|
+
tabIndex: -1
|
|
3152
|
+
}
|
|
3153
|
+
),
|
|
3154
|
+
/* @__PURE__ */ jsx(
|
|
3155
|
+
Text,
|
|
3156
|
+
{
|
|
3157
|
+
size: "xs",
|
|
3158
|
+
as: "span",
|
|
3159
|
+
className: cn(
|
|
3160
|
+
isSelected ? "font-medium text-blue-600 dark:text-blue-400" : "text-neutral-400 dark:text-neutral-500"
|
|
3161
|
+
),
|
|
3162
|
+
children: isSelected ? "Selected" : "Select"
|
|
3163
|
+
}
|
|
3164
|
+
),
|
|
3165
|
+
selectBar.badge && /* @__PURE__ */ jsx("span", { className: "ml-auto", children: selectBar.badge })
|
|
3166
|
+
]
|
|
3167
|
+
}
|
|
3168
|
+
),
|
|
3169
|
+
onPress ? /* @__PURE__ */ jsx(
|
|
3170
|
+
"button",
|
|
3171
|
+
{
|
|
3172
|
+
type: "button",
|
|
3173
|
+
onClick: onPress,
|
|
3174
|
+
className: "w-full text-left transition-colors active:bg-neutral-50 dark:active:bg-neutral-800",
|
|
3175
|
+
children: contentBody
|
|
3176
|
+
}
|
|
3177
|
+
) : contentBody,
|
|
3178
|
+
statsRenderer ?? (stats && stats.length > 0 && /* @__PURE__ */ jsx("div", { className: cn("grid gap-1.5 px-3 pb-3", colsClass[cols]), children: stats.map((stat) => /* @__PURE__ */ jsxs(
|
|
3179
|
+
"div",
|
|
3180
|
+
{
|
|
3181
|
+
className: "flex flex-col items-center rounded-md bg-neutral-100 py-1.5 dark:bg-neutral-800",
|
|
3182
|
+
children: [
|
|
3183
|
+
/* @__PURE__ */ jsx(
|
|
3184
|
+
Text,
|
|
3185
|
+
{
|
|
3186
|
+
size: "xs",
|
|
3187
|
+
as: "span",
|
|
3188
|
+
className: "leading-none text-neutral-400 dark:text-neutral-500",
|
|
3189
|
+
children: stat.label
|
|
3190
|
+
}
|
|
3191
|
+
),
|
|
3192
|
+
/* @__PURE__ */ jsx(
|
|
3193
|
+
Text,
|
|
3194
|
+
{
|
|
3195
|
+
size: "sm",
|
|
3196
|
+
weight: "semibold",
|
|
3197
|
+
as: "span",
|
|
3198
|
+
className: cn(
|
|
3199
|
+
"mt-0.5 tabular-nums",
|
|
3200
|
+
stat.className ?? "text-neutral-800 dark:text-neutral-200"
|
|
3201
|
+
),
|
|
3202
|
+
children: stat.value
|
|
3203
|
+
}
|
|
3204
|
+
)
|
|
3205
|
+
]
|
|
3206
|
+
},
|
|
3207
|
+
stat.label
|
|
3208
|
+
)) })),
|
|
3209
|
+
hasDetails && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3210
|
+
hasStats && /* @__PURE__ */ jsx(Separator3, {}),
|
|
3211
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1 px-3 py-2", children: details.map((detail) => /* @__PURE__ */ jsxs(
|
|
3212
|
+
"div",
|
|
3213
|
+
{
|
|
3214
|
+
className: "flex items-center justify-between",
|
|
3215
|
+
children: [
|
|
3216
|
+
/* @__PURE__ */ jsx(
|
|
3217
|
+
Text,
|
|
3218
|
+
{
|
|
3219
|
+
size: "xs",
|
|
3220
|
+
as: "span",
|
|
3221
|
+
className: "text-neutral-400 dark:text-neutral-500",
|
|
3222
|
+
children: detail.label
|
|
3223
|
+
}
|
|
3224
|
+
),
|
|
3225
|
+
detail.pill ? /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full bg-blue-50 px-2 py-0.5 dark:bg-blue-900/30", children: /* @__PURE__ */ jsx(
|
|
3226
|
+
Text,
|
|
3227
|
+
{
|
|
3228
|
+
size: "xs",
|
|
3229
|
+
weight: "medium",
|
|
3230
|
+
as: "span",
|
|
3231
|
+
className: "text-blue-600 dark:text-blue-400",
|
|
3232
|
+
children: detail.value
|
|
3233
|
+
}
|
|
3234
|
+
) }) : detail.value
|
|
3235
|
+
]
|
|
3236
|
+
},
|
|
3237
|
+
detail.label
|
|
3238
|
+
)) })
|
|
3239
|
+
] }),
|
|
3240
|
+
extraContent
|
|
3241
|
+
]
|
|
3242
|
+
}
|
|
3243
|
+
);
|
|
3244
|
+
}
|
|
2778
3245
|
var DEFAULT_COMPARISON_PERIODS = [
|
|
2779
3246
|
{
|
|
2780
3247
|
key: "yesterday",
|
|
@@ -2851,6 +3318,6 @@ function PeriodComparisonSelector({
|
|
|
2851
3318
|
] });
|
|
2852
3319
|
}
|
|
2853
3320
|
|
|
2854
|
-
export { Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColumnSelection, DEFAULT_COMPARISON_PERIODS, DEFAULT_PRESETS, DEFAULT_TIME_RANGE, DateRangePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormLabel, FormMessage, PeriodComparisonSelector, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Skeleton, SkeletonAvatar, SkeletonBadge, SkeletonButton, SkeletonCard, SkeletonIcon, SkeletonInput, SkeletonSubtitle, SkeletonTableRow, SkeletonTableRows, SkeletonText, SkeletonTitle, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableRowCheckbox, TableSelectAll, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, buttonVariants, segmentedControlItemVariants, segmentedControlVariants, separatorVariants, switchLabelVariants, switchThumbVariants, switchTrackVariants, toggleGroupVariants, toggleItemVariants, useColumnVisibility, useFormContext, useFormFieldContext, useTableSelection };
|
|
2855
|
-
//# sourceMappingURL=chunk-
|
|
2856
|
-
//# sourceMappingURL=chunk-
|
|
3321
|
+
export { Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColumnSelection, DEFAULT_COMPARISON_PERIODS, DEFAULT_PRESETS, DEFAULT_TIME_RANGE, DateRangePicker, DateRangePickerMobile, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormLabel, FormMessage, MobileDataCard, PeriodComparisonSelector, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Skeleton, SkeletonAvatar, SkeletonBadge, SkeletonButton, SkeletonCard, SkeletonIcon, SkeletonInput, SkeletonSubtitle, SkeletonTableRow, SkeletonTableRows, SkeletonText, SkeletonTitle, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableRowCheckbox, TableSelectAll, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, buttonVariants, segmentedControlItemVariants, segmentedControlVariants, separatorVariants, switchLabelVariants, switchThumbVariants, switchTrackVariants, toggleGroupVariants, toggleItemVariants, useColumnVisibility, useFormContext, useFormFieldContext, useTableSelection };
|
|
3322
|
+
//# sourceMappingURL=chunk-PXBJSQUY.mjs.map
|
|
3323
|
+
//# sourceMappingURL=chunk-PXBJSQUY.mjs.map
|