beez-ui 3.0.1 → 4.0.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 (56) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +45 -47
  3. package/dist/components/account-menu.js +1 -1
  4. package/dist/components/alert.js +3 -7
  5. package/dist/components/animated-collapse.js +51 -38
  6. package/dist/components/animated-list-item.js +33 -34
  7. package/dist/components/animated-theme-toggler.d.ts +5 -1
  8. package/dist/components/animated-theme-toggler.js +75 -120
  9. package/dist/components/badge.js +7 -11
  10. package/dist/components/card.js +13 -16
  11. package/dist/components/dialog-surface.js +8 -21
  12. package/dist/components/filter-query-bar.js +7 -11
  13. package/dist/components/input-group.js +5 -9
  14. package/dist/components/input.js +8 -12
  15. package/dist/components/label.js +4 -8
  16. package/dist/components/link.d.ts +1 -0
  17. package/dist/components/link.js +2 -16
  18. package/dist/components/presence-swap.d.ts +1 -1
  19. package/dist/components/presence-swap.js +44 -32
  20. package/dist/components/primitives/avatar.js +6 -9
  21. package/dist/components/primitives/dropdown-menu.d.ts +2 -2
  22. package/dist/components/primitives/dropdown-menu.js +8 -5
  23. package/dist/components/primitives/select.d.ts +2 -1
  24. package/dist/components/primitives/select.js +104 -83
  25. package/dist/components/reaction-button.d.ts +5 -6
  26. package/dist/components/reaction-button.js +139 -75
  27. package/dist/components/rich-link-editor.js +1 -1
  28. package/dist/components/separator.js +5 -9
  29. package/dist/components/sheet.js +8 -11
  30. package/dist/components/sidebar.d.ts +6 -6
  31. package/dist/components/sidebar.js +221 -184
  32. package/dist/components/svgs/whatsappIcon.js +10 -14
  33. package/dist/components/table.js +4 -8
  34. package/dist/components/textarea.js +7 -11
  35. package/dist/components/themed-toaster.js +28 -62
  36. package/dist/constants/dropdown-menu.d.ts +6 -1
  37. package/dist/constants/dropdown-menu.js +33 -1
  38. package/dist/constants/popover.js +2 -8
  39. package/dist/constants/select.d.ts +3 -1
  40. package/dist/constants/select.js +30 -1
  41. package/dist/motion/arc-tokens.d.ts +6 -0
  42. package/dist/motion/arc-tokens.js +6 -0
  43. package/dist/motion/glide-indicator.d.ts +6 -21
  44. package/dist/motion/glide-indicator.js +8 -17
  45. package/dist/motion/motion-slot.d.ts +6 -3
  46. package/dist/motion/motion-slot.js +100 -411
  47. package/dist/motion/presence.d.ts +8 -0
  48. package/dist/motion/presence.js +11 -1
  49. package/dist/motion/surface-keyframes.d.ts +2 -2
  50. package/dist/motion/surface-keyframes.js +40 -141
  51. package/dist/motion/tokens.d.ts +10 -114
  52. package/dist/motion/tokens.js +11 -116
  53. package/dist/styles.css +1 -1
  54. package/package.json +1 -1
  55. package/dist/motion/shared-layout-bg.d.ts +0 -16
  56. package/dist/motion/shared-layout-bg.js +0 -181
@@ -1,6 +1,5 @@
1
1
  "use client";
2
2
  import { c as _c } from "react/compiler-runtime";
3
- import { MotionSlot } from "../motion/motion-slot.js";
4
3
  import { cn } from "../lib/utils.js";
5
4
  import { Field, usesFieldCopy, useFieldAria } from "./field.js";
