beez-ui 0.6.2 → 0.7.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +134 -98
  2. package/README.md +274 -263
  3. package/dist/components/alert.js +1 -1
  4. package/dist/components/avatar.d.ts +2 -1
  5. package/dist/components/avatar.js +4 -3
  6. package/dist/components/calendar.js +102 -0
  7. package/dist/components/carousel.js +61 -48
  8. package/dist/components/checkbox.js +1 -1
  9. package/dist/components/data-table.js +34 -4
  10. package/dist/components/dropdown-menu.js +5 -2
  11. package/dist/components/filter-query-bar.js +11 -6
  12. package/dist/components/form.d.ts +5 -0
  13. package/dist/components/form.js +11 -9
  14. package/dist/components/input-group.js +1 -1
  15. package/dist/components/input.js +1 -1
  16. package/dist/components/pagination.d.ts +1 -0
  17. package/dist/components/pagination.js +9 -4
  18. package/dist/components/radio-group.js +1 -1
  19. package/dist/components/select.js +1 -1
  20. package/dist/components/sheet.js +12 -9
  21. package/dist/components/sidebar.js +9 -5
  22. package/dist/components/skeleton.d.ts +6 -0
  23. package/dist/components/skeleton.js +7 -1
  24. package/dist/components/switch.js +1 -1
  25. package/dist/components/textarea.js +1 -1
  26. package/dist/components/typing-animation.js +42 -15
  27. package/dist/lib/column-filter-value.d.ts +12 -0
  28. package/dist/lib/column-filter-value.js +52 -0
  29. package/dist/motion/glide-indicator.d.ts +37 -3
  30. package/dist/motion/glide-indicator.js +37 -3
  31. package/dist/motion/motion-slot.js +47 -18
  32. package/dist/motion/surface-keyframes.js +18 -6
  33. package/dist/motion/tokens.d.ts +24 -1
  34. package/dist/motion/tokens.js +23 -0
  35. package/dist/providers/beez-ui-provider.js +49 -17
  36. package/dist/styles.css +1 -1
  37. package/package.json +2 -2
