@actioneer/ads 0.5.9 → 0.6.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.
@@ -0,0 +1,25 @@
1
+ import * as React from "react";
2
+ export type DateRangeValue = {
3
+ start: string;
4
+ end: string;
5
+ };
6
+ export interface DateRangePickerProps {
7
+ value?: DateRangeValue | null;
8
+ defaultValue?: DateRangeValue | null;
9
+ onChange?: (value: DateRangeValue | null) => void;
10
+ label?: React.ReactNode;
11
+ description?: React.ReactNode;
12
+ errorMessage?: React.ReactNode;
13
+ size?: "sm" | "md";
14
+ disabled?: boolean;
15
+ minValue?: string;
16
+ maxValue?: string;
17
+ className?: string;
18
+ "aria-label"?: string;
19
+ }
20
+ /**
21
+ * ADS date-range picker, adapted from HeroUI's composition-first pattern.
22
+ * React Aria owns keyboard, focus, locale, and range-selection behavior while
23
+ * ADS owns every visual token, state, radius, and elevation.
24
+ */
25
+ export declare function DateRangePicker({ value, defaultValue, onChange, label, description, errorMessage, size, disabled, minValue, maxValue, className, "aria-label": ariaLabel, }: DateRangePickerProps): React.JSX.Element;
@@ -0,0 +1,187 @@
1
+ "use client";
2
+ import { jsxs as a, jsx as e } from "react/jsx-runtime";
3
+ import * as x from "react";
4
+ import { parseDate as u } from "@internationalized/date";
5
+ import { DateRangePicker as H, Label as I, Group as L, DateInput as b, DateSegment as p, Button as l, Text as h, Popover as O, Dialog as T, RangeCalendar as $, Heading as q, CalendarGrid as A, CalendarGridHeader as E, CalendarHeaderCell as F, CalendarGridBody as J, CalendarCell as K } from "react-aria-components";
6
+ import { Calendar as M, ChevronLeft as Q, ChevronRight as U } from "../lib/icons.js";
7
+ import { cn as n } from "../lib/cn.js";
8
+ function N(r) {
9
+ if (!(r != null && r.start) || !r.end) return null;
10
+ try {
11
+ return {
12
+ start: u(r.start),
13
+ end: u(r.end)
14
+ };
15
+ } catch {
16
+ return null;
17
+ }
18
+ }
19
+ function y(r) {
20
+ if (r)
21
+ try {
22
+ return u(r);
23
+ } catch {
24
+ return;
25
+ }
26
+ }
27
+ function W(r) {
28
+ return r ? {
29
+ start: r.start.toString(),
30
+ end: r.end.toString()
31
+ } : null;
32
+ }
33
+ const X = {
34
+ sm: {
35
+ group: "min-h-8 rounded-sm text-xs",
36
+ trigger: "size-7 rounded-sm"
37
+ },
38
+ md: {
39
+ group: "min-h-10 rounded-md text-sm",
40
+ trigger: "size-8 rounded-sm"
41
+ }
42
+ };
43
+ function te({
44
+ value: r,
45
+ defaultValue: m,
46
+ onChange: d,
47
+ label: c,
48
+ description: g,
49
+ errorMessage: s,
50
+ size: v = "md",
51
+ disabled: w,
52
+ minValue: z,
53
+ maxValue: k,
54
+ className: D,
55
+ "aria-label": C
56
+ }) {
57
+ const f = X[v], R = x.useMemo(() => N(r), [r]), j = x.useMemo(
58
+ () => N(m),
59
+ [m]
60
+ );
61
+ return /* @__PURE__ */ a(
62
+ H,
63
+ {
64
+ "aria-label": C,
65
+ className: n("flex w-full flex-col gap-1.5", D),
66
+ value: r === void 0 ? void 0 : R,
67
+ defaultValue: j ?? void 0,
68
+ isDisabled: w,
69
+ minValue: y(z),
70
+ maxValue: y(k),
71
+ isInvalid: !!s,
72
+ onChange: (t) => d == null ? void 0 : d(W(t)),
73
+ children: [
74
+ c && /* @__PURE__ */ e(I, { className: "text-xs font-medium text-foreground", children: c }),
75
+ /* @__PURE__ */ a(
76
+ L,
77
+ {
78
+ className: n(
79
+ "flex w-full items-center gap-1 border border-input bg-background px-2 text-foreground shadow-xs outline-none transition-[border-color,box-shadow,background-color]",
80
+ "hover:bg-muted/40 focus-within:border-ring focus-within:ring-3 focus-within:ring-ring",
81
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
82
+ "data-[invalid]:border-danger data-[invalid]:ring-danger/20",
83
+ f.group
84
+ ),
85
+ children: [
86
+ /* @__PURE__ */ e(b, { slot: "start", className: "flex min-w-0 flex-1 items-center", children: (t) => /* @__PURE__ */ e(
87
+ p,
88
+ {
89
+ segment: t,
90
+ className: ({ isFocused: i, isPlaceholder: o }) => n(
91
+ "rounded-xs px-0.5 tabular-nums outline-none",
92
+ o && "text-muted-foreground",
93
+ i && "bg-primary text-primary-foreground"
94
+ )
95
+ }
96
+ ) }),
97
+ /* @__PURE__ */ e("span", { "aria-hidden": "true", className: "shrink-0 text-muted-foreground", children: "–" }),
98
+ /* @__PURE__ */ e(b, { slot: "end", className: "flex min-w-0 flex-1 items-center", children: (t) => /* @__PURE__ */ e(
99
+ p,
100
+ {
101
+ segment: t,
102
+ className: ({ isFocused: i, isPlaceholder: o }) => n(
103
+ "rounded-xs px-0.5 tabular-nums outline-none",
104
+ o && "text-muted-foreground",
105
+ i && "bg-primary text-primary-foreground"
106
+ )
107
+ }
108
+ ) }),
109
+ /* @__PURE__ */ e(
110
+ l,
111
+ {
112
+ "aria-label": "Open calendar",
113
+ className: n(
114
+ "ml-auto inline-flex shrink-0 items-center justify-center border border-transparent text-muted-foreground outline-none transition-colors",
115
+ "hover:bg-muted hover:text-foreground focus-visible:ring-3 focus-visible:ring-ring data-[pressed]:bg-muted",
116
+ f.trigger
117
+ ),
118
+ children: /* @__PURE__ */ e(M, { className: "size-4" })
119
+ }
120
+ )
121
+ ]
122
+ }
123
+ ),
124
+ g && !s && /* @__PURE__ */ e(h, { slot: "description", className: "text-xs text-muted-foreground", children: g }),
125
+ s && /* @__PURE__ */ e(h, { slot: "errorMessage", className: "text-xs text-danger", children: s }),
126
+ /* @__PURE__ */ e(
127
+ O,
128
+ {
129
+ placement: "bottom end",
130
+ offset: 6,
131
+ className: "z-50 w-72 rounded-md border border-border bg-popover p-3 text-popover-foreground shadow-elevation outline-none entering:animate-in entering:fade-in entering:zoom-in-95 exiting:animate-out exiting:fade-out exiting:zoom-out-95",
132
+ children: /* @__PURE__ */ e(T, { className: "outline-none", children: /* @__PURE__ */ a($, { className: "w-full", visibleDuration: { months: 1 }, children: [
133
+ /* @__PURE__ */ a("header", { className: "mb-3 flex items-center justify-between gap-2", children: [
134
+ /* @__PURE__ */ e(
135
+ l,
136
+ {
137
+ slot: "previous",
138
+ className: "inline-flex size-8 items-center justify-center rounded-sm border border-input bg-background text-foreground outline-none hover:bg-muted focus-visible:ring-3 focus-visible:ring-ring disabled:opacity-40",
139
+ children: /* @__PURE__ */ e(Q, { className: "size-4" })
140
+ }
141
+ ),
142
+ /* @__PURE__ */ e(q, { className: "text-sm font-semibold" }),
143
+ /* @__PURE__ */ e(
144
+ l,
145
+ {
146
+ slot: "next",
147
+ className: "inline-flex size-8 items-center justify-center rounded-sm border border-input bg-background text-foreground outline-none hover:bg-muted focus-visible:ring-3 focus-visible:ring-ring disabled:opacity-40",
148
+ children: /* @__PURE__ */ e(U, { className: "size-4" })
149
+ }
150
+ )
151
+ ] }),
152
+ /* @__PURE__ */ a(A, { weekdayStyle: "short", className: "w-full border-separate border-spacing-0.5", children: [
153
+ /* @__PURE__ */ e(E, { children: (t) => /* @__PURE__ */ e(F, { className: "h-7 text-center text-xs font-medium text-muted-foreground", children: t }) }),
154
+ /* @__PURE__ */ e(J, { children: (t) => /* @__PURE__ */ e(
155
+ K,
156
+ {
157
+ date: t,
158
+ className: ({
159
+ isDisabled: i,
160
+ isFocusVisible: o,
161
+ isOutsideMonth: B,
162
+ isSelected: G,
163
+ isSelectionEnd: P,
164
+ isSelectionStart: S,
165
+ isUnavailable: V
166
+ }) => n(
167
+ "relative flex size-8 items-center justify-center rounded-sm text-xs tabular-nums outline-none transition-colors",
168
+ "hover:bg-muted",
169
+ G && "bg-muted font-medium text-foreground",
170
+ (S || P) && "bg-primary text-primary-foreground hover:bg-primary",
171
+ B && "text-muted-foreground/45",
172
+ (i || V) && "pointer-events-none text-muted-foreground/35 line-through",
173
+ o && "ring-3 ring-ring"
174
+ )
175
+ }
176
+ ) })
177
+ ] })
178
+ ] }) })
179
+ }
180
+ )
181
+ ]
182
+ }
183
+ );
184
+ }
185
+ export {
186
+ te as DateRangePicker
187
+ };
@@ -1,12 +1,12 @@
1
1
  "use client";
