@ttt-productions/ui-core 0.11.4 → 0.11.6

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.
@@ -0,0 +1,68 @@
1
+ /**
2
+ * The inline required-reason config. The caller OWNS the reason value/onChange (draft state lives at
3
+ * the call site). Any `minLength`/`maxLength` the caller supplies MUST come from a caller-owned
4
+ * constant — this component declares no business numbers and no copy; it only derives the gate + the
5
+ * Textarea `maxLength` from the values it is handed.
6
+ */
7
+ export interface ConsequenceDialogReason {
8
+ required?: boolean;
9
+ minLength?: number;
10
+ maxLength?: number;
11
+ placeholder?: string;
12
+ label?: React.ReactNode;
13
+ value: string;
14
+ onChange: (value: string) => void;
15
+ rows?: number;
16
+ }
17
+ /**
18
+ * The exact-match typed-confirmation gate. `phrase` is business copy owned by the CALLER; the
19
+ * component only compares the typed value against it.
20
+ */
21
+ export interface ConsequenceDialogTypedConfirmation {
22
+ phrase: string;
23
+ label?: React.ReactNode;
24
+ }
25
+ export interface ConsequenceDialogProps {
26
+ /** Uncontrolled open model: the element that opens the dialog (rendered `asChild`). */
27
+ trigger?: React.ReactNode;
28
+ /** Controlled open model. Provide with `onOpenChange`. */
29
+ open?: boolean;
30
+ onOpenChange?: (open: boolean) => void;
31
+ /** Heading — a string or node so callers can interpolate amounts / names. */
32
+ title: React.ReactNode;
33
+ /** SLOT 1 — what happens right now (e.g. "initiates a Stripe refund of $X now"). */
34
+ immediateEffect?: React.ReactNode;
35
+ /** SLOT 2 — what settles later, out of band (webhook / worker / async confirmation). */
36
+ delayedEffect?: React.ReactNode;
37
+ /** SLOT 3 — whether/how this can be undone or superseded. */
38
+ reversibility?: React.ReactNode;
39
+ /** Inline required-reason field. Optional. */
40
+ reason?: ConsequenceDialogReason;
41
+ /** Exact-phrase typed-confirmation gate. Optional. */
42
+ typedConfirmation?: ConsequenceDialogTypedConfirmation;
43
+ confirmLabel: React.ReactNode;
44
+ cancelLabel?: React.ReactNode;
45
+ /** `true` styles the confirm button with `bg-destructive`. */
46
+ destructive?: boolean;
47
+ /**
48
+ * Runs on confirm. May be async — while it is pending the dialog STAYS OPEN, both buttons disable,
49
+ * and a `Loader2` spins in the confirm button. Closes on resolve. If it rejects the dialog
50
+ * stays open so the caller's own surface (error toast, TOTP step-up) can show and the operator can
51
+ * retry or cancel. This component takes no Sentry/monitoring dependency — every error path
52
+ * belongs to the caller's `onConfirm`.
53
+ */
54
+ onConfirm: () => void | Promise<void>;
55
+ }
56
+ /**
57
+ * A reusable confirm-before-a-consequential-action dialog. Three optional, consistently-styled
58
+ * consequence slots (immediate / afterward / reversibility), an optional inline required-reason field,
59
+ * and an optional exact-phrase typed-confirmation gate. Composes the ui-core AlertDialog primitives
60
+ * (Radix) — it never re-implements them. Supports BOTH a `trigger` (uncontrolled) and `open` /
61
+ * `onOpenChange` (controlled).
62
+ *
63
+ * Pending model: the confirm button is a plain `Button` (NOT `AlertDialogAction`), so Radix does not
64
+ * auto-close on click; open state is managed here so the dialog stays open with a visible spinner
65
+ * until `onConfirm` resolves.
66
+ */
67
+ export declare function ConsequenceDialog({ trigger, open, onOpenChange, title, immediateEffect, delayedEffect, reversibility, reason, typedConfirmation, confirmLabel, cancelLabel, destructive, onConfirm, }: ConsequenceDialogProps): import("react").JSX.Element;
68
+ //# sourceMappingURL=consequence-dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consequence-dialog.d.ts","sourceRoot":"","sources":["../../../src/react/components/consequence-dialog.tsx"],"names":[],"mappings":"AAkBA;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,kCAAkC;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,uFAAuF;IACvF,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,0DAA0D;IAC1D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAEvC,6EAA6E;IAC7E,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IAEvB,oFAAoF;IACpF,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAClC,wFAAwF;IACxF,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,6DAA6D;IAC7D,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAEhC,8CAA8C;IAC9C,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,sDAAsD;IACtD,iBAAiB,CAAC,EAAE,kCAAkC,CAAC;IAEvD,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,8DAA8D;IAC9D,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AA0BD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,eAAe,EACf,aAAa,EACb,aAAa,EACb,MAAM,EACN,iBAAiB,EACjB,YAAY,EACZ,WAAsB,EACtB,WAAmB,EACnB,SAAS,GACV,EAAE,sBAAsB,+BAiJxB"}
@@ -0,0 +1,80 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useCallback, useId, useState } from 'react';
4
+ import { AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, } from './alert-dialog.js';
5
+ import { Button } from './button.js';
6
+ import { Textarea } from './textarea.js';
7
+ import { Input } from './input.js';
8
+ import { Label } from './label.js';
9
+ import { Loader2, Zap, Clock, RotateCcw } from 'lucide-react';
10
+ const SLOT_ICON_CLASS = 'icon-xs mt-0.5 shrink-0 text-muted-foreground';
11
+ function ConsequenceRow({ icon: Icon, label, children, }) {
12
+ return (_jsxs("span", { className: "flex items-start gap-2", children: [_jsx(Icon, { className: SLOT_ICON_CLASS, "aria-hidden": "true" }), _jsxs("span", { className: "stack-1 min-w-0", children: [_jsx("span", { className: "text-caption font-medium uppercase tracking-wide text-muted-foreground", children: label }), _jsx("span", { className: "text-small text-foreground", children: children })] })] }));
13
+ }
14
+ /**
15
+ * A reusable confirm-before-a-consequential-action dialog. Three optional, consistently-styled
16
+ * consequence slots (immediate / afterward / reversibility), an optional inline required-reason field,
17
+ * and an optional exact-phrase typed-confirmation gate. Composes the ui-core AlertDialog primitives
18
+ * (Radix) — it never re-implements them. Supports BOTH a `trigger` (uncontrolled) and `open` /
19
+ * `onOpenChange` (controlled).
20
+ *
21
+ * Pending model: the confirm button is a plain `Button` (NOT `AlertDialogAction`), so Radix does not
22
+ * auto-close on click; open state is managed here so the dialog stays open with a visible spinner
23
+ * until `onConfirm` resolves.
24
+ */
25
+ export function ConsequenceDialog({ trigger, open, onOpenChange, title, immediateEffect, delayedEffect, reversibility, reason, typedConfirmation, confirmLabel, cancelLabel = 'Cancel', destructive = false, onConfirm, }) {
26
+ const isControlled = open !== undefined;
27
+ const [internalOpen, setInternalOpen] = useState(false);
28
+ const [typedValue, setTypedValue] = useState('');
29
+ const [pending, setPending] = useState(false);
30
+ const actualOpen = isControlled ? open : internalOpen;
31
+ const reasonId = useId();
32
+ const typedId = useId();
33
+ const setOpenState = useCallback((next) => {
34
+ if (isControlled)
35
+ onOpenChange?.(next);
36
+ else
37
+ setInternalOpen(next);
38
+ }, [isControlled, onOpenChange]);
39
+ // Never allow an open-state change (Escape, cancel, controlled parent) to fight the pending action.
40
+ const handleOpenChange = useCallback((next) => {
41
+ if (pending)
42
+ return;
43
+ setTypedValue(''); // reset the typed gate on every open/close
44
+ setOpenState(next);
45
+ }, [pending, setOpenState]);
46
+ const handleConfirm = useCallback(async () => {
47
+ if (pending)
48
+ return;
49
+ setPending(true);
50
+ try {
51
+ await onConfirm();
52
+ setTypedValue('');
53
+ setOpenState(false);
54
+ }
55
+ catch {
56
+ // Keep the dialog open — the caller's onConfirm surfaced the error (toast / step-up). The
57
+ // operator can retry or cancel. Never rethrow, never monitor here.
58
+ }
59
+ finally {
60
+ setPending(false);
61
+ }
62
+ }, [pending, onConfirm, setOpenState]);
63
+ const reasonTrimmedLength = reason ? reason.value.trim().length : 0;
64
+ const reasonProvided = reasonTrimmedLength > 0;
65
+ const reasonOk = !reason
66
+ ? true
67
+ : reason.required && !reasonProvided
68
+ ? false
69
+ : !reasonProvided
70
+ ? true // optional + empty is fine
71
+ : (reason.minLength === undefined || reasonTrimmedLength >= reason.minLength) &&
72
+ (reason.maxLength === undefined || reason.value.length <= reason.maxLength);
73
+ const typedOk = !typedConfirmation ? true : typedValue === typedConfirmation.phrase;
74
+ const confirmDisabled = pending || !reasonOk || !typedOk;
75
+ return (_jsxs(AlertDialog, { open: actualOpen, onOpenChange: handleOpenChange, children: [trigger ? _jsx(AlertDialogTrigger, { asChild: true, children: trigger }) : null, _jsxs(AlertDialogContent, { onEscapeKeyDown: (e) => {
76
+ if (pending)
77
+ e.preventDefault();
78
+ }, children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: title }), _jsx(AlertDialogDescription, { asChild: true, children: _jsxs("span", { className: "stack-3", children: [immediateEffect ? (_jsx(ConsequenceRow, { icon: Zap, label: "Immediately", children: immediateEffect })) : null, delayedEffect ? (_jsx(ConsequenceRow, { icon: Clock, label: "Afterward", children: delayedEffect })) : null, reversibility ? (_jsx(ConsequenceRow, { icon: RotateCcw, label: "Reversibility", children: reversibility })) : null] }) })] }), reason ? (_jsxs("div", { className: "stack-2", children: [_jsx(Label, { htmlFor: reasonId, children: reason.label ?? 'Reason' }), _jsx(Textarea, { id: reasonId, value: reason.value, onChange: (e) => reason.onChange(e.target.value), placeholder: reason.placeholder, maxLength: reason.maxLength, rows: reason.rows ?? 3, disabled: pending })] })) : null, typedConfirmation ? (_jsxs("div", { className: "stack-2", children: [_jsx(Label, { htmlFor: typedId, children: typedConfirmation.label ?? (_jsxs(_Fragment, { children: ["Type ", _jsx("span", { className: "font-mono", children: typedConfirmation.phrase }), " to confirm"] })) }), _jsx(Input, { id: typedId, value: typedValue, onChange: (e) => setTypedValue(e.target.value), placeholder: typedConfirmation.phrase, disabled: pending, autoComplete: "off" })] })) : null, _jsxs(AlertDialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => handleOpenChange(false), disabled: pending, children: cancelLabel }), _jsxs(Button, { variant: destructive ? 'destructive' : 'default', onClick: handleConfirm, disabled: confirmDisabled, "aria-busy": pending, children: [pending ? _jsx(Loader2, { className: "mr-2 spinner-xs", "aria-hidden": "true" }) : null, confirmLabel] })] })] })] }));
79
+ }
80
+ //# sourceMappingURL=consequence-dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consequence-dialog.js","sourceRoot":"","sources":["../../../src/react/components/consequence-dialog.tsx"],"names":[],"mappings":"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"}
@@ -7,6 +7,11 @@ export interface DatePickerProps {
7
7
  disableFuture?: boolean;
8
8
  className?: string;
9
9
  }
