@bearmenu/ui 0.8.33 → 0.8.35

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 (86) hide show
  1. package/dist/{chunk-GESB7GCF.js → chunk-6W25S5CF.js} +1 -1
  2. package/dist/chunk-LY67SOFC.js +142 -0
  3. package/dist/{chunk-ZU4NAYN7.js → chunk-NIAL4ZU2.js} +13 -1
  4. package/dist/{chunk-JWTN7MNK.js → chunk-TVEIUTBQ.js} +2 -2
  5. package/dist/{chunk-ZJMCU7MI.js → chunk-VCRXL7H5.js} +1 -1
  6. package/dist/chunk-XLHMF6F5.js +127 -0
  7. package/dist/{chunk-VSRGEB36.js → chunk-XNBDACL7.js} +1 -1
  8. package/dist/components/action-bar.d.ts +67 -0
  9. package/dist/components/action-bar.js +43 -0
  10. package/dist/components/activity-row.d.ts +38 -0
  11. package/dist/components/activity-row.js +43 -0
  12. package/dist/components/alert.d.ts +2 -2
  13. package/dist/components/avatar.d.ts +4 -1
  14. package/dist/components/avatar.js +39 -5
  15. package/dist/components/badge.d.ts +1 -1
  16. package/dist/components/badge.js +1 -1
  17. package/dist/components/booking-row.d.ts +11 -1
  18. package/dist/components/booking-row.js +4 -1
  19. package/dist/components/button.d.ts +2 -2
  20. package/dist/components/combobox.js +2 -2
  21. package/dist/components/command.d.ts +15 -15
  22. package/dist/components/command.js +2 -2
  23. package/dist/components/concept-convergence.js +2 -2
  24. package/dist/components/currency-input.js +4 -142
  25. package/dist/components/dialog.d.ts +6 -0
  26. package/dist/components/dialog.js +1 -1
  27. package/dist/components/drawer.d.ts +6 -0
  28. package/dist/components/drawer.js +3 -127
  29. package/dist/components/empty-state.d.ts +2 -2
  30. package/dist/components/filter-category-row.js +1 -1
  31. package/dist/components/menu-item.js +3 -3
  32. package/dist/components/menu-pick-row.d.ts +47 -0
  33. package/dist/components/menu-pick-row.js +49 -0
  34. package/dist/components/multi-select-combobox.js +3 -3
  35. package/dist/components/place-card.js +1 -1
  36. package/dist/components/place-details-mobile.js +1 -1
  37. package/dist/components/qr-panel.d.ts +31 -0
  38. package/dist/components/qr-panel.js +33 -0
  39. package/dist/components/reconcile-bar.d.ts +47 -0
  40. package/dist/components/reconcile-bar.js +60 -0
  41. package/dist/components/responsive-overlay.d.ts +59 -0
  42. package/dist/components/responsive-overlay.js +132 -0
  43. package/dist/components/searchable-select.js +2 -2
  44. package/dist/components/signature-chip.js +2 -2
  45. package/dist/components/spinner.d.ts +2 -2
  46. package/dist/components/split-share-row.d.ts +77 -0
  47. package/dist/components/split-share-row.js +101 -0
  48. package/dist/components/table-ledger-card.d.ts +80 -0
  49. package/dist/components/table-ledger-card.js +84 -0
  50. package/dist/components/table-trigger-band.d.ts +56 -0
  51. package/dist/components/table-trigger-band.js +43 -0
  52. package/dist/components/tag.d.ts +2 -2
  53. package/dist/components/text.d.ts +2 -2
  54. package/dist/components/toggle.d.ts +1 -1
  55. package/dist/components/top-ranking-entry.js +3 -3
  56. package/dist/components/venue-events-block.js +1 -1
  57. package/package.json +23 -207
  58. package/src/components/action-bar.stories.tsx +78 -0
  59. package/src/components/action-bar.tsx +80 -0
  60. package/src/components/activity-row.stories.tsx +78 -0
  61. package/src/components/activity-row.tsx +65 -0
  62. package/src/components/avatar.stories.tsx +55 -0
  63. package/src/components/avatar.tsx +63 -19
  64. package/src/components/badge.stories.tsx +41 -0
  65. package/src/components/badge.tsx +13 -0
  66. package/src/components/booking-row.tsx +13 -0
  67. package/src/components/dialog.tsx +8 -2
  68. package/src/components/drawer.tsx +8 -2
  69. package/src/components/menu-pick-row.stories.tsx +71 -0
  70. package/src/components/menu-pick-row.tsx +76 -0
  71. package/src/components/qr-panel.stories.tsx +39 -0
  72. package/src/components/qr-panel.tsx +52 -0
  73. package/src/components/reconcile-bar.stories.tsx +57 -0
  74. package/src/components/reconcile-bar.tsx +80 -0
  75. package/src/components/responsive-overlay.stories.tsx +91 -0
  76. package/src/components/responsive-overlay.test.tsx +162 -0
  77. package/src/components/responsive-overlay.tsx +232 -0
  78. package/src/components/shared-table-primitives.test.tsx +482 -0
  79. package/src/components/split-share-row.stories.tsx +114 -0
  80. package/src/components/split-share-row.tsx +150 -0
  81. package/src/components/table-ledger-card.stories.tsx +120 -0
  82. package/src/components/table-ledger-card.tsx +138 -0
  83. package/src/components/table-trigger-band.stories.tsx +76 -0
  84. package/src/components/table-trigger-band.tsx +75 -0
  85. package/src/globals.css +44 -0
  86. package/src/test/setup.ts +11 -0
