@geomak/ui 6.25.0 → 6.26.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.js CHANGED
@@ -2840,6 +2840,7 @@ var MONTHS2 = [
2840
2840
  "November",
2841
2841
  "December"
2842
2842
  ];
2843
+ var MONTHS_SHORT = MONTHS2.map((m) => m.slice(0, 3));
2843
2844
  var WEEKDAYS2 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
2844
2845
  var toDate = (d) => d instanceof Date ? d : new Date(d);
2845
2846
  var startOfDay2 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
@@ -2967,10 +2968,18 @@ function Scheduler({
2967
2968
  /* @__PURE__ */ jsx(IconButton, { type: "bordered", size: "sm", icon: /* @__PURE__ */ jsx(Chevron4, { dir: "left" }), title: "Previous", onClick: () => go(-1) }),
2968
2969
  /* @__PURE__ */ jsx(IconButton, { type: "bordered", size: "sm", icon: /* @__PURE__ */ jsx(Chevron4, { dir: "right" }), title: "Next", onClick: () => go(1) }),
2969
2970
  /* @__PURE__ */ jsx(Button_default, { variant: "ghost", size: "sm", content: "Today", onClick: goToday }),
2970
- /* @__PURE__ */ jsxs("h2", { className: "ml-1 min-w-[9rem] text-base font-semibold tracking-tight text-foreground", children: [
2971
- title,
2972
- loading && /* @__PURE__ */ jsx("span", { className: "ml-2 inline-flex translate-y-0.5", children: /* @__PURE__ */ jsx(Spinner2, {}) })
2973
- ] })
2971
+ /* @__PURE__ */ jsx(
2972
+ MonthYearPicker,
2973
+ {
2974
+ label: title,
2975
+ cursor,
2976
+ onPick: (d) => {
2977
+ setDir(0);
2978
+ setCursor(d);
2979
+ }
2980
+ }
2981
+ ),
2982
+ loading && /* @__PURE__ */ jsx(Spinner2, {})
2974
2983
  ] }),
2975
2984
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2976
2985
  /* @__PURE__ */ jsx(
@@ -3021,6 +3030,64 @@ function Scheduler({
3021
3030
  }
3022
3031
  );
3023
3032
  }
3033
+ function MonthYearPicker({ label, cursor, onPick }) {
3034
+ const [open, setOpen] = useState(false);
3035
+ const [viewYear, setViewYear] = useState(cursor.getFullYear());
3036
+ useEffect(() => {
3037
+ if (open) setViewYear(cursor.getFullYear());
3038
+ }, [open, cursor]);
3039
+ return /* @__PURE__ */ jsxs(Popover.Root, { open, onOpenChange: setOpen, children: [
3040
+ /* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
3041
+ "button",
3042
+ {
3043
+ type: "button",
3044
+ className: "group ml-1 inline-flex items-center gap-1.5 rounded-md px-1.5 py-0.5 text-lg font-semibold tracking-tight text-foreground transition-colors hover:bg-background focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
3045
+ children: [
3046
+ label,
3047
+ /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-4 w-4 text-foreground-muted transition-transform duration-150 group-data-[state=open]:rotate-180", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 9l6 6 6-6" }) })
3048
+ ]
3049
+ }
3050
+ ) }),
3051
+ /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsxs(
3052
+ Popover.Content,
3053
+ {
3054
+ align: "start",
3055
+ sideOffset: 8,
3056
+ className: [
3057
+ "z-[400] w-64 rounded-lg border border-border bg-surface p-3 shadow-lg",
3058
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
3059
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
3060
+ ].join(" "),
3061
+ children: [
3062
+ /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-between", children: [
3063
+ /* @__PURE__ */ jsx(IconButton, { size: "sm", type: "bordered", icon: /* @__PURE__ */ jsx(Chevron4, { dir: "left" }), title: "Previous year", onClick: () => setViewYear((y) => y - 1) }),
3064
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold tabular-nums text-foreground", children: viewYear }),
3065
+ /* @__PURE__ */ jsx(IconButton, { size: "sm", type: "bordered", icon: /* @__PURE__ */ jsx(Chevron4, { dir: "right" }), title: "Next year", onClick: () => setViewYear((y) => y + 1) })
3066
+ ] }),
3067
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-1", children: MONTHS_SHORT.map((m, i) => {
3068
+ const current = i === cursor.getMonth() && viewYear === cursor.getFullYear();
3069
+ return /* @__PURE__ */ jsx(
3070
+ "button",
3071
+ {
3072
+ type: "button",
3073
+ onClick: () => {
3074
+ onPick(new Date(viewYear, i, 1));
3075
+ setOpen(false);
3076
+ },
3077
+ className: [
3078
+ "rounded-md px-2 py-1.5 text-sm transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
3079
+ current ? "bg-accent font-semibold text-accent-fg" : "text-foreground hover:bg-background"
3080
+ ].join(" "),
3081
+ children: m
3082
+ },
3083
+ m
3084
+ );
3085
+ }) })
3086
+ ]
3087
+ }
3088
+ ) })
3089
+ ] });
3090
+ }
3024
3091
  var MAX_CHIPS = 3;