2
- import { jsx as i, jsxs as v } from "react/jsx-runtime";
2
+ import { jsx as i, jsxs as b } from "react/jsx-runtime";
3
3
  import * as a from "react";
4
- import { createPortal as R } from "react-dom";
5
- import { MotionConfig as b, AnimatePresence as z, motion as h } from "motion/react";
6
- import { Close as E } from "../lib/icons.js";
4
+ import { createPortal as E } from "react-dom";
5
+ import { MotionConfig as y, AnimatePresence as z, motion as w } from "motion/react";
6
+ import { Close as R } from "../lib/icons.js";
7
7
  import { cva as j } from "class-variance-authority";
8
- import { cn as l } from "../lib/cn.js";
9
- import { springSheet as c, drawerOffset as m, drawerBackdropVariants as F } from "../lib/motion.js";
8
+ import { cn as n } from "../lib/cn.js";
9
+ import { springSheet as l, drawerOffset as h, drawerBackdropVariants as F } from "../lib/motion.js";
10
10
  const N = j(
11
11
  [
12
12
  "relative flex flex-col",
@@ -47,6 +47,11 @@ const N = j(
47
47
  right: "justify-end items-stretch",
48
48
  left: "justify-start items-stretch",
49
49
  bottom: "justify-center items-end"
50
+ }, B = {
51
+ sm: "25%",
52
+ md: "33.333333%",
53
+ lg: "50%",
54
+ xl: "66.666667%"
50
55
  };
51
56
  function k({
52
57
  onClick: t,
@@ -58,7 +63,7 @@ function k({
58
63
  type: "button",
59
64
  onClick: t,
60
65
  "aria-label": "Close",
61
- className: l(
66
+ className: n(
62
67
  "absolute inline-flex size-8 items-center justify-center",
63
68
  "rounded-sm text-muted-foreground",
64
69
  "transition-[background,color,transform] duration-150 ease-out motion-reduce:transition-none hover:bg-muted hover:text-foreground",
@@ -67,41 +72,41 @@ function k({
67
72
  "[&_svg]:size-4 [&_svg]:shrink-0",
68
73
  e
69
74
  ),
70
- children: /* @__PURE__ */ i(E, { "aria-hidden": !0 })
75
+ children: /* @__PURE__ */ i(R, { "aria-hidden": !0 })
71
76
  }
72
77
  );
73
78
  }
74
- function S({
79
+ function G({
75
80
  open: t,
76
81
  onOpenChange: e,
77
- side: r,
78
- size: f,
79
- className: u,
80
- children: w,
81
- "aria-label": x
82
+ side: s,
83
+ size: d,
84
+ className: v,
85
+ children: x,
86
+ "aria-label": g
82
87
  }) {
83
- const o = r ?? "right", d = a.useRef(null), n = a.useRef(null);
88
+ const r = s ?? "right", c = a.useRef(null), m = a.useRef(null);
84
89
  return a.useEffect(() => {
85
90
  if (!t) return;
86
- n.current = document.activeElement;
87
- const g = document.body.style.overflow;
91
+ m.current = document.activeElement;
92
+ const f = document.body.style.overflow;
88
93
  document.body.style.overflow = "hidden";
89
- const y = (s) => {
90
- s.key === "Escape" && (s.stopPropagation(), e(!1));
94
+ const u = (o) => {
95
+ o.key === "Escape" && (o.stopPropagation(), e(!1));
91
96
  };
92
- document.addEventListener("keydown", y);
97
+ document.addEventListener("keydown", u);
93
98
  const D = requestAnimationFrame(() => {
94
- var s;
95
- (s = d.current) == null || s.focus();
99
+ var o;
100
+ (o = c.current) == null || o.focus();
96
101
  });
97
102
  return () => {
98
- var s, p;
99
- document.removeEventListener("keydown", y), document.body.style.overflow = g, cancelAnimationFrame(D), (p = (s = n.current) == null ? void 0 : s.focus) == null || p.call(s);
103
+ var o, p;
104
+ document.removeEventListener("keydown", u), document.body.style.overflow = f, cancelAnimationFrame(D), (p = (o = m.current) == null ? void 0 : o.focus) == null || p.call(o);
100
105
  };
101
- }, [t, e]), R(
102
- /* @__PURE__ */ i(b, { reducedMotion: "user", children: /* @__PURE__ */ i(z, { children: t && /* @__PURE__ */ v("div", { className: l("fixed inset-0 z-50 flex", A[o]), children: [
106
+ }, [t, e]), E(
107
+ /* @__PURE__ */ i(y, { reducedMotion: "user", children: /* @__PURE__ */ i(z, { children: t && /* @__PURE__ */ b("div", { className: n("fixed inset-0 z-50 flex", A[r]), children: [
103
108
  /* @__PURE__ */ i(
104
- h.div,
109
+ w.div,
105
110
  {
106
111
  variants: F,
107
112
  initial: "hidden",
@@ -113,18 +118,18 @@ function S({
113
118
  },
114
119
  "backdrop"
115
120
  ),
116
- /* @__PURE__ */ v(
117
- h.div,
121
+ /* @__PURE__ */ b(
122
+ w.div,
118
123
  {
119
- ref: d,
120
- initial: m[o],
121
- animate: { transform: "translate3d(0, 0, 0)", opacity: 1, transition: c },
122
- exit: { ...m[o], transition: c },
124
+ ref: c,
125
+ initial: h[r],
126
+ animate: { transform: "translate3d(0, 0, 0)", opacity: 1, transition: l },
127
+ exit: { ...h[r], pointerEvents: "none", transition: l },
123
128
  role: "dialog",
124
129
  "aria-modal": "true",
125
- "aria-label": x,
130
+ "aria-label": g,
126
131
  tabIndex: -1,
127
- className: l(N({ side: o, size: f }), "relative outline-none", u),
132
+ className: n(N({ side: r, size: d }), "relative outline-none", v),
128
133
  children: [
129
134
  /* @__PURE__ */ i(
130
135
  k,
@@ -133,7 +138,7 @@ function S({
133
138
  className: "right-4 top-4"
134
139
  }
135
140
  ),
136
- w
141
+ x
137
142
  ]
138
143
  },
139
144
  "panel"
@@ -142,96 +147,109 @@ function S({
142
147
  document.body
143
148
  );
144
149
  }
145
- function B({
150
+ function L({
146
151
  open: t,
147
152
  onOpenChange: e,
148
- side: r,
149
- size: f,
150
- className: u,
151
- children: w,
152
- "aria-label": x
153
+ side: s,
154
+ size: d,
155
+ className: v,
156
+ children: x,
157
+ "aria-label": g
153
158
  }) {
154
- const o = r ?? "right", d = a.useRef(null);
159
+ const r = s ?? "right", c = d ?? "md", m = a.useRef(null);
155
160
  return a.useEffect(() => {
156
161
  if (!t) return;
157
- const n = (g) => {
158
- g.key === "Escape" && e(!1);
162
+ const f = (u) => {
163
+ u.key === "Escape" && e(!1);
159
164
  };
160
- return document.addEventListener("keydown", n), () => document.removeEventListener("keydown", n);
161
- }, [t, e]), /* @__PURE__ */ i(b, { reducedMotion: "user", children: /* @__PURE__ */ i(z, { initial: !1, children: t && /* @__PURE__ */ v(
162
- h.aside,
165
+ return document.addEventListener("keydown", f), () => document.removeEventListener("keydown", f);
166
+ }, [t, e]), /* @__PURE__ */ i(y, { reducedMotion: "user", children: /* @__PURE__ */ i(z, { initial: !1, children: t && /* @__PURE__ */ i(
167
+ w.div,
163
168
  {
164
- ref: d,
165
- initial: m[o],
166
- animate: { transform: "translate3d(0, 0, 0)", opacity: 1, transition: c },
167
- exit: { ...m[o], transition: c },
168
- role: "complementary",
169
- "aria-label": x,
170
- className: l(
171
- N({ side: o, size: f }),
172
- "relative shrink-0 overflow-hidden rounded-lg bg-card shadow-none outline-none",
173
- u
169
+ initial: r === "bottom" ? { height: "0%" } : { width: 0 },
170
+ animate: r === "bottom" ? { height: B[c], transition: l } : { width: "auto", transition: l },
171
+ exit: r === "bottom" ? { height: "0%", pointerEvents: "none", transition: l } : { width: 0, pointerEvents: "none", transition: l },
172
+ className: n(
173
+ "shrink-0 overflow-hidden",
174
+ r === "bottom" ? "w-full" : "h-full"
174
175
  ),
175
- children: [
176
- /* @__PURE__ */ i(
177
- k,
178
- {
179
- onClick: () => e(!1),
180
- className: "right-2 top-1"
181
- }
182
- ),
183
- w
184
- ]
176
+ children: /* @__PURE__ */ b(
177
+ w.aside,
178
+ {
179
+ ref: m,
180
+ initial: h[r],
181
+ animate: { transform: "translate3d(0, 0, 0)", opacity: 1, transition: l },
182
+ exit: { ...h[r], pointerEvents: "none", transition: l },
183
+ role: "complementary",
184
+ "aria-label": g,
185
+ className: n(
186
+ N({ side: r, size: d }),
187
+ "relative shrink-0 overflow-hidden rounded-lg bg-card shadow-none outline-none",
188
+ r === "bottom" && "h-full",
189
+ v
190
+ ),
191
+ children: [
192
+ /* @__PURE__ */ i(
193
+ k,
194
+ {
195
+ onClick: () => e(!1),
196
+ className: "right-2 top-1"
197
+ }
198
+ ),
199
+ x
200
+ ]
201
+ }
202
+ )
185
203
  },
186
- "inline-drawer"
204
+ "inline-drawer-slot"
187
205
  ) }) });
188
206
  }
189
- const G = B, L = a.forwardRef(({ className: t, ...e }, r) => /* @__PURE__ */ i(
207
+ const J = L, M = a.forwardRef(({ className: t, ...e }, s) => /* @__PURE__ */ i(
190
208
  "div",
191
209
  {
192
- ref: r,
193
- className: l("flex flex-col gap-1 px-6 py-4 pr-14", t),
210
+ ref: s,
211
+ className: n("flex flex-col gap-1 px-6 py-4 pr-14", t),
194
212
  ...e
195
213
  }
196
214
  ));
197
- L.displayName = "DrawerHeader";
198
- const M = a.forwardRef(({ className: t, ...e }, r) => /* @__PURE__ */ i(
215
+ M.displayName = "DrawerHeader";
216
+ const V = a.forwardRef(({ className: t, ...e }, s) => /* @__PURE__ */ i(
199
217
  "h2",
200
218
  {
201
- ref: r,
202
- className: l("text-lg font-medium text-foreground", t),
219
+ ref: s,
220
+ className: n("text-lg font-medium text-foreground", t),
203
221
  ...e
204
222
  }
205
223
  ));
206
- M.displayName = "DrawerTitle";
207
- const V = a.forwardRef(({ className: t, ...e }, r) => /* @__PURE__ */ i(
224
+ V.displayName = "DrawerTitle";
225
+ const I = a.forwardRef(({ className: t, ...e }, s) => /* @__PURE__ */ i(
208
226
  "div",
209
227
  {
210
- ref: r,
228
+ ref: s,
211
229
  tabIndex: 0,
212
- className: l("flex-1 overflow-y-auto px-6 py-4 text-xs text-foreground", t),
230
+ className: n("flex-1 overflow-y-auto px-6 py-4 text-xs text-foreground", t),
213
231
  ...e
214
232
  }
215
233
  ));
216
- V.displayName = "DrawerBody";
217
- const I = a.forwardRef(({ className: t, ...e }, r) => /* @__PURE__ */ i(
234
+ I.displayName = "DrawerBody";
235
+ const P = a.forwardRef(({ className: t, ...e }, s) => /* @__PURE__ */ i(
218
236
  "div",
219
237
  {
220
- ref: r,
221
- className: l(
238
+ ref: s,
239
+ className: n(
222
240
  "flex items-center justify-end gap-2 px-6 py-4",
223
241
  t
224
242
  ),
225
243
  ...e
226
244
  }
227
245
  ));
228
- I.displayName = "DrawerFooter";
246
+ P.displayName = "DrawerFooter";
229
247
  export {
230
- B as Drawer,
231
- V as DrawerBody,
232
- I as DrawerFooter,
233
- L as DrawerHeader,
234
- M as DrawerTitle,
235
- G as InlineDrawer,
236
- S as ModalDrawer
248
+ L as Drawer,
249
+ I as DrawerBody,
250
+ P as DrawerFooter,
251
+ M as DrawerHeader,
252
+ V as DrawerTitle,
253
+ J as InlineDrawer,
254
+ G as ModalDrawer
237
255
  };
@@ -28,6 +28,7 @@ export * from './radio';
28
28
  export * from './switch';
29
29
  export * from './number-field';
30
30
  export * from './select';
31
+ export * from './date-range-picker';
31
32
  export * from './autocomplete';
32
33
  export * from './slider';
33
34
  export * from './segmented';