10
+ /** Calendar with fast month/year navigation: the header's month and year are
11
+ * each buttons — month opens a 12-month grid, year opens a paged 12-year
12
+ * grid (no single-step year arrows; distant years are a couple of clicks).
13
+ * Picking a year drills to the month grid, then the day grid — the natural
14
+ * date-of-birth path — while picking just a month returns straight to days. */
10
15
  declare function DatePicker({ selected, onSelect, disabled, disablePast, disableFuture, className, }: DatePickerProps): React.JSX.Element;
11
16
  declare namespace DatePicker {
12
17
  var displayName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/react/components/date-picker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,IAAI,CAAA;IACf,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,KAAK,IAAI,CAAA;IAC3C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAA;IAClC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AASD,iBAAS,UAAU,CAAC,EAClB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,WAAmB,EACnB,aAAqB,EACrB,SAAS,GACV,EAAE,eAAe,qBA4KjB;kBAnLQ,UAAU;;;AAuLnB,OAAO,EAAE,UAAU,EAAE,CAAA"}
1
+ {"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/react/components/date-picker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,IAAI,CAAA;IACf,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,KAAK,IAAI,CAAA;IAC3C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAA;IAClC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAgBD;;;;gFAIgF;AAChF,iBAAS,UAAU,CAAC,EAClB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,WAAmB,EACnB,aAAqB,EACrB,SAAS,GACV,EAAE,eAAe,qBAoSjB;kBA3SQ,UAAU;;;AA+SnB,OAAO,EAAE,UAAU,EAAE,CAAA"}
@@ -1,17 +1,28 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
- import { ChevronLeft, ChevronRight, ChevronUp, ChevronDown } from "lucide-react";
4
+ import { ChevronLeft, ChevronRight } from "lucide-react";
5
5
  import { Button } from "./button.js";
6
6
  import { cn } from "../../lib/utils.js";
7
7
  const MONTHS = [
8
8
  "January", "February", "March", "April", "May", "June",
9
9
  "July", "August", "September", "October", "November", "December",
10
10
  ];
11
+ const MONTHS_SHORT = [
12
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
13
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
14
+ ];
11
15
  const DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
16
+ const YEARS_PER_PAGE = 12;
17
+ /** Calendar with fast month/year navigation: the header's month and year are
18
+ * each buttons — month opens a 12-month grid, year opens a paged 12-year
19
+ * grid (no single-step year arrows; distant years are a couple of clicks).
20
+ * Picking a year drills to the month grid, then the day grid — the natural
21
+ * date-of-birth path — while picking just a month returns straight to days. */
12
22
  function DatePicker({ selected, onSelect, disabled, disablePast = false, disableFuture = false, className, }) {
13
23
  const [viewDate, setViewDate] = React.useState(() => selected || new Date());
14
- const [showYearPicker, setShowYearPicker] = React.useState(false);
24
+ const [view, setView] = React.useState("days");
25
+ const [yearPageStart, setYearPageStart] = React.useState(() => Math.floor((selected || new Date()).getFullYear() / YEARS_PER_PAGE) * YEARS_PER_PAGE);
15
26
  const today = new Date();
16
27
  today.setHours(0, 0, 0, 0);
17
28
  const getDaysInMonth = (date) => {
@@ -35,6 +46,21 @@ function DatePicker({ selected, onSelect, disabled, disablePast = false, disable
35
46
  return true;
36
47
  return false;
37
48
  };
49
+ /** A whole month is unpickable only when every day in it is out of range. */
50
+ const isMonthDisabled = (year, month) => {
51
+ if (disableFuture && new Date(year, month, 1) > today)
52
+ return true;
53
+ if (disablePast && new Date(year, month + 1, 0) < today)
54
+ return true;
55
+ return false;
56
+ };
57
+ const isYearDisabled = (year) => {
58
+ if (disableFuture && year > today.getFullYear())
59
+ return true;
60
+ if (disablePast && year < today.getFullYear())
61
+ return true;
62
+ return false;
63
+ };
38
64
  const isDateSelected = (date) => {
39
65
  if (!selected)
40
66
  return false;
@@ -63,22 +89,39 @@ function DatePicker({ selected, onSelect, disabled, disablePast = false, disable
63
89
  };
64
90
  const previousMonth = () => setViewDate((prev) => new Date(prev.getFullYear(), prev.getMonth() - 1));
65
91
  const nextMonth = () => setViewDate((prev) => new Date(prev.getFullYear(), prev.getMonth() + 1));
66
- const previousYear = () => setViewDate((prev) => new Date(prev.getFullYear() - 1, prev.getMonth()));
67
- const nextYear = () => setViewDate((prev) => new Date(prev.getFullYear() + 1, prev.getMonth()));
68
92
  const handleDateClick = (date) => {
69
93
  if (isDateDisabled(date))
70
94
  return;
71
95
  onSelect?.(date);
72
96
  };
97
+ const openYears = () => {
98
+ setYearPageStart(Math.floor(viewDate.getFullYear() / YEARS_PER_PAGE) * YEARS_PER_PAGE);
99
+ setView("years");
100
+ };
73
101
  const calendarDays = generateCalendarDays();
74
- return (_jsxs("div", { className: cn("p-4 bg-card rounded-lg", className), children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsx(Button, { variant: "default", size: "sm", className: "h-8 w-8 p-0", onClick: previousMonth, children: _jsx(ChevronLeft, { className: "h-4 w-4" }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { onClick: () => setShowYearPicker(!showYearPicker), className: "text-base font-bold hover:opacity-80 transition-opacity text-foreground", children: [MONTHS[viewDate.getMonth()], " ", viewDate.getFullYear()] }), showYearPicker && (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Button, { variant: "ghost", size: "sm", className: "h-4 w-4 p-0", onClick: nextYear, children: _jsx(ChevronUp, { className: "h-3 w-3" }) }), _jsx(Button, { variant: "ghost", size: "sm", className: "h-4 w-4 p-0", onClick: previousYear, children: _jsx(ChevronDown, { className: "h-3 w-3" }) })] }))] }), _jsx(Button, { variant: "default", size: "sm", className: "h-8 w-8 p-0", onClick: nextMonth, children: _jsx(ChevronRight, { className: "h-4 w-4" }) })] }), _jsx("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS.map((day) => (_jsx("div", { className: "text-center text-sm font-bold py-2 text-foreground", children: day }, day))) }), _jsx("div", { className: "grid grid-cols-7 gap-1", children: calendarDays.map((date, index) => {
75
- if (!date)
76
- return _jsx("div", { className: "h-9" }, `empty-${index}`);
77
- const disabled = isDateDisabled(date);
78
- const selected = isDateSelected(date);
79
- const todayDate = isToday(date);
80
- return (_jsxs("button", { onClick: () => handleDateClick(date), disabled: disabled, className: cn("h-9 w-9 rounded-lg text-sm font-semibold transition-all", "hover:scale-105 active:scale-95", "flex items-center justify-center", !disabled && !selected && !todayDate && "text-foreground hover:bg-primary/10", todayDate && !selected && "bg-accent text-foreground font-bold ring-2 ring-border", selected && "bg-primary text-white font-bold shadow-lg", disabled && "opacity-30 cursor-not-allowed hover:scale-100 hover:bg-transparent", disabled && "relative"), children: [date.getDate(), disabled && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx("div", { className: "w-px h-full bg-current transform rotate-45" }) }))] }, date.toISOString()));
81
- }) }), _jsxs("div", { className: "mt-4 pt-3 border-t border-border text-xs space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-3 w-3 rounded-sm bg-primary" }), _jsx("span", { className: "text-muted-foreground", children: "Selected" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-3 w-3 rounded-sm bg-accent ring-2 ring-border" }), _jsx("span", { className: "text-muted-foreground", children: "Today" })] }), (disablePast || disableFuture || disabled) && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-3 w-3 rounded-sm bg-muted opacity-30 relative", children: _jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx("div", { className: "w-px h-full bg-foreground transform rotate-45" }) }) }), _jsx("span", { className: "text-muted-foreground", children: "Unavailable" })] }))] })] }));
102
+ const yearPage = Array.from({ length: YEARS_PER_PAGE }, (_, i) => yearPageStart + i);
103
+ return (_jsxs("div", { className: cn("p-4 bg-card rounded-lg", className), children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsx(Button, { variant: "default", size: "sm", className: cn("h-8 w-8 p-0", view !== "days" && "invisible"), "aria-label": "Previous month", onClick: previousMonth, children: _jsx(ChevronLeft, { className: "h-4 w-4" }) }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("button", { type: "button", onClick: () => setView(view === "months" ? "days" : "months"), "aria-expanded": view === "months", className: "text-base font-bold hover:opacity-80 transition-opacity text-foreground underline decoration-1 underline-offset-4 decoration-border", children: MONTHS[viewDate.getMonth()] }), _jsx("button", { type: "button", onClick: () => (view === "years" ? setView("days") : openYears()), "aria-expanded": view === "years", className: "text-base font-bold hover:opacity-80 transition-opacity text-foreground underline decoration-1 underline-offset-4 decoration-border", children: viewDate.getFullYear() })] }), _jsx(Button, { variant: "default", size: "sm", className: cn("h-8 w-8 p-0", view !== "days" && "invisible"), "aria-label": "Next month", onClick: nextMonth, children: _jsx(ChevronRight, { className: "h-4 w-4" }) })] }), view === "years" && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx(Button, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0", "aria-label": `Previous ${YEARS_PER_PAGE} years`, onClick: () => setYearPageStart((s) => s - YEARS_PER_PAGE), children: _jsx(ChevronLeft, { className: "h-4 w-4" }) }), _jsxs("span", { className: "text-sm font-semibold text-muted-foreground", children: [yearPageStart, " \u2013 ", yearPageStart + YEARS_PER_PAGE - 1] }), _jsx(Button, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0", "aria-label": `Next ${YEARS_PER_PAGE} years`, onClick: () => setYearPageStart((s) => s + YEARS_PER_PAGE), children: _jsx(ChevronRight, { className: "h-4 w-4" }) })] }), _jsx("div", { className: "grid grid-cols-3 gap-1", children: yearPage.map((year) => {
104
+ const yearDisabled = isYearDisabled(year);
105
+ const isViewYear = year === viewDate.getFullYear();
106
+ return (_jsx("button", { type: "button", disabled: yearDisabled, onClick: () => {
107
+ setViewDate((prev) => new Date(year, prev.getMonth()));
108
+ setView("months");
109
+ }, className: cn("h-10 rounded-lg text-sm font-semibold transition-all", "flex items-center justify-center", !yearDisabled && !isViewYear && "text-foreground hover:bg-primary/10", isViewYear && "bg-primary text-white font-bold shadow-lg", yearDisabled && "opacity-30 cursor-not-allowed"), children: year }, year));
110
+ }) })] })), view === "months" && (_jsx("div", { className: "grid grid-cols-3 gap-1", children: MONTHS_SHORT.map((label, month) => {
111
+ const monthDisabled = isMonthDisabled(viewDate.getFullYear(), month);
112
+ const isViewMonth = month === viewDate.getMonth();
113
+ return (_jsx("button", { type: "button", disabled: monthDisabled, onClick: () => {
114
+ setViewDate((prev) => new Date(prev.getFullYear(), month));
115
+ setView("days");
116
+ }, className: cn("h-10 rounded-lg text-sm font-semibold transition-all", "flex items-center justify-center", !monthDisabled && !isViewMonth && "text-foreground hover:bg-primary/10", isViewMonth && "bg-primary text-white font-bold shadow-lg", monthDisabled && "opacity-30 cursor-not-allowed"), children: label }, label));
117
+ }) })), view === "days" && (_jsxs(_Fragment, { children: [_jsx("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS.map((day) => (_jsx("div", { className: "text-center text-sm font-bold py-2 text-foreground", children: day }, day))) }), _jsx("div", { className: "grid grid-cols-7 gap-1", children: calendarDays.map((date, index) => {
118
+ if (!date)
119
+ return _jsx("div", { className: "h-9" }, `empty-${index}`);
120
+ const dateDisabled = isDateDisabled(date);
121
+ const dateSelected = isDateSelected(date);
122
+ const todayDate = isToday(date);
123
+ return (_jsxs("button", { type: "button", onClick: () => handleDateClick(date), disabled: dateDisabled, className: cn("h-9 w-9 rounded-lg text-sm font-semibold transition-all", "hover:scale-105 active:scale-95", "flex items-center justify-center", !dateDisabled && !dateSelected && !todayDate && "text-foreground hover:bg-primary/10", todayDate && !dateSelected && "bg-accent text-foreground font-bold ring-2 ring-border", dateSelected && "bg-primary text-white font-bold shadow-lg", dateDisabled && "opacity-30 cursor-not-allowed hover:scale-100 hover:bg-transparent", dateDisabled && "relative"), children: [date.getDate(), dateDisabled && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx("div", { className: "w-px h-full bg-current transform rotate-45" }) }))] }, date.toISOString()));
124
+ }) }), _jsxs("div", { className: "mt-4 pt-3 border-t border-border text-xs space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-3 w-3 rounded-sm bg-primary" }), _jsx("span", { className: "text-muted-foreground", children: "Selected" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-3 w-3 rounded-sm bg-accent ring-2 ring-border" }), _jsx("span", { className: "text-muted-foreground", children: "Today" })] }), (disablePast || disableFuture || disabled) && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-3 w-3 rounded-sm bg-muted opacity-30 relative", children: _jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx("div", { className: "w-px h-full bg-foreground transform rotate-45" }) }) }), _jsx("span", { className: "text-muted-foreground", children: "Unavailable" })] }))] })] }))] }));
82
125
  }