3025
3092
  function MonthView({
3026
3093
  cursor,
@@ -3045,7 +3112,9 @@ function MonthView({
3045
3112
  className: [
3046
3113
  "group flex min-h-[5rem] flex-col gap-1 border-b border-r border-border p-1.5 text-left transition-colors",
3047
3114
  "[&:nth-child(7n)]:border-r-0 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent",
3048
- inMonth ? "bg-surface hover:bg-surface-raised" : "bg-background/40"
3115
+ // surface===surface-raised in light mode, so hover lifts toward the
3116
+ // cool chart-mist background instead (a visible, on-brand tint).
3117
+ inMonth ? "bg-surface hover:bg-background" : "bg-background hover:bg-surface"
3049
3118
  ].join(" "),
3050
3119
  children: [
3051
3120
  /* @__PURE__ */ jsx(
@@ -3102,6 +3171,8 @@ function WeekView({
3102
3171
  onSelectEvent
3103
3172
  }) {
3104
3173
  const days = useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
3174
+ const labels = useMemo(() => weekdayLabels(weekStartsOn), [weekStartsOn]);
3175
+ const dow = (d) => labels[(d.getDay() - weekStartsOn + 7) % 7];
3105
3176
  const [startHour, endHour] = dayHours;
3106
3177
  const hours = useMemo(
3107
3178
  () => Array.from({ length: endHour - startHour }, (_, i) => startHour + i),
@@ -3113,7 +3184,7 @@ function WeekView({
3113
3184
  /* @__PURE__ */ jsxs("div", { className: "grid border-b border-border", style: { gridTemplateColumns: `3.5rem repeat(7, 1fr)` }, children: [
3114
3185
  /* @__PURE__ */ jsx("div", { className: "border-r border-border" }),
3115
3186
  days.map((d) => /* @__PURE__ */ jsxs("div", { className: "border-r border-border px-1 py-1.5 text-center last:border-r-0", children: [
3116
- /* @__PURE__ */ jsx("div", { className: "text-[11px] font-medium uppercase tracking-wide text-foreground-muted", children: weekdayLabels(weekStartsOn)[(d.getDay() - weekStartsOn + 7) % 7] }),
3187
+ /* @__PURE__ */ jsx("div", { className: "text-[11px] font-medium uppercase tracking-wide text-foreground-muted", children: dow(d) }),
3117
3188
  /* @__PURE__ */ jsx("div", { className: ["mx-auto mt-0.5 flex h-6 w-6 items-center justify-center rounded-full text-xs tabular-nums", isToday(d) ? "bg-accent font-semibold text-accent-fg" : "text-foreground"].join(" "), children: d.getDate() })
3118
3189
  ] }, d.getTime()))
3119
3190
  ] }),
@@ -3126,9 +3197,9 @@ function WeekView({
3126
3197
  "button",
3127
3198
  {
3128
3199
  type: "button",
3129
- "aria-label": `${weekdayLabels(weekStartsOn)[(day.getDay() - weekStartsOn + 7) % 7]} ${day.getDate()} ${hourLabel(h)}`,
3200
+ "aria-label": `${dow(day)} ${day.getDate()} ${hourLabel(h)}`,
3130
3201
  onClick: () => onSelectSlot?.(new Date(day.getFullYear(), day.getMonth(), day.getDate(), h)),
3131
- className: "absolute left-0 right-0 border-b border-border/60 hover:bg-surface-raised/60 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent",
3202
+ className: "absolute left-0 right-0 border-b border-border hover:bg-background focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent",
3132
3203
  style: { top: i * hourHeight, height: hourHeight }
3133
3204
  },
3134
3205
  h
@@ -3147,11 +3218,16 @@ function WeekView({
3147
3218
  onSelectEvent?.(e);
3148
3219
  },
3149
3220
  title: `${e.title} \xB7 ${timeLabel(e.start)}\u2013${timeLabel(e.end)}`,
3150
- className: "absolute left-0.5 right-0.5 overflow-hidden rounded-md border-l-2 px-1.5 py-0.5 text-left text-[11px] leading-tight text-foreground shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
3151
- style: { top: Math.max(0, top), height, borderLeftColor: color, backgroundColor: `color-mix(in oklab, ${color} 16%, var(--color-surface))` },
3221
+ className: "absolute left-0.5 right-0.5 overflow-hidden rounded-md border px-1.5 py-0.5 text-left text-[11px] leading-tight text-foreground shadow-sm transition-shadow hover:shadow-md focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
3222
+ style: {
3223
+ top: Math.max(0, top),
3224
+ height,
3225
+ backgroundColor: `color-mix(in oklab, ${color} 14%, var(--color-surface))`,
3226
+ borderColor: `color-mix(in oklab, ${color} 40%, var(--color-surface))`
3227
+ },
3152
3228
  children: [
3153
3229
  /* @__PURE__ */ jsx("div", { className: "truncate font-medium", children: e.title }),
3154
- /* @__PURE__ */ jsx("div", { className: "truncate text-foreground-muted", children: timeLabel(e.start) })
3230
+ /* @__PURE__ */ jsx("div", { className: "truncate", style: { color }, children: timeLabel(e.start) })
3155
3231
  ]
3156
3232
  },
3157
3233
  e.id