@@ -1,4 +1,4 @@
1
- import { Badge } from './chunk-ZU4NAYN7.js';
1
+ import { Badge } from './chunk-NIAL4ZU2.js';
2
2
  import { cn } from './chunk-FEK5XGZW.js';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
 
@@ -0,0 +1,142 @@
1
+ import { Input } from './chunk-GTQSGDYF.js';
2
+ import { cn } from './chunk-FEK5XGZW.js';
3
+ import { __objRest, __spreadValues } from './chunk-MMUBH76A.js';
4
+ import * as React from 'react';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ var ALLOWED_NAVIGATION_KEYS = /* @__PURE__ */ new Set([
8
+ "Backspace",
9
+ "Tab",
10
+ "Escape",
11
+ "Enter",
12
+ "Delete",
13
+ "Home",
14
+ "End",
15
+ "ArrowLeft",
16
+ "ArrowRight",
17
+ "ArrowUp",
18
+ "ArrowDown"
19
+ ]);
20
+ var ALLOWED_SHORTCUT_KEYS = /* @__PURE__ */ new Set(["a", "c", "v", "x", "z"]);
21
+ var CurrencyInput = React.forwardRef(
22
+ (_a, ref) => {
23
+ var _b = _a, {
24
+ value,
25
+ onChange,
26
+ placeholder = "Enter amount",
27
+ currency = "$",
28
+ locale = "en-US",
29
+ min,
30
+ max,
31
+ disabled = false,
32
+ className,
33
+ error,
34
+ id: providedId
35
+ } = _b, props = __objRest(_b, [
36
+ "value",
37
+ "onChange",
38
+ "placeholder",
39
+ "currency",
40
+ "locale",
41
+ "min",
42
+ "max",
43
+ "disabled",
44
+ "className",
45
+ "error",
46
+ "id"
47
+ ]);
48
+ const reactId = React.useId();
49
+ const id = providedId != null ? providedId : reactId;
50
+ const errorId = `${id}-error`;
51
+ const [displayValue, setDisplayValue] = React.useState("");
52
+ const [isFocused, setIsFocused] = React.useState(false);
53
+ const formatNumber = React.useCallback(
54
+ (num) => {
55
+ if (num === null || isNaN(num)) return "";
56
+ return new Intl.NumberFormat(locale, {
57
+ minimumFractionDigits: 0,
58
+ maximumFractionDigits: 2
59
+ }).format(num);
60
+ },
61
+ [locale]
62
+ );
63
+ const parseInput = (input) => {
64
+ const cleaned = input.replace(/[^\d.-]/g, "");
65
+ const parsed = parseFloat(cleaned);
66
+ return isNaN(parsed) ? null : parsed;
67
+ };
68
+ React.useEffect(() => {
69
+ if (!isFocused) {
70
+ setDisplayValue(formatNumber(value));
71
+ }
72
+ }, [value, isFocused, formatNumber]);
73
+ const handleInputChange = (e) => {
74
+ const inputValue = e.target.value;
75
+ setDisplayValue(inputValue);
76
+ const parsedValue = parseInput(inputValue);
77
+ if (parsedValue !== null) {
78
+ if (min !== void 0 && parsedValue < min) return;
79
+ if (max !== void 0 && parsedValue > max) return;
80
+ }
81
+ onChange(parsedValue);
82
+ };
83
+ const handleFocus = () => {
84
+ setIsFocused(true);
85
+ if (value !== null && value !== void 0 && !isNaN(value)) {
86
+ setDisplayValue(value.toString());
87
+ }
88
+ };
89
+ const handleBlur = () => {
90
+ setIsFocused(false);
91
+ if (value !== null && value !== void 0 && !isNaN(value)) {
92
+ setDisplayValue(formatNumber(value));
93
+ } else {
94
+ setDisplayValue("");
95
+ }
96
+ };
97
+ const handleKeyDown = (e) => {
98
+ if (ALLOWED_NAVIGATION_KEYS.has(e.key)) return;
99
+ if ((e.ctrlKey || e.metaKey) && ALLOWED_SHORTCUT_KEYS.has(e.key.toLowerCase())) return;
100
+ if (/^[0-9]$/.test(e.key)) return;
101
+ if (e.key === "." || e.key === "-") return;
102
+ e.preventDefault();
103
+ };
104
+ const symbolLength = currency.length;
105
+ const inputPaddingClass = symbolLength <= 1 ? "pl-8" : symbolLength === 2 ? "pl-10" : symbolLength === 3 ? "pl-12" : "pl-14";
106
+ return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
107
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
108
+ /* @__PURE__ */ jsx(
109
+ "span",
110
+ {
111
+ "aria-hidden": true,
112
+ className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-sm font-semibold text-muted-foreground",
113
+ children: currency
114
+ }
115
+ ),
116
+ /* @__PURE__ */ jsx(
117
+ Input,
118
+ __spreadValues({
119
+ ref,
120
+ id,
121
+ type: "text",
122
+ inputMode: "decimal",
123
+ value: displayValue,
124
+ onChange: handleInputChange,
125
+ onFocus: handleFocus,
126
+ onBlur: handleBlur,
127
+ onKeyDown: handleKeyDown,
128
+ placeholder,
129
+ disabled,
130
+ "aria-invalid": error ? true : void 0,
131
+ "aria-describedby": error ? errorId : void 0,
132
+ className: cn(inputPaddingClass, className)
133
+ }, props)
134
+ )
135
+ ] }),
136
+ error && /* @__PURE__ */ jsx("p", { id: errorId, className: "ml-1 mt-1 text-sm text-destructive", children: error })
137
+ ] });
138
+ }
139
+ );
140
+ CurrencyInput.displayName = "CurrencyInput";
141
+
142
+ export { CurrencyInput };
@@ -37,7 +37,19 @@ var badgeVariants = cva(
37
37
  * of `confirmed` / `pending`: the same pill, the muted ink, because
38
38
  * nothing about it needs acting on.
39
39
  */
40
- completed: "rounded-full border-0 bg-muted px-[9px] py-[3px] text-[10.5px] leading-[1.2] font-bold text-muted-foreground"
40
+ completed: "rounded-full border-0 bg-muted px-[9px] py-[3px] text-[10.5px] leading-[1.2] font-bold text-muted-foreground",
41
+ /**
42
+ * Who an item belongs to, in the organise table (T4 desktop): a soft
43
+ * pill carrying an avatar (or an `AvatarGroup` for "Shared") and a
44
+ * chevron, because the whole pill opens "Who had this?".
45
+ *
46
+ * It is a control, not a status, so it keeps 6px of inset either side
47
+ * of its slots and `gap-1.5` between them; the caller renders the
48
+ * avatar and the chevron as children. Sized to clear 44px of tap
49
+ * target when it is the row's own control — see `MenuPickRow` for the
50
+ * same rule on the add toggle.
51
+ */
52
+ assignee: "rounded-full border-0 bg-surface-2 py-1 pl-1 pr-2 gap-1.5 text-[12px] leading-[1.2] font-semibold text-foreground"
41
53
  },