83
126
  DatePicker.displayName = "DatePicker";
84
127
  export { DatePicker };
@@ -1 +1 @@
1
- {"version":3,"file":"date-picker.js","sourceRoot":"","sources":["../../../src/react/components/date-picker.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"date-picker.js","sourceRoot":"","sources":["../../../src/react/components/date-picker.tsx"],"names":[],"mappings":"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"}
@@ -38,6 +38,8 @@ export { Sheet, SheetPortal, SheetOverlay, SheetTrigger, SheetClose, SheetConten
38
38
  export { Collapsible, CollapsibleTrigger, CollapsibleContent } from "./components/collapsible.js";
39
39
  export type { SearchDropdownProps } from "./components/search-dropdown.js";
40
40
  export { SearchDropdown } from "./components/search-dropdown.js";
41
+ export type { ConsequenceDialogProps, ConsequenceDialogReason, ConsequenceDialogTypedConfirmation } from "./components/consequence-dialog.js";
42
+ export { ConsequenceDialog } from "./components/consequence-dialog.js";
41
43
  export type { MaxWidthOption, ScreenAdaptiveViewProps } from "./components/layout/screen-adaptive-view.js";
42
44
  export { ScreenAdaptiveView } from "./components/layout/screen-adaptive-view.js";
43
45
  export { useMediaQuery } from "./hooks/use-media-query.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC7G,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACpL,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC1W,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACtS,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAChQ,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC5E,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACnI,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChM,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACrI,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,YAAY,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACzG,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACjI,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzK,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAClG,YAAY,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,YAAY,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AAC3G,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,YAAY,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAErF,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,YAAY,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAEnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,YAAY,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,7 @@ export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableC
33
33
  export { Sheet, SheetPortal, SheetOverlay, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription } from "./components/sheet.js";
34
34
  export { Collapsible, CollapsibleTrigger, CollapsibleContent } from "./components/collapsible.js";
35
35
  export { SearchDropdown } from "./components/search-dropdown.js";
36
+ export { ConsequenceDialog } from "./components/consequence-dialog.js";
36
37
  export { ScreenAdaptiveView } from "./components/layout/screen-adaptive-view.js";
37
38
  export { useMediaQuery } from "./hooks/use-media-query.js";
38
39
  // Shared building blocks
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAGb,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC7G,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACpL,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC1W,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACtS,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAChQ,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE5E,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACnI,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAElD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChM,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACrI,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACzG,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACjI,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzK,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAElG,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,yBAAyB;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAG7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAG3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAGzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/ui-core",
3
- "version": "0.11.4",
3
+ "version": "0.11.6",
4
4
  "description": "Shared UI components for TTT Productions projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -49,7 +49,7 @@
49
49
  "react-dom": ">=19.0.0",
50
50
  "react-hook-form": ">=7.0.0",
51
51
  "@hookform/resolvers": ">=3.0.0",
52
- "@ttt-productions/firebase-helpers": "^0.12.0"
52
+ "@ttt-productions/firebase-helpers": "^0.12.1"
53
53
  },
54
54
  "peerDependenciesMeta": {
55
55
  "react": {
@@ -99,7 +99,7 @@
99
99
  "typescript": "^5.8.3",
100
100
  "react-hook-form": "^7.69.0",
101
101
  "@hookform/resolvers": "^5.2.2",
102
- "@ttt-productions/firebase-helpers": "^0.12.0"
102
+ "@ttt-productions/firebase-helpers": "^0.12.1"
103
103
  },
104
104
  "author": "DJ (TTT Productions)",
105
105
  "license": "MIT"
@@ -0,0 +1,276 @@
1
+ 'use client';
2
+
3
+ import { useCallback, useId, useState } from 'react';
4
+ import {
5
+ AlertDialog,
6
+ AlertDialogTrigger,
7
+ AlertDialogContent,
8
+ AlertDialogHeader,
9
+ AlertDialogFooter,
10
+ AlertDialogTitle,
11
+ AlertDialogDescription,
12
+ } from './alert-dialog.js';
13
+ import { Button } from './button.js';
14
+ import { Textarea } from './textarea.js';
15
+ import { Input } from './input.js';
16
+ import { Label } from './label.js';
17
+ import { Loader2, Zap, Clock, RotateCcw } from 'lucide-react';
18
+
19
+ /**
20
+ * The inline required-reason config. The caller OWNS the reason value/onChange (draft state lives at
21
+ * the call site). Any `minLength`/`maxLength` the caller supplies MUST come from a caller-owned
22
+ * constant — this component declares no business numbers and no copy; it only derives the gate + the
23
+ * Textarea `maxLength` from the values it is handed.
24
+ */
25
+ export interface ConsequenceDialogReason {
26
+ required?: boolean;
27
+ minLength?: number;
28
+ maxLength?: number;
29
+ placeholder?: string;
30
+ label?: React.ReactNode;
31
+ value: string;
32
+ onChange: (value: string) => void;
33
+ rows?: number;
34
+ }
35
+
36
+ /**
37
+ * The exact-match typed-confirmation gate. `phrase` is business copy owned by the CALLER; the
38
+ * component only compares the typed value against it.
39
+ */
40
+ export interface ConsequenceDialogTypedConfirmation {
41
+ phrase: string;
42
+ label?: React.ReactNode;
43
+ }
44
+
45
+ export interface ConsequenceDialogProps {
46
+ /** Uncontrolled open model: the element that opens the dialog (rendered `asChild`). */
47
+ trigger?: React.ReactNode;
48
+ /** Controlled open model. Provide with `onOpenChange`. */
49
+ open?: boolean;
50
+ onOpenChange?: (open: boolean) => void;
51
+
52
+ /** Heading — a string or node so callers can interpolate amounts / names. */
53
+ title: React.ReactNode;
54
+
55
+ /** SLOT 1 — what happens right now (e.g. "initiates a Stripe refund of $X now"). */
56
+ immediateEffect?: React.ReactNode;
57
+ /** SLOT 2 — what settles later, out of band (webhook / worker / async confirmation). */
58
+ delayedEffect?: React.ReactNode;
59
+ /** SLOT 3 — whether/how this can be undone or superseded. */
60
+ reversibility?: React.ReactNode;
61
+
62
+ /** Inline required-reason field. Optional. */
63
+ reason?: ConsequenceDialogReason;
64
+ /** Exact-phrase typed-confirmation gate. Optional. */
65
+ typedConfirmation?: ConsequenceDialogTypedConfirmation;
66
+
67
+ confirmLabel: React.ReactNode;
68
+ cancelLabel?: React.ReactNode;
69
+ /** `true` styles the confirm button with `bg-destructive`. */
70
+ destructive?: boolean;
71
+
72
+ /**
73
+ * Runs on confirm. May be async — while it is pending the dialog STAYS OPEN, both buttons disable,
74
+ * and a `Loader2` spins in the confirm button. Closes on resolve. If it rejects the dialog
75
+ * stays open so the caller's own surface (error toast, TOTP step-up) can show and the operator can
76
+ * retry or cancel. This component takes no Sentry/monitoring dependency — every error path
77
+ * belongs to the caller's `onConfirm`.
78
+ */
79
+ onConfirm: () => void | Promise<void>;
80
+ }
81
+
82
+ const SLOT_ICON_CLASS = 'icon-xs mt-0.5 shrink-0 text-muted-foreground';
83
+
84
+ function ConsequenceRow({
85
+ icon: Icon,
86
+ label,
87
+ children,
88
+ }: {
89
+ icon: typeof Zap;
90
+ label: string;
91
+ children: React.ReactNode;
92
+ }) {
93
+ return (
94
+ <span className="flex items-start gap-2">
95
+ <Icon className={SLOT_ICON_CLASS} aria-hidden="true" />
96
+ <span className="stack-1 min-w-0">
97
+ <span className="text-caption font-medium uppercase tracking-wide text-muted-foreground">
98
+ {label}
99
+ </span>
100
+ <span className="text-small text-foreground">{children}</span>
101
+ </span>
102
+ </span>
103
+ );
104
+ }
105
+
106
+ /**
107
+ * A reusable confirm-before-a-consequential-action dialog. Three optional, consistently-styled
108
+ * consequence slots (immediate / afterward / reversibility), an optional inline required-reason field,
109
+ * and an optional exact-phrase typed-confirmation gate. Composes the ui-core AlertDialog primitives
110
+ * (Radix) — it never re-implements them. Supports BOTH a `trigger` (uncontrolled) and `open` /
111
+ * `onOpenChange` (controlled).
112
+ *
113
+ * Pending model: the confirm button is a plain `Button` (NOT `AlertDialogAction`), so Radix does not
114
+ * auto-close on click; open state is managed here so the dialog stays open with a visible spinner
115
+ * until `onConfirm` resolves.
116
+ */
117
+ export function ConsequenceDialog({
118
+ trigger,
119
+ open,
120
+ onOpenChange,
121
+ title,
122
+ immediateEffect,
123
+ delayedEffect,
124
+ reversibility,
125
+ reason,
126
+ typedConfirmation,
127
+ confirmLabel,
128
+ cancelLabel = 'Cancel',
129
+ destructive = false,
130
+ onConfirm,
131
+ }: ConsequenceDialogProps) {
132
+ const isControlled = open !== undefined;
133
+ const [internalOpen, setInternalOpen] = useState(false);
134
+ const [typedValue, setTypedValue] = useState('');
135
+ const [pending, setPending] = useState(false);
136
+
137
+ const actualOpen = isControlled ? open : internalOpen;
138
+
139
+ const reasonId = useId();
140
+ const typedId = useId();
141
+
142
+ const setOpenState = useCallback(
143
+ (next: boolean) => {
144
+ if (isControlled) onOpenChange?.(next);
145
+ else setInternalOpen(next);
146
+ },
147
+ [isControlled, onOpenChange],
148
+ );
149
+
150
+ // Never allow an open-state change (Escape, cancel, controlled parent) to fight the pending action.
151
+ const handleOpenChange = useCallback(
152
+ (next: boolean) => {
153
+ if (pending) return;
154
+ setTypedValue(''); // reset the typed gate on every open/close
155
+ setOpenState(next);
156
+ },
157
+ [pending, setOpenState],
158
+ );
159
+
160
+ const handleConfirm = useCallback(async () => {
161
+ if (pending) return;
162
+ setPending(true);
163
+ try {
164
+ await onConfirm();
165
+ setTypedValue('');
166
+ setOpenState(false);
167
+ } catch {
168
+ // Keep the dialog open — the caller's onConfirm surfaced the error (toast / step-up). The
169
+ // operator can retry or cancel. Never rethrow, never monitor here.
170
+ } finally {
171
+ setPending(false);
172
+ }
173
+ }, [pending, onConfirm, setOpenState]);
174
+
175
+ const reasonTrimmedLength = reason ? reason.value.trim().length : 0;
176
+ const reasonProvided = reasonTrimmedLength > 0;
177
+ const reasonOk = !reason
178
+ ? true
179
+ : reason.required && !reasonProvided
180
+ ? false
181
+ : !reasonProvided
182
+ ? true // optional + empty is fine
183
+ : (reason.minLength === undefined || reasonTrimmedLength >= reason.minLength) &&
184
+ (reason.maxLength === undefined || reason.value.length <= reason.maxLength);
185
+
186
+ const typedOk = !typedConfirmation ? true : typedValue === typedConfirmation.phrase;
187
+ const confirmDisabled = pending || !reasonOk || !typedOk;
188
+
189
+ return (
190
+ <AlertDialog open={actualOpen} onOpenChange={handleOpenChange}>
191
+ {trigger ? <AlertDialogTrigger asChild>{trigger}</AlertDialogTrigger> : null}
192
+ <AlertDialogContent
193
+ onEscapeKeyDown={(e) => {
194
+ if (pending) e.preventDefault();
195
+ }}
196
+ >
197
+ <AlertDialogHeader>
198
+ <AlertDialogTitle>{title}</AlertDialogTitle>
199
+ <AlertDialogDescription asChild>
200
+ <span className="stack-3">
201
+ {immediateEffect ? (
202
+ <ConsequenceRow icon={Zap} label="Immediately">
203
+ {immediateEffect}
204
+ </ConsequenceRow>
205
+ ) : null}
206
+ {delayedEffect ? (
207
+ <ConsequenceRow icon={Clock} label="Afterward">
208
+ {delayedEffect}
209
+ </ConsequenceRow>
210
+ ) : null}
211
+ {reversibility ? (
212
+ <ConsequenceRow icon={RotateCcw} label="Reversibility">
213
+ {reversibility}
214
+ </ConsequenceRow>
215
+ ) : null}
216
+ </span>
217
+ </AlertDialogDescription>
218
+ </AlertDialogHeader>
219
+
220
+ {reason ? (
221
+ <div className="stack-2">
222
+ <Label htmlFor={reasonId}>{reason.label ?? 'Reason'}</Label>
223
+ <Textarea
224
+ id={reasonId}
225
+ value={reason.value}
226
+ onChange={(e) => reason.onChange(e.target.value)}
227
+ placeholder={reason.placeholder}
228
+ maxLength={reason.maxLength}
229
+ rows={reason.rows ?? 3}
230
+ disabled={pending}
231
+ />
232
+ </div>
233
+ ) : null}
234
+
235
+ {typedConfirmation ? (
236
+ <div className="stack-2">
237
+ <Label htmlFor={typedId}>
238
+ {typedConfirmation.label ?? (
239
+ <>
240
+ Type <span className="font-mono">{typedConfirmation.phrase}</span> to confirm
241
+ </>
242
+ )}
243
+ </Label>
244
+ <Input
245
+ id={typedId}
246
+ value={typedValue}
247
+ onChange={(e) => setTypedValue(e.target.value)}
248
+ placeholder={typedConfirmation.phrase}
249
+ disabled={pending}
250
+ autoComplete="off"
251
+ />
252
+ </div>
253
+ ) : null}
254
+
255
+ <AlertDialogFooter>
256
+ <Button
257
+ variant="outline"
258
+ onClick={() => handleOpenChange(false)}
259
+ disabled={pending}
260
+ >
261
+ {cancelLabel}
262
+ </Button>
263
+ <Button
264
+ variant={destructive ? 'destructive' : 'default'}
265
+ onClick={handleConfirm}
266
+ disabled={confirmDisabled}
267
+ aria-busy={pending}
268
+ >
269
+ {pending ? <Loader2 className="mr-2 spinner-xs" aria-hidden="true" /> : null}
270
+ {confirmLabel}
271
+ </Button>
272
+ </AlertDialogFooter>
273
+ </AlertDialogContent>
274
+ </AlertDialog>
275
+ );
276
+ }
@@ -1,7 +1,7 @@
1
1
  "use client"
2
2
 
3
3
  import * as React from "react"
4
- import { ChevronLeft, ChevronRight, ChevronUp, ChevronDown } from "lucide-react"
4
+ import { ChevronLeft, ChevronRight } from "lucide-react"
5
5
  import { Button } from "./button.js"
6
6
  import { cn } from "../../lib/utils.js"
7
7
 
@@ -19,8 +19,20 @@ const MONTHS = [
19
19
  "July", "August", "September", "October", "November", "December",
20
20
  ]
21
21
 
22
+ const MONTHS_SHORT = [
23
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
24
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
25
+ ]
26
+
22
27
  const DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
23
28
 
29
+ const YEARS_PER_PAGE = 12
30
+
31
+ /** Calendar with fast month/year navigation: the header's month and year are
32
+ * each buttons — month opens a 12-month grid, year opens a paged 12-year
33
+ * grid (no single-step year arrows; distant years are a couple of clicks).
34
+ * Picking a year drills to the month grid, then the day grid — the natural
35
+ * date-of-birth path — while picking just a month returns straight to days. */
24
36
  function DatePicker({
25
37
  selected,
26
38
  onSelect,
@@ -30,7 +42,10 @@ function DatePicker({
30
42
  className,
31
43
  }: DatePickerProps) {
32
44
  const [viewDate, setViewDate] = React.useState(() => selected || new Date())
33
- const [showYearPicker, setShowYearPicker] = React.useState(false)
45
+ const [view, setView] = React.useState<"days" | "months" | "years">("days")
46
+ const [yearPageStart, setYearPageStart] = React.useState(
47
+ () => Math.floor((selected || new Date()).getFullYear() / YEARS_PER_PAGE) * YEARS_PER_PAGE,
48
+ )
34
49
 
35
50
  const today = new Date()
36
51
  today.setHours(0, 0, 0, 0)
@@ -58,6 +73,19 @@ function DatePicker({
58
73
  return false
59
74
  }
60
75
 
76
+ /** A whole month is unpickable only when every day in it is out of range. */
77
+ const isMonthDisabled = (year: number, month: number) => {
78
+ if (disableFuture && new Date(year, month, 1) > today) return true
79
+ if (disablePast && new Date(year, month + 1, 0) < today) return true
80
+ return false
81
+ }
82
+
83
+ const isYearDisabled = (year: number) => {
84
+ if (disableFuture && year > today.getFullYear()) return true
85
+ if (disablePast && year < today.getFullYear()) return true
86
+ return false
87
+ }
88
+
61
89
  const isDateSelected = (date: Date) => {
62
90
  if (!selected) return false
63
91
  const selectedDate = new Date(selected)
@@ -90,114 +118,218 @@ function DatePicker({
90
118
  const previousMonth = () => setViewDate((prev) => new Date(prev.getFullYear(), prev.getMonth() - 1))
91
119
  const nextMonth = () => setViewDate((prev) => new Date(prev.getFullYear(), prev.getMonth() + 1))
92
120
 
93
- const previousYear = () => setViewDate((prev) => new Date(prev.getFullYear() - 1, prev.getMonth()))
94
- const nextYear = () => setViewDate((prev) => new Date(prev.getFullYear() + 1, prev.getMonth()))
95
-
96
121
  const handleDateClick = (date: Date) => {
97
122
  if (isDateDisabled(date)) return
98
123
  onSelect?.(date)
99
124
  }
100
125
 
126
+ const openYears = () => {
127
+ setYearPageStart(Math.floor(viewDate.getFullYear() / YEARS_PER_PAGE) * YEARS_PER_PAGE)
128
+ setView("years")
129
+ }
130
+
101
131
  const calendarDays = generateCalendarDays()
132
+ const yearPage = Array.from({ length: YEARS_PER_PAGE }, (_, i) => yearPageStart + i)
102
133
 
103
134
  return (
104
135
  <div className={cn("p-4 bg-card rounded-lg", className)}>
105
136
  <div className="flex items-center justify-between mb-4">
106
- <Button variant="default" size="sm" className="h-8 w-8 p-0" onClick={previousMonth}>
137
+ <Button
138
+ variant="default"
139
+ size="sm"
140
+ className={cn("h-8 w-8 p-0", view !== "days" && "invisible")}
141
+ aria-label="Previous month"
142
+ onClick={previousMonth}
143
+ >
107
144
  <ChevronLeft className="h-4 w-4" />
108
145
  </Button>
109
146
 
110
- <div className="flex items-center gap-2">
147
+ {/* Month and year are EACH pickers: month → 12-month grid; year →
148
+ paged 12-year grid. No single-step year arrows. */}
149
+ <div className="flex items-center gap-1.5">
111
150
  <button
112
- onClick={() => setShowYearPicker(!showYearPicker)}
113
- className="text-base font-bold hover:opacity-80 transition-opacity text-foreground"
151
+ type="button"
152
+ onClick={() => setView(view === "months" ? "days" : "months")}
153
+ aria-expanded={view === "months"}
154
+ className="text-base font-bold hover:opacity-80 transition-opacity text-foreground underline decoration-1 underline-offset-4 decoration-border"
114
155
  >
115
- {MONTHS[viewDate.getMonth()]} {viewDate.getFullYear()}
156
+ {MONTHS[viewDate.getMonth()]}
157
+ </button>
158
+ <button
159
+ type="button"
160
+ onClick={() => (view === "years" ? setView("days") : openYears())}
161
+ aria-expanded={view === "years"}
162
+ className="text-base font-bold hover:opacity-80 transition-opacity text-foreground underline decoration-1 underline-offset-4 decoration-border"
163
+ >
164
+ {viewDate.getFullYear()}
116
165
  </button>
117
-
118
- {showYearPicker && (
119
- <div className="flex flex-col gap-1">
120
- <Button variant="ghost" size="sm" className="h-4 w-4 p-0" onClick={nextYear}>
121
- <ChevronUp className="h-3 w-3" />
122
- </Button>
123
- <Button variant="ghost" size="sm" className="h-4 w-4 p-0" onClick={previousYear}>
124
- <ChevronDown className="h-3 w-3" />
125
- </Button>
126
- </div>
127
- )}
128
166
  </div>
129
167
 
130
- <Button variant="default" size="sm" className="h-8 w-8 p-0" onClick={nextMonth}>
168
+ <Button
169
+ variant="default"
170
+ size="sm"
171
+ className={cn("h-8 w-8 p-0", view !== "days" && "invisible")}
172
+ aria-label="Next month"
173
+ onClick={nextMonth}
174
+ >
131
175
  <ChevronRight className="h-4 w-4" />
132
176
  </Button>
133
177
  </div>
134
178
 
135
- <div className="grid grid-cols-7 gap-1 mb-2">
136
- {DAYS.map((day) => (
137
- <div
138
- key={day}
139
- className="text-center text-sm font-bold py-2 text-foreground"
140
- >
141
- {day}
142
- </div>
143
- ))}
144
- </div>
145
-
146
- <div className="grid grid-cols-7 gap-1">
147
- {calendarDays.map((date, index) => {
148
- if (!date) return <div key={`empty-${index}`} className="h-9" />
149
-
150
- const disabled = isDateDisabled(date)
151
- const selected = isDateSelected(date)
152
- const todayDate = isToday(date)
153
-
154
- return (
155
- <button
156
- key={date.toISOString()}
157
- onClick={() => handleDateClick(date)}
158
- disabled={disabled}
159
- className={cn(
160
- "h-9 w-9 rounded-lg text-sm font-semibold transition-all",
161
- "hover:scale-105 active:scale-95",
162
- "flex items-center justify-center",
163
- !disabled && !selected && !todayDate && "text-foreground hover:bg-primary/10",
164
- todayDate && !selected && "bg-accent text-foreground font-bold ring-2 ring-border",
165
- selected && "bg-primary text-white font-bold shadow-lg",
166
- disabled && "opacity-30 cursor-not-allowed hover:scale-100 hover:bg-transparent",
167
- disabled && "relative"
168
- )}
179
+ {view === "years" && (
180
+ <>
181
+ <div className="flex items-center justify-between mb-2">
182
+ <Button
183
+ variant="ghost"
184
+ size="sm"
185
+ className="h-8 w-8 p-0"
186
+ aria-label={`Previous ${YEARS_PER_PAGE} years`}
187
+ onClick={() => setYearPageStart((s) => s - YEARS_PER_PAGE)}
169
188
  >
170
- {date.getDate()}
171
- {disabled && (
172
- <div className="absolute inset-0 flex items-center justify-center">
173
- <div className="w-px h-full bg-current transform rotate-45" />
174
- </div>
175
- )}
176
- </button>
177
- )
178
- })}
179
- </div>
180
-
181
- <div className="mt-4 pt-3 border-t border-border text-xs space-y-1">
182
- <div className="flex items-center gap-2">
183
- <div className="h-3 w-3 rounded-sm bg-primary" />
184
- <span className="text-muted-foreground">Selected</span>
185
- </div>
186
- <div className="flex items-center gap-2">
187
- <div className="h-3 w-3 rounded-sm bg-accent ring-2 ring-border" />
188
- <span className="text-muted-foreground">Today</span>
189
+ <ChevronLeft className="h-4 w-4" />
190
+ </Button>
191
+ <span className="text-sm font-semibold text-muted-foreground">
192
+ {yearPageStart} – {yearPageStart + YEARS_PER_PAGE - 1}
193
+ </span>
194
+ <Button
195
+ variant="ghost"
196
+ size="sm"
197
+ className="h-8 w-8 p-0"
198
+ aria-label={`Next ${YEARS_PER_PAGE} years`}
199
+ onClick={() => setYearPageStart((s) => s + YEARS_PER_PAGE)}
200
+ >
201
+ <ChevronRight className="h-4 w-4" />
202
+ </Button>
203
+ </div>
204
+ <div className="grid grid-cols-3 gap-1">
205
+ {yearPage.map((year) => {
206
+ const yearDisabled = isYearDisabled(year)
207
+ const isViewYear = year === viewDate.getFullYear()
208
+ return (
209
+ <button
210
+ key={year}
211
+ type="button"
212
+ disabled={yearDisabled}
213
+ onClick={() => {
214
+ setViewDate((prev) => new Date(year, prev.getMonth()))
215
+ setView("months")
216
+ }}
217
+ className={cn(
218
+ "h-10 rounded-lg text-sm font-semibold transition-all",
219
+ "flex items-center justify-center",
220
+ !yearDisabled && !isViewYear && "text-foreground hover:bg-primary/10",
221
+ isViewYear && "bg-primary text-white font-bold shadow-lg",
222
+ yearDisabled && "opacity-30 cursor-not-allowed",
223
+ )}
224
+ >
225
+ {year}
226
+ </button>
227
+ )
228
+ })}
229
+ </div>
230
+ </>
231
+ )}
232
+
233
+ {view === "months" && (
234
+ <div className="grid grid-cols-3 gap-1">
235
+ {MONTHS_SHORT.map((label, month) => {
236
+ const monthDisabled = isMonthDisabled(viewDate.getFullYear(), month)
237
+ const isViewMonth = month === viewDate.getMonth()
238
+ return (
239
+ <button
240
+ key={label}
241
+ type="button"
242
+ disabled={monthDisabled}
243
+ onClick={() => {
244
+ setViewDate((prev) => new Date(prev.getFullYear(), month))
245
+ setView("days")
246
+ }}
247
+ className={cn(
248
+ "h-10 rounded-lg text-sm font-semibold transition-all",
249
+ "flex items-center justify-center",
250
+ !monthDisabled && !isViewMonth && "text-foreground hover:bg-primary/10",
251
+ isViewMonth && "bg-primary text-white font-bold shadow-lg",
252
+ monthDisabled && "opacity-30 cursor-not-allowed",
253
+ )}
254
+ >
255
+ {label}
256
+ </button>
257
+ )
258
+ })}
189
259
  </div>
190
- {(disablePast || disableFuture || disabled) && (
191
- <div className="flex items-center gap-2">
192
- <div className="h-3 w-3 rounded-sm bg-muted opacity-30 relative">
193
- <div className="absolute inset-0 flex items-center justify-center">
194
- <div className="w-px h-full bg-foreground transform rotate-45" />
260
+ )}
261
+
262
+ {view === "days" && (
263
+ <>
264
+ <div className="grid grid-cols-7 gap-1 mb-2">
265
+ {DAYS.map((day) => (
266
+ <div
267
+ key={day}
268
+ className="text-center text-sm font-bold py-2 text-foreground"
269
+ >
270
+ {day}
195
271
  </div>
272
+ ))}
273
+ </div>
274
+
275
+ <div className="grid grid-cols-7 gap-1">
276
+ {calendarDays.map((date, index) => {
277
+ if (!date) return <div key={`empty-${index}`} className="h-9" />
278
+
279
+ const dateDisabled = isDateDisabled(date)
280
+ const dateSelected = isDateSelected(date)
281
+ const todayDate = isToday(date)
282
+
283
+ return (
284
+ <button
285
+ key={date.toISOString()}
286
+ type="button"
287
+ onClick={() => handleDateClick(date)}
288
+ disabled={dateDisabled}
289
+ className={cn(
290
+ "h-9 w-9 rounded-lg text-sm font-semibold transition-all",
291
+ "hover:scale-105 active:scale-95",
292
+ "flex items-center justify-center",
293
+ !dateDisabled && !dateSelected && !todayDate && "text-foreground hover:bg-primary/10",
294
+ todayDate && !dateSelected && "bg-accent text-foreground font-bold ring-2 ring-border",
295
+ dateSelected && "bg-primary text-white font-bold shadow-lg",
296
+ dateDisabled && "opacity-30 cursor-not-allowed hover:scale-100 hover:bg-transparent",
297
+ dateDisabled && "relative"
298
+ )}
299
+ >
300
+ {date.getDate()}
301
+ {dateDisabled && (
302
+ <div className="absolute inset-0 flex items-center justify-center">
303
+ <div className="w-px h-full bg-current transform rotate-45" />
304
+ </div>
305
+ )}
306
+ </button>
307
+ )
308
+ })}
309
+ </div>
310
+
311
+ <div className="mt-4 pt-3 border-t border-border text-xs space-y-1">
312
+ <div className="flex items-center gap-2">
313
+ <div className="h-3 w-3 rounded-sm bg-primary" />
314
+ <span className="text-muted-foreground">Selected</span>
196
315
  </div>
197
- <span className="text-muted-foreground">Unavailable</span>
316
+ <div className="flex items-center gap-2">
317
+ <div className="h-3 w-3 rounded-sm bg-accent ring-2 ring-border" />
318
+ <span className="text-muted-foreground">Today</span>
319
+ </div>
320
+ {(disablePast || disableFuture || disabled) && (
321
+ <div className="flex items-center gap-2">
322
+ <div className="h-3 w-3 rounded-sm bg-muted opacity-30 relative">
323
+ <div className="absolute inset-0 flex items-center justify-center">
324
+ <div className="w-px h-full bg-foreground transform rotate-45" />
325
+ </div>
326
+ </div>
327
+ <span className="text-muted-foreground">Unavailable</span>
328
+ </div>
329
+ )}
198
330
  </div>
199
- )}
200
- </div>
331
+ </>
332
+ )}
201
333
  </div>
202
334
  )
203
335
  }
@@ -41,6 +41,9 @@ export { Collapsible, CollapsibleTrigger, CollapsibleContent } from "./component
41
41
  export type { SearchDropdownProps } from "./components/search-dropdown.js";
42
42
  export { SearchDropdown } from "./components/search-dropdown.js";
43
43
 
44
+ export type { ConsequenceDialogProps, ConsequenceDialogReason, ConsequenceDialogTypedConfirmation } from "./components/consequence-dialog.js";
45
+ export { ConsequenceDialog } from "./components/consequence-dialog.js";
46
+
44
47
  export type { MaxWidthOption, ScreenAdaptiveViewProps } from "./components/layout/screen-adaptive-view.js";
45
48
  export { ScreenAdaptiveView } from "./components/layout/screen-adaptive-view.js";
46
49