6
5
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -68,16 +67,13 @@ function Textarea(textareaProps) {
68
67
  const t4 = aria["aria-invalid"];
69
68
  let t5;
70
69
  if ($[14] !== props || $[15] !== t1 || $[16] !== t2 || $[17] !== t3 || $[18] !== t4) {
71
- t5 = /* @__PURE__ */ _jsx(MotionSlot, {
72
- kind: "field",
73
- children: /* @__PURE__ */ _jsx("textarea", {
74
- "data-slot": "textarea",
75
- className: t1,
76
- ...props,
77
- id: t2,
78
- "aria-describedby": t3,
79
- "aria-invalid": t4
80
- })
70
+ t5 = /* @__PURE__ */ _jsx("textarea", {
71
+ "data-slot": "textarea",
72
+ className: t1,
73
+ ...props,
74
+ id: t2,
75
+ "aria-describedby": t3,
76
+ "aria-invalid": t4
81
77
  });
82
78
  $[14] = props;
83
79
  $[15] = t1;
@@ -1,6 +1,5 @@
1
1
  "use client";
2
2
  import { c as _c } from "react/compiler-runtime";
3
- import { MotionSlot } from "../motion/motion-slot.js";
4
3
  import { cn } from "../lib/utils.js";
5
4
  import { Toaster } from "./toaster.js";
6
5
  import { useTheme } from "next-themes";
@@ -11,7 +10,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
11
10
  * toasts stay usable from an open `Dialog` (also in `alert` mode) or `Sheet`.
12
11
  */
13
12
  const ThemedToaster = (t0) => {
14
- const $ = _c(16);
13
+ const $ = _c(13);
15
14
  let className;
16
15
  let props;
17
16
  let theme;
@@ -37,84 +36,51 @@ const ThemedToaster = (t0) => {
37
36
  t1 = $[5];
38
37
  }
39
38
  let t2;
39
+ let t3;
40
40
  if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
41
- t2 = /* @__PURE__ */ _jsx(MotionSlot, {
42
- kind: "selection",
43
- children: /* @__PURE__ */ _jsx(CircleCheck, { className: "size-4" })
44
- });
41
+ t2 = {
42
+ success: /* @__PURE__ */ _jsx(CircleCheck, { className: "size-4" }),
43
+ info: /* @__PURE__ */ _jsx(Info, { className: "size-4" }),
44
+ warning: /* @__PURE__ */ _jsx(TriangleAlert, { className: "size-4" }),
45
+ error: /* @__PURE__ */ _jsx(OctagonAlert, { className: "size-4" }),
46
+ loading: /* @__PURE__ */ _jsx(Loader, { className: "size-4 animate-spin" })
47
+ };
48
+ t3 = {
49
+ "--normal-bg": "var(--popover)",
50
+ "--normal-text": "var(--popover-foreground)",
51
+ "--normal-border": "var(--border)",
52
+ "--border-radius": "var(--radius)"
53
+ };
45
54
  $[6] = t2;
46
- } else {
47
- t2 = $[6];
48
- }
49
- let t3;
50
- if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
51
- t3 = /* @__PURE__ */ _jsx(MotionSlot, {
52
- kind: "selection",
53
- children: /* @__PURE__ */ _jsx(Info, { className: "size-4" })
54
- });
55
55
  $[7] = t3;
56
56
  } else {
57
+ t2 = $[6];
57
58
  t3 = $[7];
58
59
  }
59
60
  let t4;
60
61
  if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
61
- t4 = /* @__PURE__ */ _jsx(MotionSlot, {
62
- kind: "selection",
63
- children: /* @__PURE__ */ _jsx(TriangleAlert, { className: "size-4" })
64
- });
62
+ t4 = { classNames: { toast: "cn-toast" } };
65
63
  $[8] = t4;
66
64
  } else {
67
65
  t4 = $[8];
68
66
  }
69
67
  let t5;
70
- let t6;
71
- if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
72
- t5 = {
73
- success: t2,
74
- info: t3,
75
- warning: t4,
76
- error: /* @__PURE__ */ _jsx(MotionSlot, {
77
- kind: "selection",
78
- children: /* @__PURE__ */ _jsx(OctagonAlert, { className: "size-4" })
79
- }),
80
- loading: /* @__PURE__ */ _jsx(Loader, { className: "size-4 animate-spin" })
81
- };
82
- t6 = {
83
- "--normal-bg": "var(--popover)",
84
- "--normal-text": "var(--popover-foreground)",
85
- "--normal-border": "var(--border)",
86
- "--border-radius": "var(--radius)"
87
- };
88
- $[9] = t5;
89
- $[10] = t6;
90
- } else {
91
- t5 = $[9];
92
- t6 = $[10];
93
- }
94
- let t7;
95
- if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
96
- t7 = { classNames: { toast: "cn-toast" } };
97
- $[11] = t7;
98
- } else {
99
- t7 = $[11];
100
- }
101
- let t8;
102
- if ($[12] !== activeTheme || $[13] !== props || $[14] !== t1) {
103
- t8 = /* @__PURE__ */ _jsx(Toaster, {
68
+ if ($[9] !== activeTheme || $[10] !== props || $[11] !== t1) {
69
+ t5 = /* @__PURE__ */ _jsx(Toaster, {
104
70
  theme: activeTheme,
105
71
  className: t1,
106
- icons: t5,
107
- style: t6,
108
- toastOptions: t7,
72
+ icons: t2,
73
+ style: t3,
74
+ toastOptions: t4,
109
75
  ...props
110
76
  });
111
- $[12] = activeTheme;
112
- $[13] = props;
113
- $[14] = t1;
114
- $[15] = t8;
77
+ $[9] = activeTheme;
78
+ $[10] = props;
79
+ $[11] = t1;
80
+ $[12] = t5;
115
81
  } else {
116
- t8 = $[15];
82
+ t5 = $[12];
117
83
  }
118
- return t8;
84
+ return t5;
119
85
  };
120
86
  export { ThemedToaster };
@@ -1,5 +1,10 @@
1
- /** Placement defaults of the dropdown menu content, taken from Arc's Dropdown menu. */
1
+ import type { ArcFloatingMotion } from "../motion/arc-floating-slot.js";
2
2
  /** Gap, in pixels, between the trigger and the menu. */
3
3
  export declare const DROPDOWN_MENU_SIDE_OFFSET_PX = 6;
4
4
  /** Minimum distance, in pixels, a menu keeps from the viewport edges. */
5
5
  export declare const DROPDOWN_MENU_COLLISION_PADDING_PX = 12;
6
+ /**
7
+ * Arc's menu: it starts 5px toward its trigger at .97, settles on the CSS spring while it fades in quickly, and
8
+ * leaves halfway back toward the trigger at .985.
9
+ */
10
+ export declare const DROPDOWN_MENU_MOTION: ArcFloatingMotion;
@@ -1,5 +1,37 @@
1
- /** Placement defaults of the dropdown menu content, taken from Arc's Dropdown menu. */
1
+ import { ARC_DURATION, ARC_EASE, ARC_SPRING_CSS } from "../motion/arc-tokens.js";
2
2
  /** Gap, in pixels, between the trigger and the menu. */
3
3
  export const DROPDOWN_MENU_SIDE_OFFSET_PX = 6;
4
4
  /** Minimum distance, in pixels, a menu keeps from the viewport edges. */
5
5
  export const DROPDOWN_MENU_COLLISION_PADDING_PX = 12;
6
+ /** Arc closes the menu in 130ms on the standard curve. */
7
+ const DROPDOWN_MENU_EXIT_TWEEN = {
8
+ duration: .13,
9
+ ease: [...ARC_EASE.standard]
10
+ };
11
+ /**
12
+ * Arc's menu: it starts 5px toward its trigger at .97, settles on the CSS spring while it fades in quickly, and
13
+ * leaves halfway back toward the trigger at .985.
14
+ */
15
+ export const DROPDOWN_MENU_MOTION = {
16
+ enterFrom: {
17
+ travel: 5,
18
+ scale: .97,
19
+ opacity: 0
20
+ },
21
+ enter: {
22
+ transform: ARC_SPRING_CSS,
23
+ opacity: {
24
+ duration: ARC_DURATION.fast,
25
+ ease: [...ARC_EASE.enter]
26
+ }
27
+ },
28
+ exitTo: {
29
+ travel: 2.5,
30
+ scale: .985,
31
+ opacity: 0
32
+ },
33
+ exit: {
34
+ transform: DROPDOWN_MENU_EXIT_TWEEN,
35
+ opacity: DROPDOWN_MENU_EXIT_TWEEN
36
+ }
37
+ };
@@ -1,14 +1,8 @@
1
- import { ARC_DURATION, ARC_EASE } from "../motion/arc-tokens.js";
1
+ import { ARC_DURATION, ARC_EASE, ARC_SPRING_CSS } from "../motion/arc-tokens.js";
2
2
  /** Gap, in px, between the panel and its trigger. */
3
3
  export const POPOVER_SIDE_OFFSET_PX = 6;
4
4
  /** Distance, in px, the panel keeps from the viewport edges before it flips or shifts. */
5
5
  export const POPOVER_COLLISION_PADDING_PX = 10;
6
- /** Arc's CSS spring (`--ease-spring`, bounce .15) as a Motion spring: the panel settles with a gentle overshoot. */
7
- const POPOVER_SETTLE_SPRING = {
8
- type: "spring",
9
- visualDuration: .34,
10
- bounce: .15
11
- };
12
6
  const exitTween = {
13
7
  duration: ARC_DURATION.fast,
14
8
  ease: [...ARC_EASE.standard]
@@ -21,7 +15,7 @@ export const POPOVER_MOTION = {
21
15
  opacity: 0
22
16
  },
23
17
  enter: {
24
- transform: POPOVER_SETTLE_SPRING,
18
+ transform: ARC_SPRING_CSS,
25
19
  opacity: {
26
20
  duration: ARC_DURATION.fast,
27
21
  ease: [...ARC_EASE.enter]
@@ -1,5 +1,7 @@
1
- /** Placement defaults and copy of Arc's Select. */
1
+ import type { ArcFloatingMotion } from "../motion/arc-floating-slot.js";
2
2
  /** Minimum distance, in pixels, the option list keeps from the viewport edges. */
3
3
  export declare const SELECT_COLLISION_PADDING_PX = 12;
4
4
  /** Default Spanish placeholder, shown while no option is chosen. Arc's English default is "Select an option". */
5
5
  export declare const SELECT_DEFAULT_PLACEHOLDER = "Seleccion\u00E1 una opci\u00F3n";
6
+ /** Arc's option list: it grows 6px from the trigger edge at .97 and leaves halfway back at .98, both as tweens. */
7
+ export declare const SELECT_MOTION: ArcFloatingMotion;
@@ -1,5 +1,34 @@
1
- /** Placement defaults and copy of Arc's Select. */
1
+ import { ARC_DURATION, ARC_EASE } from "../motion/arc-tokens.js";
2
2
  /** Minimum distance, in pixels, the option list keeps from the viewport edges. */
3
3
  export const SELECT_COLLISION_PADDING_PX = 12;
4
4
  /** Default Spanish placeholder, shown while no option is chosen. Arc's English default is "Select an option". */
5
5
  export const SELECT_DEFAULT_PLACEHOLDER = "Seleccioná una opción";
6
+ const SELECT_ENTER_TWEEN = {
7
+ duration: ARC_DURATION.standard,
8
+ ease: [...ARC_EASE.enter]
9
+ };
10
+ const SELECT_EXIT_TWEEN = {
11
+ duration: ARC_DURATION.instant,
12
+ ease: [...ARC_EASE.standard]
13
+ };
14
+ /** Arc's option list: it grows 6px from the trigger edge at .97 and leaves halfway back at .98, both as tweens. */
15
+ export const SELECT_MOTION = {
16
+ enterFrom: {
17
+ travel: 6,
18
+ scale: .97,
19
+ opacity: 0
20
+ },
21
+ enter: {
22
+ transform: SELECT_ENTER_TWEEN,
23
+ opacity: SELECT_ENTER_TWEEN
24
+ },
25
+ exitTo: {
26
+ travel: 3,
27
+ scale: .98,
28
+ opacity: 0
29
+ },
30
+ exit: {
31
+ transform: SELECT_EXIT_TWEEN,
32
+ opacity: SELECT_EXIT_TWEEN
33
+ }
34
+ };
@@ -35,6 +35,12 @@ export declare const ARC_SPRING_MORPH: {
35
35
  readonly visualDuration: 0.42;
36
36
  readonly bounce: 0.16;
37
37
  };
38
+ /** Arc's CSS spring (`--ease-spring` over `--duration-spring`) as a Motion spring: a gentle overshoot that settles. */
39
+ export declare const ARC_SPRING_CSS: {
40
+ readonly type: "spring";
41
+ readonly visualDuration: 0.34;
42
+ readonly bounce: 0.15;
43
+ };
38
44
  /** Stagger steps in seconds; keep a whole staggered entrance under roughly 0.4s. */
39
45
  export declare const ARC_STAGGER: {
40
46
  readonly char: 0.016;
@@ -55,6 +55,12 @@ export const ARC_SPRING_MORPH = {
55
55
  visualDuration: .42,
56
56
  bounce: .16
57
57
  };
58
+ /** Arc's CSS spring (`--ease-spring` over `--duration-spring`) as a Motion spring: a gentle overshoot that settles. */
59
+ export const ARC_SPRING_CSS = {
60
+ type: "spring",
61
+ visualDuration: .34,
62
+ bounce: .15
63
+ };
58
64
  /** Stagger steps in seconds; keep a whole staggered entrance under roughly 0.4s. */
59
65
  export const ARC_STAGGER = {
60
66
  char: .016,
@@ -1,5 +1,4 @@
1
- import { SPRING_HIGHLIGHT, SPRING_LAYOUT, SPRING_TABS } from "./tokens.js";
2
- import { ARC_SPRING_MORPH } from "./arc-tokens.js";
1
+ import { ARC_SPRING_MORPH, ARC_SPRING_SNAPPY } from "./arc-tokens.js";
3
2
  /** Which part of the active item carries the highlight that must travel. */
4
3
  type GlideSurface = "background" | "after";
5
4
  /** Describes the items of one container and how their active state is exposed. */
@@ -14,13 +13,12 @@ export interface GlidePreset {
14
13
  attributes: string[];
15
14
  isActive: (item: Element) => boolean;
16
15
  surface: (container: HTMLElement) => GlideSurface;
17
- spring: typeof SPRING_LAYOUT | typeof SPRING_TABS | typeof SPRING_HIGHLIGHT | typeof ARC_SPRING_MORPH;
16
+ spring: typeof ARC_SPRING_MORPH | typeof ARC_SPRING_SNAPPY;
18
17
  /**
19
- * Highlights that follow the pointer (menus, listboxes) jump straight to the hovered item:
20
- * the pointer already marks the position, so a travelling copy would only trail behind it.
21
- * The glide is kept for keyboard navigation.
18
+ * Arc's menu highlight glides between items for the pointer and jumps instantly for the
19
+ * keyboard, so a held arrow key never trails behind the focus.
22
20
  */
23
- instantOnPointer?: boolean;
21
+ instantOnKeyboard?: boolean;
24
22
  }
25
23
  export declare const GLIDE_PRESETS: {
26
24
  tabs: {
@@ -47,19 +45,6 @@ export declare const GLIDE_PRESETS: {
47
45
  readonly bounce: 0.16;
48
46
  };
49
47
  };
50
- suggestions: {
51
- itemSelector: string;
52
- containerSelector: string;
53
- attributes: string[];
54
- isActive: (item: Element) => boolean;
55
- surface: () => "background";
56
- spring: {
57
- readonly type: "spring";
58
- readonly visualDuration: 0.26;
59
- readonly bounce: 0.12;
60
- };
61
- instantOnPointer: true;
62
- };
63
48
  menu: {
64
49
  itemSelector: string;
65
50
  containerSelector: string;
@@ -71,7 +56,7 @@ export declare const GLIDE_PRESETS: {
71
56
  readonly visualDuration: 0.26;
72
57
  readonly bounce: 0.12;
73
58
  };
74
- instantOnPointer: true;
59
+ instantOnKeyboard: true;
75
60
  };
76
61
  };
77
62
  export type GlidePresetName = keyof typeof GLIDE_PRESETS;
@@ -4,8 +4,8 @@
4
4
  * previous item and is removed once it lands, leaving the item's own styles in charge again.
5
5
  */
6
6
  import { animate } from "motion/react";
7
- import { GLIDE_CONTINUITY_MS, SPRING_HIGHLIGHT } from "./tokens.js";
8
- import { ARC_SPRING_MORPH } from "./arc-tokens.js";
7
+ import { GLIDE_CONTINUITY_MS } from "./tokens.js";
8
+ import { ARC_SPRING_MORPH, ARC_SPRING_SNAPPY } from "./arc-tokens.js";
9
9
  export const GLIDE_PRESETS = {
10
10
  tabs: {
11
11
  itemSelector: "[data-slot=\"tabs-trigger\"]",
@@ -24,23 +24,14 @@ export const GLIDE_PRESETS = {
24
24
  surface: () => "background",
25
25
  spring: ARC_SPRING_MORPH
26
26
  },
27
- suggestions: {
28
- itemSelector: "[role=\"option\"]",
29
- containerSelector: "[role=\"listbox\"]",
30
- attributes: ["aria-selected"],
31
- isActive: (item) => item.getAttribute("aria-selected") === "true",
32
- surface: () => "background",
33
- spring: SPRING_HIGHLIGHT,
34
- instantOnPointer: true
35
- },
36
27
  menu: {
37
- itemSelector: "[role=\"menuitem\"],[role=\"menuitemcheckbox\"],[role=\"menuitemradio\"],[role=\"option\"]",
38
- containerSelector: "[role=\"menu\"],[role=\"listbox\"]",
28
+ itemSelector: "[role=\"menuitem\"],[role=\"menuitemcheckbox\"],[role=\"menuitemradio\"]",
29
+ containerSelector: "[role=\"menu\"]",
39
30
  attributes: ["data-highlighted"],
40
31
  isActive: (item) => item.hasAttribute("data-highlighted"),
41
32
  surface: () => "background",
42
- spring: SPRING_HIGHLIGHT,
43
- instantOnPointer: true
33
+ spring: ARC_SPRING_SNAPPY,
34
+ instantOnKeyboard: true
44
35
  }
45
36
  };
46
37
  /** Marks the item whose own highlight is hidden while the travelling copy stands in for it. */
@@ -197,7 +188,7 @@ export function attachGlideIndicator(container, preset) {
197
188
  const onKeyDown = () => {
198
189
  isPointerDriven = false;
199
190
  };
200
- if (preset.instantOnPointer) {
191
+ if (preset.instantOnKeyboard) {
201
192
  container.addEventListener("pointermove", onPointerMove);
202
193
  container.ownerDocument.addEventListener("keydown", onKeyDown, true);
203
194
  }
@@ -300,7 +291,7 @@ export function attachGlideIndicator(container, preset) {
300
291
  const isContinuous = previous !== null && previous !== active && previous.isConnected && !preset.isActive(previous) && (lastActiveSeenAt === Number.NEGATIVE_INFINITY || now - lastActiveSeenAt <= GLIDE_CONTINUITY_MS);
301
292
  lastActive = active;
302
293
  lastActiveSeenAt = Number.NEGATIVE_INFINITY;
303
- if (isContinuous && !(preset.instantOnPointer && isPointerDriven)) glide(previous, active);
294
+ if (isContinuous && !(preset.instantOnKeyboard && !isPointerDriven)) glide(previous, active);
304
295
  else settle();
305
296
  });
306
297
  observer.observe(container, {
@@ -1,9 +1,12 @@
1
- /** Animates the original primitive node with Motion, without adding DOM wrappers. */
1
+ /**
2
+ * Animates the original primitive node with Motion, without adding DOM wrappers. Every kind plays Arc's motion
3
+ * (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md) for the component it serves.
4
+ */
2
5
  import { type ReactElement, type ComponentProps } from "react";
3
6
  import { Slot } from "radix-ui";
4
7
  import { type MotionKind } from "./tokens.js";
5
- /** Composes refs through Radix Slot and delegates gesture, entry and exit playback to Motion. */
8
+ /** Composes refs through Radix Slot and delegates entry, exit and state playback to Motion. */
6
9
  export declare function MotionSlot({ children, kind, ref, ...props }: Omit<ComponentProps<typeof Slot.Root>, "children"> & {
7
10
  children: ReactElement;
8
- kind?: MotionKind;
11
+ kind: MotionKind;
9
12
  }): import("react").JSX.Element;