42
54
  /**
43
55
  * `status` is the taller pill the booking design draws beside a
@@ -49,9 +49,9 @@ var dialogContentVariants = cva(
49
49
  );
50
50
  var DialogContent = React.forwardRef(
51
51
  (_a, ref) => {
52
- var _b = _a, { className, children, size, scrollBehavior, showCloseButton = true } = _b, props = __objRest(_b, ["className", "children", "size", "scrollBehavior", "showCloseButton"]);
52
+ var _b = _a, { className, children, size, scrollBehavior, showCloseButton = true, overlayClassName } = _b, props = __objRest(_b, ["className", "children", "size", "scrollBehavior", "showCloseButton", "overlayClassName"]);
53
53
  return /* @__PURE__ */ jsxs(DialogPortal, { children: [
54
- /* @__PURE__ */ jsx(DialogOverlay, {}),
54
+ /* @__PURE__ */ jsx(DialogOverlay, { className: overlayClassName }),
55
55
  /* @__PURE__ */ jsxs(
56
56
  DialogPrimitive.Content,
57
57
  __spreadProps(__spreadValues({
@@ -1,4 +1,4 @@
1
- import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from './chunk-JWTN7MNK.js';
1
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from './chunk-TVEIUTBQ.js';
2
2
  import { cn } from './chunk-FEK5XGZW.js';
3
3
  import { __objRest, __spreadValues, __spreadProps } from './chunk-MMUBH76A.js';
4
4
  import * as React from 'react';
@@ -0,0 +1,127 @@
1
+ import { cn } from './chunk-FEK5XGZW.js';
2
+ import { __objRest, __spreadValues, __spreadProps } from './chunk-MMUBH76A.js';
3
+ import * as React from 'react';
4
+ import { Drawer as Drawer$1 } from 'vaul';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+
7
+ var DrawerDirectionContext = React.createContext("bottom");
8
+ var Drawer = (_a) => {
9
+ var _b = _a, {
10
+ shouldScaleBackground = false,
11
+ direction = "bottom"
12
+ } = _b, props = __objRest(_b, [
13
+ "shouldScaleBackground",
14
+ "direction"
15
+ ]);
16
+ return /* @__PURE__ */ jsx(DrawerDirectionContext.Provider, { value: direction, children: /* @__PURE__ */ jsx(
17
+ Drawer$1.Root,
18
+ __spreadValues({
19
+ shouldScaleBackground,
20
+ direction
21
+ }, props)
22
+ ) });
23
+ };
24
+ Drawer.displayName = "Drawer";
25
+ var DrawerTrigger = Drawer$1.Trigger;
26
+ var DrawerPortal = Drawer$1.Portal;
27
+ var DrawerClose = Drawer$1.Close;
28
+ var DrawerOverlay = React.forwardRef((_a, ref) => {
29
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
30
+ return /* @__PURE__ */ jsx(
31
+ Drawer$1.Overlay,
32
+ __spreadValues({
33
+ ref,
34
+ "data-slot": "drawer-overlay",
35
+ className: cn("fixed inset-0 z-[1000] bg-black/60", className)
36
+ }, props)
37
+ );
38
+ });
39
+ DrawerOverlay.displayName = Drawer$1.Overlay.displayName;
40
+ var DrawerContent = React.forwardRef((_a, ref) => {
41
+ var _b = _a, { className, variant = "flush", showHandle, overlayClassName, children } = _b, props = __objRest(_b, ["className", "variant", "showHandle", "overlayClassName", "children"]);
42
+ const direction = React.useContext(DrawerDirectionContext);
43
+ const isVertical = direction === "top" || direction === "bottom";
44
+ const handleEnabled = showHandle != null ? showHandle : direction === "bottom";
45
+ const positionClasses = direction === "bottom" ? "inset-x-0 bottom-0 flex-col rounded-t-2xl border-t [padding-bottom:max(env(safe-area-inset-bottom),0px)]" : direction === "top" ? "inset-x-0 top-0 flex-col rounded-b-2xl border-b [padding-top:max(env(safe-area-inset-top),0px)]" : direction === "left" ? "inset-y-0 left-0 h-full w-3/4 max-w-sm flex-col rounded-r-2xl border-r [padding-left:max(env(safe-area-inset-left),0px)]" : "inset-y-0 right-0 h-full w-3/4 max-w-sm flex-col rounded-l-2xl border-l [padding-right:max(env(safe-area-inset-right),0px)]";
46
+ return /* @__PURE__ */ jsxs(DrawerPortal, { children: [
47
+ /* @__PURE__ */ jsx(DrawerOverlay, { className: overlayClassName }),
48
+ /* @__PURE__ */ jsxs(
49
+ Drawer$1.Content,
50
+ __spreadProps(__spreadValues({
51
+ ref,
52
+ "data-slot": "drawer-content",
53
+ className: cn(
54
+ "fixed z-[1000] flex border-border bg-card shadow-[var(--shadow-overlay)]",
55
+ positionClasses,
56
+ // The single height cap for every vertical drawer. Consumers should
57
+ // NOT restate it: six app call sites carried an identical
58
+ // `!max-h-[90vh]`, so this default governed nothing and changing it
59
+ // here would have reached none of them.
60
+ isVertical ? "max-h-[85vh]" : "",
61
+ variant === "floating" && "m-3 rounded-2xl border",
62
+ className
63
+ )
64
+ }, props), {
65
+ children: [
66
+ handleEnabled && /* @__PURE__ */ jsx(
67
+ "div",
68
+ {
69
+ "aria-hidden": true,
70
+ className: "mx-auto mt-2 h-1.5 w-[60px] shrink-0 rounded-full bg-muted-foreground/30"
71
+ }
72
+ ),
73
+ children
74
+ ]
75
+ })
76
+ )
77
+ ] });
78
+ });
79
+ DrawerContent.displayName = "DrawerContent";
80
+ var DrawerHeader = (_a) => {
81
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
82
+ return /* @__PURE__ */ jsx(
83
+ "div",
84
+ __spreadValues({
85
+ "data-slot": "drawer-header",
86
+ className: cn("grid gap-1.5 p-4 text-center sm:text-left", className)
87
+ }, props)
88
+ );
89
+ };
90
+ DrawerHeader.displayName = "DrawerHeader";
91
+ var DrawerFooter = (_a) => {
92
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
93
+ return /* @__PURE__ */ jsx(
94
+ "div",
95
+ __spreadValues({
96
+ "data-slot": "drawer-footer",
97
+ className: cn("mt-auto flex flex-col gap-2 p-4", className)
98
+ }, props)
99
+ );
100
+ };
101
+ DrawerFooter.displayName = "DrawerFooter";
102
+ var DrawerTitle = React.forwardRef((_a, ref) => {
103
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
104
+ return /* @__PURE__ */ jsx(
105
+ Drawer$1.Title,
106
+ __spreadValues({
107
+ ref,
108
+ "data-slot": "drawer-title",
109
+ className: cn("text-lg font-semibold leading-none tracking-tight", className)
110
+ }, props)
111
+ );
112
+ });
113
+ DrawerTitle.displayName = Drawer$1.Title.displayName;
114
+ var DrawerDescription = React.forwardRef((_a, ref) => {
115
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
116
+ return /* @__PURE__ */ jsx(
117
+ Drawer$1.Description,
118
+ __spreadValues({
119
+ ref,
120
+ "data-slot": "drawer-description",
121
+ className: cn("text-sm text-muted-foreground", className)
122
+ }, props)
123
+ );
124
+ });
125
+ DrawerDescription.displayName = Drawer$1.Description.displayName;
126
+
127
+ export { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger };
@@ -1,4 +1,4 @@
1
- import { SignatureChip } from './chunk-GESB7GCF.js';
1
+ import { SignatureChip } from './chunk-6W25S5CF.js';
2
2
  import { cn } from './chunk-FEK5XGZW.js';
3
3
  import { __objRest, __spreadValues } from './chunk-MMUBH76A.js';
4
4
  import { memo } from 'react';
@@ -0,0 +1,67 @@
1
+ import * as React from 'react';
2
+
3
+ /**
4
+ * ActionBar — the band that closes a screen or an overlay: the note that
5
+ * qualifies the action on one side, the actions on the other.
6
+ *
7
+ * The shared-table board draws it three ways and they are one component
8
+ * (16-shared-table.html): the table overview's "Add item · Organise" pair
9
+ * over the bottom nav (T2), the add-item overlay's "Added items can be
10
+ * assigned afterwards." beside "Add 1 item" (T3), and the split sheet's lone
11
+ * "Save split" (T6). The booking flow draws the same band under its steps.
12
+ *
13
+ * Two rules the frames are consistent about:
14
+ * - The actions sit on the trailing edge at their own width, and `primary` is
15
+ * last. A `note` takes the left, so the qualifier is read before the commit.
16
+ * Only the table overview divides the bar between two equal buttons — that
17
+ * is `layout="split"`, not the default. (T5 and T6 draw a lone Save on the
18
+ * trailing edge; T6 and X10 draw Cancel + Save split right-aligned.)
19
+ * - The bar owns the home-indicator inset. `pb-[max(env(safe-area-inset-bottom),12px)]`
20
+ * is here and nowhere else, so no caller has to remember it.
21
+ *
22
+ * App-only offsets — bearmenu-fe's `--bottom-nav-offset`, `--page-gutter` —
23
+ * arrive through `className`. The design system does not know the app's
24
+ * chrome and must not guess at it.
25
+ */
26
+ type ActionBarProps = Omit<React.HTMLAttributes<HTMLDivElement>, "children"> & {
27
+ /** The commit. Trailing edge, always last in the DOM. */
28
+ primary: React.ReactNode;
29
+ /** The way out — Cancel, Keep organising. Sits before the primary. */
30
+ secondary?: React.ReactNode;
31
+ /** The line that qualifies the action. Takes the left when present. */
32
+ note?: React.ReactNode;
33
+ /**
34
+ * `end` (the default) keeps the actions at their own width on the trailing
35
+ * edge. `split` divides the bar between them — the table overview's
36
+ * "Add item · Organise" pair, and nothing else the board draws.
37
+ */
38
+ layout?: "end" | "split";
39
+ /**
40
+ * Pins the bar to the bottom of its scroll container with the band's own
41
+ * ground and hairline. Off by default: inside an overlay the footer is
42
+ * already the last row of a flex column and does not need to stick.
43
+ */
44
+ sticky?: boolean;
45
+ };
46
+ declare const ActionBar: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "children"> & {
47
+ /** The commit. Trailing edge, always last in the DOM. */
48
+ primary: React.ReactNode;
49
+ /** The way out — Cancel, Keep organising. Sits before the primary. */
50
+ secondary?: React.ReactNode;
51
+ /** The line that qualifies the action. Takes the left when present. */
52
+ note?: React.ReactNode;
53
+ /**
54
+ * `end` (the default) keeps the actions at their own width on the trailing
55
+ * edge. `split` divides the bar between them — the table overview's
56
+ * "Add item · Organise" pair, and nothing else the board draws.
57
+ */
58
+ layout?: "end" | "split";
59
+ /**
60
+ * Pins the bar to the bottom of its scroll container with the band's own
61
+ * ground and hairline. Off by default: inside an overlay the footer is
62
+ * already the last row of a flex column and does not need to stick.
63
+ */
64
+ sticky?: boolean;
65
+ } & React.RefAttributes<HTMLDivElement>>;
66
+
67
+ export { ActionBar, type ActionBarProps };
@@ -0,0 +1,43 @@
1
+ import { cn } from '../chunk-FEK5XGZW.js';
2
+ import { __objRest, __spreadProps, __spreadValues } from '../chunk-MMUBH76A.js';
3
+ import * as React from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var ActionBar = React.forwardRef(
7
+ (_a, ref) => {
8
+ var _b = _a, { className, primary, secondary, note, layout = "end", sticky = false } = _b, props = __objRest(_b, ["className", "primary", "secondary", "note", "layout", "sticky"]);
9
+ return /* @__PURE__ */ jsxs(
10
+ "div",
11
+ __spreadProps(__spreadValues({
12
+ ref,
13
+ "data-slot": "action-bar",
14
+ className: cn(
15
+ "flex items-center gap-3 px-4 pt-3 pb-[max(env(safe-area-inset-bottom),12px)]",
16
+ sticky && "sticky bottom-0 z-10 border-t border-border bg-card",
17
+ className
18
+ )
19
+ }, props), {
20
+ children: [
21
+ note ? /* @__PURE__ */ jsx("div", { "data-slot": "action-bar-note", className: "min-w-0 flex-1 text-[12.5px] leading-normal text-muted-foreground", children: note }) : null,
22
+ /* @__PURE__ */ jsxs(
23
+ "div",
24
+ {
25
+ "data-slot": "action-bar-actions",
26
+ className: cn(
27
+ "flex items-center gap-3",
28
+ layout === "split" ? "flex-1 [&>*]:flex-1" : "ml-auto shrink-0"
29
+ ),
30
+ children: [
31
+ secondary,
32
+ primary
33
+ ]
34
+ }
35
+ )
36
+ ]
37
+ })
38
+ );
39
+ }
40
+ );
41
+ ActionBar.displayName = "ActionBar";
42
+
43
+ export { ActionBar };
@@ -0,0 +1,38 @@
1
+ import * as React from 'react';
2
+
3
+ /**
4
+ * ActivityRow / ActivityList — what happened at the table, newest first
5
+ * (16-shared-table.html T9): "Bruno added Tochitură ardelenească · 9 min ago",
6
+ * down to "Adrian opened the table · 19:42".
7
+ *
8
+ * The leading slot is the actor's avatar when an event has one and a quiet
9
+ * glyph disc when it does not — a split belongs to an item, not to a person.
10
+ * Both are 32px so the sentences stay on one left edge however the feed mixes.
11
+ *
12
+ * The rows come from an append-only log, not from the current state: state
13
+ * cannot say that Ana moved Papanași to herself, only that it is hers now.
14
+ */
15
+ type ActivityRowProps = Omit<React.LiHTMLAttributes<HTMLLIElement>, "children"> & {
16
+ /** The actor's `Avatar`. Wins over `icon` when both are given. */
17
+ avatar?: React.ReactNode;
18
+ /** A lucide glyph for an event with no actor. Sits in a muted disc. */
19
+ icon?: React.ReactNode;
20
+ /** The sentence — the caller bolds the actor inside it. */
21
+ body: React.ReactNode;
22
+ /** "9 min ago", "19:42". Formatted by the caller. */
23
+ time: React.ReactNode;
24
+ };
25
+ declare const ActivityRow: React.ForwardRefExoticComponent<Omit<React.LiHTMLAttributes<HTMLLIElement>, "children"> & {
26
+ /** The actor's `Avatar`. Wins over `icon` when both are given. */
27
+ avatar?: React.ReactNode;
28
+ /** A lucide glyph for an event with no actor. Sits in a muted disc. */
29
+ icon?: React.ReactNode;
30
+ /** The sentence — the caller bolds the actor inside it. */
31
+ body: React.ReactNode;
32
+ /** "9 min ago", "19:42". Formatted by the caller. */
33
+ time: React.ReactNode;
34
+ } & React.RefAttributes<HTMLLIElement>>;
35
+ type ActivityListProps = React.HTMLAttributes<HTMLUListElement>;
36
+ declare const ActivityList: React.ForwardRefExoticComponent<ActivityListProps & React.RefAttributes<HTMLUListElement>>;
37
+
38
+ export { ActivityList, type ActivityListProps, ActivityRow, type ActivityRowProps };
@@ -0,0 +1,43 @@
1
+ import { cn } from '../chunk-FEK5XGZW.js';
2
+ import { __objRest, __spreadProps, __spreadValues } from '../chunk-MMUBH76A.js';
3
+ import * as React from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var ActivityRow = React.forwardRef(
7
+ (_a, ref) => {
8
+ var _b = _a, { className, avatar, icon, body, time } = _b, props = __objRest(_b, ["className", "avatar", "icon", "body", "time"]);
9
+ return /* @__PURE__ */ jsxs(
10
+ "li",
11
+ __spreadProps(__spreadValues({
12
+ ref,
13
+ "data-slot": "activity-row",
14
+ className: cn("flex items-start gap-3 py-3", className)
15
+ }, props), {
16
+ children: [
17
+ /* @__PURE__ */ jsx("div", { className: "shrink-0", children: avatar != null ? avatar : /* @__PURE__ */ jsx("span", { className: "grid size-8 place-items-center rounded-full bg-muted text-muted-foreground [&>svg]:size-4", children: icon }) }),
18
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
19
+ /* @__PURE__ */ jsx("div", { className: "text-[14px] leading-snug", children: body }),
20
+ /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-[12.5px] text-muted-foreground", children: time })
21
+ ] })
22
+ ]
23
+ })
24
+ );
25
+ }
26
+ );
27
+ ActivityRow.displayName = "ActivityRow";
28
+ var ActivityList = React.forwardRef(
29
+ (_a, ref) => {
30
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
31
+ return /* @__PURE__ */ jsx(
32
+ "ul",
33
+ __spreadValues({
34
+ ref,
35
+ "data-slot": "activity-list",
36
+ className: cn("divide-y divide-border", className)
37
+ }, props)
38
+ );
39
+ }
40
+ );
41
+ ActivityList.displayName = "ActivityList";
42
+
43
+ export { ActivityList, ActivityRow };
@@ -3,10 +3,10 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const alertVariants: (props?: ({
6
- variant?: "default" | "destructive" | "warning" | "success" | null | undefined;
6
+ variant?: "default" | "success" | "warning" | "destructive" | null | undefined;
7
7
  } & class_variance_authority_types.ClassProp) | undefined) => string;
8
8
  declare const Alert: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
9
- variant?: "default" | "destructive" | "warning" | "success" | null | undefined;
9
+ variant?: "default" | "success" | "warning" | "destructive" | null | undefined;
10
10
  } & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLDivElement>>;
11
11
  declare const AlertTitle: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLHeadingElement> & React.RefAttributes<HTMLParagraphElement>>;
12
12
  declare const AlertDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
@@ -5,10 +5,13 @@ import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const avatarVariants: (props?: ({
7
7
  size?: "default" | "xs" | "sm" | "lg" | "xl" | null | undefined;
8
+ tone?: "brown" | "muted" | "teal" | "green" | "blue" | "violet" | "rose" | null | undefined;
8
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
10
  type AvatarSize = NonNullable<VariantProps<typeof avatarVariants>["size"]>;
11
+ type AvatarTone = NonNullable<VariantProps<typeof avatarVariants>["tone"]>;
10
12
  declare const Avatar: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarProps & React.RefAttributes<HTMLSpanElement>, "ref"> & VariantProps<(props?: ({
11
13
  size?: "default" | "xs" | "sm" | "lg" | "xl" | null | undefined;
14
+ tone?: "brown" | "muted" | "teal" | "green" | "blue" | "violet" | "rose" | null | undefined;
12
15
  } & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLSpanElement>>;
13
16
  declare const AvatarImage: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarImageProps & React.RefAttributes<HTMLImageElement>, "ref"> & React.RefAttributes<HTMLImageElement>>;
14
17
  declare const AvatarFallback: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarFallbackProps & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
@@ -29,4 +32,4 @@ declare const AvatarGroup: React.ForwardRefExoticComponent<React.HTMLAttributes<
29
32
  size?: AvatarSize;
30
33
  } & React.RefAttributes<HTMLDivElement>>;
31
34
 
32
- export { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarImage, type AvatarSize, avatarGroupOverflowVariants, avatarVariants };
35
+ export { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarImage, type AvatarSize, type AvatarTone, avatarGroupOverflowVariants, avatarVariants };
@@ -15,6 +15,34 @@ var avatarVariants = cva(
15
15
  default: "size-10 text-sm",
16
16
  lg: "size-12 text-base",
17
17
  xl: "size-16 text-lg"
18
+ },
19
+ /**
20
+ * A person's fixed hue at a shared table: the same face is the same
21
+ * colour on the ledger card, the organise chip, the split row and the
22
+ * activity feed, so a reader tracks people by colour and never has to
23
+ * re-read a name (16-shared-table.html, T2/T4/T6/T9).
24
+ *
25
+ * The caller assigns it — from join order, from the wire, from wherever
26
+ * it keeps its participants. The design system never hashes a name into
27
+ * a colour: a hash re-colours everyone when one person joins, and gives
28
+ * two people the same hue often enough to matter at a table of four.
29
+ *
30
+ * `muted` is the non-person disc — the "Shared between everyone" card's
31
+ * people glyph, an activity row with no actor.
32
+ *
33
+ * Six hues, assigned in the order listed. The board draws the first
34
+ * three; the rest space across the arc they leave free. Past six, cycle —
35
+ * at that size the initial and the name are doing the identifying, and
36
+ * colour is a support cue, never the only one.
37
+ */
38
+ tone: {
39
+ brown: "bg-avatar-brown",
40
+ teal: "bg-avatar-teal",
41
+ green: "bg-avatar-green",
42
+ blue: "bg-avatar-blue",
43
+ violet: "bg-avatar-violet",
44
+ rose: "bg-avatar-rose",
45
+ muted: "bg-muted"
18
46
  }
19
47
  },
20
48
  defaultVariants: {
@@ -23,18 +51,20 @@ var avatarVariants = cva(
23
51
  }
24
52
  );
25
53
  var AvatarContext = React.createContext("default");
54
+ var AvatarToneContext = React.createContext(null);
26
55
  var Avatar = React.forwardRef((_a, ref) => {
27
- var _b = _a, { className, size } = _b, props = __objRest(_b, ["className", "size"]);
56
+ var _b = _a, { className, size, tone } = _b, props = __objRest(_b, ["className", "size", "tone"]);
28
57
  const inheritedSize = React.useContext(AvatarContext);
29
58
  const resolvedSize = size != null ? size : inheritedSize;
30
- return /* @__PURE__ */ jsx(AvatarContext.Provider, { value: resolvedSize, children: /* @__PURE__ */ jsx(
59
+ return /* @__PURE__ */ jsx(AvatarContext.Provider, { value: resolvedSize, children: /* @__PURE__ */ jsx(AvatarToneContext.Provider, { value: tone != null ? tone : null, children: /* @__PURE__ */ jsx(
31
60
  AvatarPrimitive.Root,
32
61
  __spreadValues({
33
62
  ref,
34
63
  "data-slot": "avatar",
35
- className: cn(avatarVariants({ size: resolvedSize }), className)
64
+ "data-tone": tone != null ? tone : void 0,
65
+ className: cn(avatarVariants({ size: resolvedSize, tone }), className)
36
66
  }, props)
37
- ) });
67
+ ) }) });
38
68
  });
39
69
  Avatar.displayName = AvatarPrimitive.Root.displayName;
40
70
  var AvatarImage = React.forwardRef((_a, ref) => {
@@ -51,13 +81,17 @@ var AvatarImage = React.forwardRef((_a, ref) => {
51
81
  AvatarImage.displayName = AvatarPrimitive.Image.displayName;
52
82
  var AvatarFallback = React.forwardRef((_a, ref) => {
53
83
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
84
+ const tone = React.useContext(AvatarToneContext);
54
85
  return /* @__PURE__ */ jsx(
55
86
  AvatarPrimitive.Fallback,
56
87
  __spreadValues({
57
88
  ref,
58
89
  "data-slot": "avatar-fallback",
59
90
  className: cn(
60
- "flex size-full items-center justify-center rounded-full bg-muted font-semibold text-muted-foreground",
91
+ "flex size-full items-center justify-center rounded-full font-semibold",
92
+ tone === null && "bg-muted text-muted-foreground",
93
+ tone === "muted" && "text-muted-foreground",
94
+ tone !== null && tone !== "muted" && "text-white",
61
95
  className
62
96
  )
63
97
  }, props)
@@ -4,7 +4,7 @@ import * as React from 'react';
4
4
  import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const badgeVariants: (props?: ({
7
- variant?: "code" | "default" | "destructive" | "outline" | "secondary" | "glass" | "overlay" | "brown" | "warning" | "success" | "onPrimary" | "confirmed" | "pending" | "completed" | null | undefined;
7
+ variant?: "secondary" | "default" | "success" | "warning" | "destructive" | "outline" | "glass" | "overlay" | "brown" | "code" | "onPrimary" | "confirmed" | "pending" | "completed" | "assignee" | null | undefined;
8
8
  size?: "status" | "chip" | null | undefined;
9
9
  live?: boolean | null | undefined;
10
10
  } & class_variance_authority_types.ClassProp) | undefined) => string;
@@ -1,3 +1,3 @@
1
- export { Badge, badgeVariants } from '../chunk-ZU4NAYN7.js';
1
+ export { Badge, badgeVariants } from '../chunk-NIAL4ZU2.js';
2
2
  import '../chunk-FEK5XGZW.js';
3
3
  import '../chunk-MMUBH76A.js';