@@ -7,10 +7,11 @@ export type AvatarImageProps = Omit<React.ComponentProps<"img">, "src"> & {
7
7
  declare function Avatar({ className, size, ...props }: AvatarPrimitive.Root.Props & {
8
8
  size?: "default" | "sm" | "lg";
9
9
  }): React.JSX.Element;
10
- /** Delegates loading, failure and fallback synchronization to the avatar primitive. */
10
+ /** Delegates loading, failure and fallback synchronization to the avatar primitive; loaded images develop in place. */
11
11
  declare function AvatarImage({ alt, className, src, ...props }: AvatarImageProps): React.JSX.Element;
12
12
  declare function AvatarFallback({ className, ...props }: AvatarPrimitive.Fallback.Props): React.JSX.Element;
13
13
  declare function AvatarBadge({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
14
+ /** Overlaps avatars; the hovered one lifts slightly above its neighbours. */
14
15
  declare function AvatarGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
15
16
  declare function AvatarGroupCount({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
16
17
  export { Avatar, AvatarImage, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarBadge, };
@@ -51,7 +51,7 @@ function Avatar(t0) {
51
51
  }
52
52
  return t3;
53
53
  }
54
- /** Delegates loading, failure and fallback synchronization to the avatar primitive. */
54
+ /** Delegates loading, failure and fallback synchronization to the avatar primitive; loaded images develop in place. */
55
55
  function AvatarImage(t0) {
56
56
  const $ = _c(15);
57
57
  let className;
@@ -94,7 +94,7 @@ function AvatarImage(t0) {
94
94
  let t6;
95
95
  if ($[9] !== alt || $[10] !== props || $[11] !== t3 || $[12] !== t4 || $[13] !== t5) {
96
96
  t6 = /* @__PURE__ */ _jsx(MotionSlot, {
97
- kind: "field",
97
+ kind: "reveal",
98
98
  children: /* @__PURE__ */ _jsx(AvatarPrimitive.Image, {
99
99
  render: t3,
100
100
  keepMounted: true,
@@ -190,6 +190,7 @@ function AvatarBadge(t0) {
190
190
  }
191
191
  return t2;
192
192
  }
193
+ /** Overlaps avatars; the hovered one lifts slightly above its neighbours. */
193
194
  function AvatarGroup(t0) {
194
195
  const $ = _c(8);
195
196
  let className;
@@ -205,7 +206,7 @@ function AvatarGroup(t0) {
205
206
  }
206
207
  let t1;
207
208
  if ($[3] !== className) {
208
- t1 = cn("group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background", className);
209
+ t1 = cn("group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background *:data-[slot=avatar]:transition-[translate] *:data-[slot=avatar]:duration-200 *:data-[slot=avatar]:ease-out *:data-[slot=avatar]:hover:z-10 *:data-[slot=avatar]:hover:-translate-y-0.5", className);
209
210
  $[3] = className;
210
211
  $[4] = t1;
211
212
  } else {
@@ -3,6 +3,9 @@ import { c as _c } from "react/compiler-runtime";
3
3
  import * as React from "react";
4
4
  import { es } from "react-day-picker/locale";
5
5
  import { DayPicker, getDefaultClassNames } from "react-day-picker";
6
+ import { animate, frame } from "motion/react";
7
+ import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
8
+ import { MOTION_EASE, MOTION_MONTH_DISTANCE, MOTION_TIMING } from "../motion/tokens.js";
6
9
  import { cn } from "../lib/utils.js";
7
10
  import { Button, buttonVariants } from "./button.js";
8
11
  import { ChevronLeft, ChevronRight, ChevronDown } from "lucide-react";
@@ -173,6 +176,7 @@ function Calendar(t0) {
173
176
  Root: _temp,
174
177
  Chevron: _temp2,
175
178
  DayButton: t34,
179
+ Month: CalendarMonth,
176
180
  WeekNumber: _temp3,
177
181
  ...components
178
182
  };
@@ -247,6 +251,104 @@ function _temp(t0) {
247
251
  ...props_0
248
252
  });
249
253
  }
254
+ /**
255
+ * Renders one displayed month and slides it in from the side the user navigated from.
256
+ * DayPicker keys months by display position, so this instance survives navigation and can
257
+ * compare the new month with the previous one. The first render and reduced motion stay static.
258
+ * @param props - DayPicker month properties, including the month being displayed.
259
+ * @returns The month container with its caption and grid.
260
+ */
261
+ function CalendarMonth(t0) {
262
+ const $ = _c(13);
263
+ let calendarMonth;
264
+ let children;
265
+ let displayIndex;
266
+ let props;
267
+ if ($[0] !== t0) {
268
+ ({calendarMonth, displayIndex, children, ...props} = t0);
269
+ $[0] = t0;
270
+ $[1] = calendarMonth;
271
+ $[2] = children;
272
+ $[3] = displayIndex;
273
+ $[4] = props;
274
+ } else {
275
+ calendarMonth = $[1];
276
+ children = $[2];
277
+ displayIndex = $[3];
278
+ props = $[4];
279
+ }
280
+ const monthRef = React.useRef(null);
281
+ const monthTime = calendarMonth.date.getTime();
282
+ const previousMonthTimeRef = React.useRef(monthTime);
283
+ const reduceMotion = usePrefersReducedMotion();
284
+ let t1;
285
+ let t2;
286
+ if ($[5] !== monthTime || $[6] !== reduceMotion) {
287
+ t1 = () => {
288
+ const previousMonthTime = previousMonthTimeRef.current;
289
+ previousMonthTimeRef.current = monthTime;
290
+ const element = monthRef.current;
291
+ if (!element || reduceMotion || previousMonthTime === monthTime) {
292
+ return;
293
+ }
294
+ const isForward = monthTime > previousMonthTime;
295
+ const isRightToLeft = getComputedStyle(element).direction === "rtl";
296
+ const direction = isForward !== isRightToLeft ? 1 : -1;
297
+ const original = {
298
+ opacity: element.style.opacity,
299
+ transform: element.style.transform
300
+ };
301
+ const restore = () => {
302
+ element.style.opacity = original.opacity;
303
+ element.style.transform = original.transform;
304
+ };
305
+ const animation = animate(element, {
306
+ opacity: [0, 1],
307
+ transform: [`translateX(${direction * MOTION_MONTH_DISTANCE}px)`, "translateX(0px)"]
308
+ }, {
309
+ duration: MOTION_TIMING.monthSwap,
310
+ ease: [...MOTION_EASE]
311
+ });
312
+ let isActive = true;
313
+ animation.then(() => frame.postRender(() => {
314
+ if (isActive) {
315
+ restore();
316
+ }
317
+ }));
318
+ return () => {
319
+ isActive = false;
320
+ animation.cancel();
321
+ restore();
322
+ };
323
+ };
324
+ t2 = [monthTime, reduceMotion];
325
+ $[5] = monthTime;
326
+ $[6] = reduceMotion;
327
+ $[7] = t1;
328
+ $[8] = t2;
329
+ } else {
330
+ t1 = $[7];
331
+ t2 = $[8];
332
+ }
333
+ React.useLayoutEffect(t1, t2);
334
+ let t3;
335
+ if ($[9] !== children || $[10] !== displayIndex || $[11] !== props) {
336
+ t3 = /* @__PURE__ */ _jsx("div", {
337
+ ref: monthRef,
338
+ "data-slot": "calendar-month",
339
+ "data-display-index": displayIndex,
340
+ ...props,
341
+ children
342
+ });
343
+ $[9] = children;
344
+ $[10] = displayIndex;
345
+ $[11] = props;
346
+ $[12] = t3;
347
+ } else {
348
+ t3 = $[12];
349
+ }
350
+ return t3;
351
+ }
250
352
  function CalendarDayButton(t0) {
251
353
  const $ = _c(21);
252
354
  let className;
@@ -7,6 +7,17 @@ import { cn } from "../lib/utils.js";
7
7
  import { Button } from "./button.js";
8
8
  import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
9
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ /** Arrow keys that move to the previous and next slide along each axis. */
11
+ const CAROUSEL_KEYS = {
12
+ horizontal: {
13
+ previous: "ArrowLeft",
14
+ next: "ArrowRight"
15
+ },
16
+ vertical: {
17
+ previous: "ArrowUp",
18
+ next: "ArrowDown"
19
+ }
20
+ };
10
21
  const CarouselContext = React.createContext(null);
11
22
  function useCarousel() {
12
23
  const context = React.useContext(CarouselContext);
@@ -16,7 +27,7 @@ function useCarousel() {
16
27
  return context;
17
28
  }
18
29
  function Carousel(t0) {
19
- const $ = _c(47);
30
+ const $ = _c(48);
20
31
  let children;
21
32
  let className;
22
33
  let opts;
@@ -100,28 +111,30 @@ function Carousel(t0) {
100
111
  }
101
112
  const scrollNext = t6;
102
113
  let t7;
103
- if ($[18] !== scrollNext || $[19] !== scrollPrev) {
114
+ if ($[18] !== orientation || $[19] !== scrollNext || $[20] !== scrollPrev) {
104
115
  t7 = (event) => {
105
- if (event.key === "ArrowLeft") {
116
+ const keys = CAROUSEL_KEYS[orientation];
117
+ if (event.key === keys.previous) {
106
118
  event.preventDefault();
107
119
  scrollPrev();
108
120
  } else {
109
- if (event.key === "ArrowRight") {
121
+ if (event.key === keys.next) {
110
122
  event.preventDefault();
111
123
  scrollNext();
112
124
  }
113
125
  }
114
126
  };
115
- $[18] = scrollNext;
116
- $[19] = scrollPrev;
117
- $[20] = t7;
127
+ $[18] = orientation;
128
+ $[19] = scrollNext;
129
+ $[20] = scrollPrev;
130
+ $[21] = t7;
118
131
  } else {
119
- t7 = $[20];
132
+ t7 = $[21];
120
133
  }
121
134
  const handleKeyDown = t7;
122
135
  let t8;
123
136
  let t9;
124
- if ($[21] !== api || $[22] !== setApi) {
137
+ if ($[22] !== api || $[23] !== setApi) {
125
138
  t8 = () => {
126
139
  if (!api || !setApi) {
127
140
  return;
@@ -129,18 +142,18 @@ function Carousel(t0) {
129
142
  setApi(api);
130
143
  };
131
144
  t9 = [api, setApi];
132
- $[21] = api;
133
- $[22] = setApi;
134
- $[23] = t8;
135
- $[24] = t9;
145
+ $[22] = api;
146
+ $[23] = setApi;
147
+ $[24] = t8;
148
+ $[25] = t9;
136
149
  } else {
137
- t8 = $[23];
138
- t9 = $[24];
150
+ t8 = $[24];
151
+ t9 = $[25];
139
152
  }
140
153
  React.useEffect(t8, t9);
141
154
  let t10;
142
155
  let t11;
143
- if ($[25] !== api) {
156
+ if ($[26] !== api) {
144
157
  t10 = () => {
145
158
  if (!api) {
146
159
  return;
@@ -160,17 +173,17 @@ function Carousel(t0) {
160
173
  };
161
174
  };
162
175
  t11 = [api, onSelect];
163
- $[25] = api;
164
- $[26] = t10;
165
- $[27] = t11;
176
+ $[26] = api;
177
+ $[27] = t10;
178
+ $[28] = t11;
166
179
  } else {
167
- t10 = $[26];
168
- t11 = $[27];
180
+ t10 = $[27];
181
+ t11 = $[28];
169
182
  }
170
183
  React.useEffect(t10, t11);
171
184
  const t12 = orientation || (opts?.axis === "y" ? "vertical" : "horizontal");
172
185
  let t13;
173
- if ($[28] !== api || $[29] !== canScrollNext || $[30] !== canScrollPrev || $[31] !== carouselRef || $[32] !== opts || $[33] !== scrollNext || $[34] !== scrollPrev || $[35] !== t12) {
186
+ if ($[29] !== api || $[30] !== canScrollNext || $[31] !== canScrollPrev || $[32] !== carouselRef || $[33] !== opts || $[34] !== scrollNext || $[35] !== scrollPrev || $[36] !== t12) {
174
187
  t13 = {
175
188
  carouselRef,
176
189
  api,
@@ -181,28 +194,28 @@ function Carousel(t0) {
181
194
  canScrollPrev,
182
195
  canScrollNext
183
196
  };
184
- $[28] = api;
185
- $[29] = canScrollNext;
186
- $[30] = canScrollPrev;
187
- $[31] = carouselRef;
188
- $[32] = opts;
189
- $[33] = scrollNext;
190
- $[34] = scrollPrev;
191
- $[35] = t12;
192
- $[36] = t13;
197
+ $[29] = api;
198
+ $[30] = canScrollNext;
199
+ $[31] = canScrollPrev;
200
+ $[32] = carouselRef;
201
+ $[33] = opts;
202
+ $[34] = scrollNext;
203
+ $[35] = scrollPrev;
204
+ $[36] = t12;
205
+ $[37] = t13;
193
206
  } else {
194
- t13 = $[36];
207
+ t13 = $[37];
195
208
  }
196
209
  let t14;
197
- if ($[37] !== className) {
210
+ if ($[38] !== className) {
198
211
  t14 = cn("relative", className);
199
- $[37] = className;
200
- $[38] = t14;
212
+ $[38] = className;
213
+ $[39] = t14;
201
214
  } else {
202
- t14 = $[38];
215
+ t14 = $[39];
203
216
  }
204
217
  let t15;
205
- if ($[39] !== children || $[40] !== handleKeyDown || $[41] !== props || $[42] !== t14) {
218
+ if ($[40] !== children || $[41] !== handleKeyDown || $[42] !== props || $[43] !== t14) {
206
219
  t15 = /* @__PURE__ */ _jsx("div", {
207
220
  onKeyDownCapture: handleKeyDown,
208
221
  className: t14,
@@ -212,25 +225,25 @@ function Carousel(t0) {
212
225
  ...props,
213
226
  children
214
227
  });
215
- $[39] = children;
216
- $[40] = handleKeyDown;
217
- $[41] = props;
218
- $[42] = t14;
219
- $[43] = t15;
228
+ $[40] = children;
229
+ $[41] = handleKeyDown;
230
+ $[42] = props;
231
+ $[43] = t14;
232
+ $[44] = t15;
220
233
  } else {
221
- t15 = $[43];
234
+ t15 = $[44];
222
235
  }
223
236
  let t16;
224
- if ($[44] !== t13 || $[45] !== t15) {
237
+ if ($[45] !== t13 || $[46] !== t15) {
225
238
  t16 = /* @__PURE__ */ _jsx(CarouselContext.Provider, {
226
239
  value: t13,
227
240
  children: t15
228
241
  });
229
- $[44] = t13;
230
- $[45] = t15;
231
- $[46] = t16;
242
+ $[45] = t13;
243
+ $[46] = t15;
244
+ $[47] = t16;
232
245
  } else {
233
- t16 = $[46];
246
+ t16 = $[47];
234
247
  }
235
248
  return t16;
236
249
  }
@@ -21,7 +21,7 @@ function Checkbox(t0) {
21
21
  }
22
22
  let t1;
23
23
  if ($[3] !== className) {
24
- t1 = cn("peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary", className);
24
+ t1 = cn("peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input shadow-xs transition-[color,background-color,border-color,box-shadow] outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary", className);
25
25
  $[3] = className;
26
26
  $[4] = t1;
27
27
  } else {
@@ -3,6 +3,7 @@ import * as React from "react";
3
3
  import { flexRender, getCoreRowModel, getFilteredRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table";
4
4
  import { CircleAlert, ChevronDown, ChevronRight, Ellipsis, Eraser, X } from "lucide-react";
5
5
  import { cn } from "../lib/utils.js";
6
+ import { matchesColumnFilterValue, normalizeFilterToken } from "../lib/column-filter-value.js";
6
7
  import { MotionSlot } from "../motion/motion-slot.js";
7
8
  import { Button } from "./button.js";
8
9
  import { Badge } from "./badge.js";
@@ -12,7 +13,6 @@ import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMe
12
13
  import { Input } from "./input.js";
13
14
  import { Table, TableBody, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "./table.js";
14
15
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
15
- const DIACRITICS_PATTERN = /[\u0300-\u036f]/g;
16
16
  const CLEAR_FILTER_ARIA_LABEL = "Limpiar filtro";
17
17
  const ACTIVE_EXCLUSIONS_SR_LABEL = "Filtros de exclusión activos";
18
18
  const HIDE_EXCLUDE_FILTERS_ARIA_LABEL = "Ocultar filtros de exclusión";
@@ -22,8 +22,37 @@ const EXCLUDED_ROWS_SUMMARY_LABEL = "Total excluidas";
22
22
  const CLEAR_ALL_EXCLUSIONS_ARIA_LABEL = "Quitar todas las exclusiones";
23
23
  const CLEAR_ALL_EXCLUSIONS_FROM_INPUT_ARIA_LABEL = "Limpiar filtros excluidos";
24
24
  const REVERSE_FILTER_PENDING_MESSAGE = "Estás escribiendo una exclusión. Presioná Enter para aplicarla.";
25
- function normalizeFilterToken(value) {
26
- return value.normalize("NFD").replace(DIACRITICS_PATTERN, "").toLocaleLowerCase().trim();
25
+ /** Filters a column with the structured values the query bar writes, or plain text. */
26
+ const columnFilterValueFn = (row, columnId, filterValue) => matchesColumnFilterValue(row.getValue(columnId), filterValue);
27
+ /** Mirrors TanStack's column id resolution: explicit id, else the accessor key with dots as `_`. */
28
+ function getColumnDefId(column) {
29
+ if (column.id) return column.id;
30
+ const accessorKey = column.accessorKey;
31
+ return typeof accessorKey === "string" ? accessorKey.replaceAll(".", "_") : undefined;
32
+ }
33
+ /**
34
+ * Gives the columns targeted by query qualifiers a filter that understands the query bar's
35
+ * structured values. TanStack would otherwise infer one from the data (`inNumberRange` for
36
+ * numbers, which crashes on an object). A consumer's own `filterFn` always wins.
37
+ */
38
+ function withQueryFilterFns(columns, targetedColumnIds) {
39
+ if (targetedColumnIds.size === 0) return columns;
40
+ return columns.map((column) => {
41
+ if ("columns" in column && column.columns) {
42
+ return {
43
+ ...column,
44
+ columns: withQueryFilterFns(column.columns, targetedColumnIds)
45
+ };
46
+ }
47
+ const columnId = getColumnDefId(column);
48
+ if (column.filterFn != null || columnId == null || !targetedColumnIds.has(columnId)) {
49
+ return column;
50
+ }
51
+ return {
52
+ ...column,
53
+ filterFn: columnFilterValueFn
54
+ };
55
+ });
27
56
  }
28
57
  function getTableFilterValue(filterValue, showExcludeFilterToggle) {
29
58
  const normalizedFilterValue = filterValue.trimStart();
@@ -310,8 +339,9 @@ export function DataTable({ columns, data, emptyMessage, toolbarActions, onVisib
310
339
  onColumnVisibilityChange?.(updater);
311
340
  }, [controlledColumnVisibility, onColumnVisibilityChange]);
312
341
  // TanStack Table manages internal reactive state through this hook.
342
+ const tableColumns = React.useMemo(() => withQueryFilterFns(columns, advancedFilterColumnIds), [columns, advancedFilterColumnIds]);
313
343
  const table = useReactTable({
314
- columns,
344
+ columns: tableColumns,
315
345
  data,
316
346
  // La tabla no pagina (no hay `getPaginationRowModel`). Con el auto-reset por
317
347
  // defecto, cada cambio de filtro dispara `resetPageIndex` → `setPagination`,
@@ -586,7 +586,7 @@ function DropdownMenuSubTrigger(t0) {
586
586
  }
587
587
  let t1;
588
588
  if ($[5] !== className) {
589
- t1 = cn("flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className);
589
+ t1 = cn("flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground data-open:*:data-[slot=dropdown-menu-sub-trigger-icon]:translate-x-0.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className);
590
590
  $[5] = className;
591
591
  $[6] = t1;
592
592
  } else {
@@ -594,7 +594,10 @@ function DropdownMenuSubTrigger(t0) {
594
594
  }
595
595
  let t2;
596
596
  if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
597
- t2 = /* @__PURE__ */ _jsx(ChevronRightIcon, { className: "ml-auto" });
597
+ t2 = /* @__PURE__ */ _jsx(ChevronRightIcon, {
598
+ "data-slot": "dropdown-menu-sub-trigger-icon",
599
+ className: "ml-auto transition-transform duration-200 ease-out"
600
+ });
598
601
  $[7] = t2;
599
602
  } else {
600
603
  t2 = $[7];
@@ -5,6 +5,7 @@ import { Calendar, Check, CircleDot, CircleMinus, CircleSlash, Folder, Hash, Lis
5
5
  import { Button } from "./button.js";
6
6
  import { Input } from "./input.js";
7
7
  import { Popover, PopoverAnchor, PopoverContent } from "./popover.js";
8
+ import { GlideSlot } from "../motion/glide-slot.js";
8
9
  import { cn } from "../lib/utils.js";
9
10
  import { getActiveFilterToken, getValueHighlightRanges, normalizeFilterSlug, parseFilterQuery, PRESENCE_HAS_META_KEY, PRESENCE_NO_META_KEY, UNASSIGNED_FOLDER_FILTER_VALUE } from "./filter-query-grammar.js";
10
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -810,12 +811,16 @@ export function FilterQueryBar(t0) {
810
811
  onCloseAutoFocus: _temp,
811
812
  onInteractOutside: t34,
812
813
  onOpenAutoFocus: _temp2,
813
- children: /* @__PURE__ */ _jsx("ul", {
814
- "aria-label": t35,
815
- className: "grid gap-0.5",
816
- id: listboxId,
817
- role: "listbox",
818
- children: t36
814
+ children: /* @__PURE__ */ _jsx(GlideSlot, {
815
+ preset: "suggestions",
816
+ children: /* @__PURE__ */ _jsx("ul", {
817
+ "aria-label": t35,
818
+ className: "grid gap-0.5",
819
+ "data-slot": "filter-query-bar-suggestions",
820
+ id: listboxId,
821
+ role: "listbox",
822
+ children: t36
823
+ })
819
824
  })
820
825
  });
821
826
  $[83] = listboxId;
@@ -4,6 +4,11 @@ import { Slot } from "radix-ui";
4
4
  import { type ControllerProps, type FieldPath, type FieldValues } from "react-hook-form";
5
5
  declare const Form: <TFieldValues extends FieldValues, TContext = any, TTransformedValues = TFieldValues>({ children, watch, getValues, getErrors, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, resetDefaultValues, handleSubmit, unregister, control, register, setFocus, subscribe, }: import("react-hook-form").FormProviderProps<TFieldValues, TContext, TTransformedValues>) => React.JSX.Element;
6
6
  declare const FormField: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ ...props }: ControllerProps<TFieldValues, TName>) => React.JSX.Element;
7
+ /**
8
+ * Reads the field and item context shared by the form parts.
9
+ * @returns Accessible ids plus the react-hook-form state of the enclosing field.
10
+ * @throws When used outside `<FormField>`, where no field name is available.
11
+ */
7
12
  declare const useFormField: () => {
8
13
  invalid: boolean;
9
14
  isDirty: boolean;
@@ -49,6 +49,11 @@ const FormField = (t0) => {
49
49
  }
50
50
  return t3;
51
51
  };
52
+ /**
53
+ * Reads the field and item context shared by the form parts.
54
+ * @returns Accessible ids plus the react-hook-form state of the enclosing field.
55
+ * @throws When used outside `<FormField>`, where no field name is available.
56
+ */
52
57
  const useFormField = () => {
53
58
  const $ = _c(13);
54
59
  const fieldContext = React.useContext(FormFieldContext);
@@ -63,6 +68,9 @@ const useFormField = () => {
63
68
  t0 = $[1];
64
69
  }
65
70
  const formState = useFormState(t0);
71
+ if (!fieldContext.name) {
72
+ throw new Error("useFormField: must be used within <FormField>, which provides the field name");
73
+ }
66
74
  let t1;
67
75
  if ($[2] !== fieldContext.name || $[3] !== formState || $[4] !== getFieldState) {
68
76
  t1 = getFieldState(fieldContext.name, formState);
@@ -74,9 +82,6 @@ const useFormField = () => {
74
82
  t1 = $[5];
75
83
  }
76
84
  const fieldState = t1;
77
- if (!fieldContext) {
78
- throw new Error("useFormField should be used within <FormField>");
79
- }
80
85
  const { id } = itemContext;
81
86
  const t2 = `${id}-form-item`;
82
87
  const t3 = `${id}-form-item-description`;
@@ -149,12 +154,9 @@ function FormItem(t0) {
149
154
  }
150
155
  let t4;
151
156
  if ($[10] !== t1 || $[11] !== t3) {
152
- t4 = /* @__PURE__ */ _jsx(MotionSlot, {
153
- kind: "field",
154
- children: /* @__PURE__ */ _jsx(FormItemContext.Provider, {
155
- value: t1,
156
- children: t3
157
- })
157
+ t4 = /* @__PURE__ */ _jsx(FormItemContext.Provider, {
158
+ value: t1,
159
+ children: t3
158
160
  });
159
161
  $[10] = t1;
160
162
  $[11] = t3;
@@ -23,7 +23,7 @@ function InputGroup(t0) {
23
23
  }
24
24
  let t1;
25
25
  if ($[3] !== className) {
26
- t1 = cn("group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5", className);
26
+ t1 = cn("group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-[color,background-color,border-color,box-shadow] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5", className);
27
27
  $[3] = className;
28
28
  $[4] = t1;
29
29
  } else {
@@ -9,7 +9,7 @@ function Input({ className, type, ...props }) {
9
9
  children: /* @__PURE__ */ _jsx(InputPrimitive, {
10
10
  type,
11
11
  "data-slot": "input",
12
- className: cn("h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className),
12
+ className: cn("h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-[color,background-color,border-color,box-shadow] outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className),
13
13
  ...props
14
14
  })
15
15
  });
@@ -2,6 +2,7 @@ import * as React from "react";
2
2
  import { type LinkProps } from "./link.js";
3
3
  import { Button } from "./button.js";
4
4
  declare function Pagination({ className, ...props }: React.ComponentProps<"nav">): React.JSX.Element;
5
+ /** Lists page links; the current page's highlight glides to the newly selected page. */
5
6
  declare function PaginationContent({ className, ...props }: React.ComponentProps<"ul">): React.JSX.Element;
6
7
  declare function PaginationItem({ ...props }: React.ComponentProps<"li">): React.JSX.Element;
7
8
  export type PaginationLinkProps = {
@@ -2,6 +2,7 @@
2
2
  import { c as _c } from "react/compiler-runtime";
3
3
  import * as React from "react";
4
4
  import { Link } from "./link.js";
5
+ import { GlideSlot } from "../motion/glide-slot.js";
5
6
  import { cn } from "../lib/utils.js";
6
7
  import { Button } from "./button.js";
7
8
  import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from "lucide-react";
@@ -44,6 +45,7 @@ function Pagination(t0) {
44
45
  }
45
46
  return t2;
46
47
  }
48
+ /** Lists page links; the current page's highlight glides to the newly selected page. */
47
49
  function PaginationContent(t0) {
48
50
  const $ = _c(8);
49
51
  let className;
@@ -67,10 +69,13 @@ function PaginationContent(t0) {
67
69
  }
68
70
  let t2;
69
71
  if ($[5] !== props || $[6] !== t1) {
70
- t2 = /* @__PURE__ */ _jsx("ul", {
71
- "data-slot": "pagination-content",
72
- className: t1,
73
- ...props
72
+ t2 = /* @__PURE__ */ _jsx(GlideSlot, {
73
+ preset: "pagination",
74
+ children: /* @__PURE__ */ _jsx("ul", {
75
+ "data-slot": "pagination-content",
76
+ className: t1,
77
+ ...props
78
+ })
74
79
  });
75
80
  $[5] = props;
76
81
  $[6] = t1;
@@ -56,7 +56,7 @@ function RadioGroupItem(t0) {
56
56
  }
57
57
  let t1;
58
58
  if ($[3] !== className) {
59
- t1 = cn("group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary", className);
59
+ t1 = cn("group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input transition-[color,background-color,border-color,box-shadow] outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary", className);
60
60
  $[3] = className;
61
61
  $[4] = t1;
62
62
  } else {
@@ -116,7 +116,7 @@ function SelectTrigger(t0) {
116
116
  const size = t1 === undefined ? "default" : t1;
117
117
  let t2;
118
118
  if ($[5] !== className) {
119
- t2 = cn("flex w-fit items-center justify-between gap-1.5 rounded-lg border data-[state=open]:*:data-[slot=select-icon]:rotate-180 border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className);
119
+ t2 = cn("flex w-fit items-center justify-between gap-1.5 rounded-lg border data-[state=open]:*:data-[slot=select-icon]:rotate-180 border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-[color,background-color,border-color,box-shadow] outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className);
120
120
  $[5] = className;
121
121
  $[6] = t2;
122
122
  } else {