@columenlabs/lumen-ui 0.1.131 → 0.1.132

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.
@@ -9,17 +9,17 @@ export interface StatusMessage {
9
9
  interface Group extends Required<StatusMessage> {
10
10
  count: number;
11
11
  }
12
- /** One entry per distinct message (same tone, same words), counted, most severe first. */
12
+ /** One entry per distinct message (same tone, same words), counted, in the order given. */
13
13
  export declare function groupStatusMessages(messages: readonly StatusMessage[]): Group[];
14
14
  /**
15
- * The app's messages in the status bar. Each message is one line that ends in an ellipsis past
16
- * `--status-message-max`, with its full text on hover or tap; a repeated message shows once with
17
- * `×N`; past `max` messages (one on a phone), a `+N` chip lists the rest.
15
+ * The app's messages in the status bar, newest first. Only the latest shows, on one line that ends
16
+ * in an ellipsis past `--status-message-max`, with its full text on hover or tap; a new message
17
+ * takes its place rather than adding a second line. A repeat shows once with `×N`, and the earlier
18
+ * messages sit behind a `+N` chip that lists them.
18
19
  */
19
- export declare function StatusMessages({ messages, max, className, }: {
20
+ export declare function StatusMessages({ messages, className, }: {
21
+ /** Newest first. */
20
22
  messages: readonly StatusMessage[];
21
- /** How many messages show at once on a wider screen; the rest go behind the `+N` chip. */
22
- max?: number;
23
23
  className?: string;
24
24
  }): import("react").JSX.Element | null;
25
25
  export {};
@@ -1,10 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useHoverOpen } from './hooks/use-hover-open.js';
3
- import { useIsMobile } from './hooks/use-mobile.js';
4
3
  import { cn } from './lib/utils.js';
5
4
  import { Popover, PopoverContent, PopoverTrigger } from './ui/popover.js';
6
- /** Errors first, then warnings, so the message that matters most is the one in view. */
7
- const RANK = { error: 0, warning: 1, success: 2, info: 3 };
8
5
  const TEXT = {
9
6
  error: 'text-destructive',
10
7
  warning: 'text-warning',
@@ -17,7 +14,7 @@ const DOT = {
17
14
  success: 'bg-gain',
18
15
  info: undefined,
19
16
  };
20
- /** One entry per distinct message (same tone, same words), counted, most severe first. */
17
+ /** One entry per distinct message (same tone, same words), counted, in the order given. */
21
18
  export function groupStatusMessages(messages) {
22
19
  const groups = new Map();
23
20
  for (const m of messages) {
@@ -33,8 +30,8 @@ export function groupStatusMessages(messages) {
33
30
  else
34
31
  groups.set(key, { text, tone, count });
35
32
  }
36
- // Map keeps first-seen order; the sort is stable, so equal tones keep it.
37
- return [...groups.values()].sort((a, b) => RANK[a.tone] - RANK[b.tone]);
33
+ // Map keeps first-seen order, so the latest message stays first.
34
+ return [...groups.values()];
38
35
  }
39
36
  const label = (g) => (g.count > 1 ? `${g.text} (×${g.count})` : g.text);
40
37
  function Dot({ tone }) {
@@ -57,16 +54,14 @@ function Line({ group }) {
57
54
  return (_jsxs(Pop, { className: cn(TRIGGER, 'min-w-0 max-w-(--status-message-max)'), content: _jsx("p", { className: TEXT[group.tone], children: label(group) }), children: [_jsx(Dot, { tone: group.tone }), _jsx("span", { className: cn('min-w-0 truncate', TEXT[group.tone]), children: group.text }), group.count > 1 && (_jsxs("span", { className: "num shrink-0 text-foreground/80", "aria-label": `${group.count} times`, children: ["\u00D7", group.count] }))] }));
58
55
  }
59
56
  /**
60
- * The app's messages in the status bar. Each message is one line that ends in an ellipsis past
61
- * `--status-message-max`, with its full text on hover or tap; a repeated message shows once with
62
- * `×N`; past `max` messages (one on a phone), a `+N` chip lists the rest.
57
+ * The app's messages in the status bar, newest first. Only the latest shows, on one line that ends
58
+ * in an ellipsis past `--status-message-max`, with its full text on hover or tap; a new message
59
+ * takes its place rather than adding a second line. A repeat shows once with `×N`, and the earlier
60
+ * messages sit behind a `+N` chip that lists them.
63
61
  */
64
- export function StatusMessages({ messages, max = 2, className, }) {
65
- const phone = useIsMobile();
66
- const groups = groupStatusMessages(messages);
67
- if (!groups.length)
62
+ export function StatusMessages({ messages, className, }) {
63
+ const [latest, ...earlier] = groupStatusMessages(messages);
64
+ if (!latest)
68
65
  return null;
69
- const shown = groups.slice(0, phone ? 1 : Math.max(1, max));
70
- const rest = groups.slice(shown.length);
71
- return (_jsxs("span", { "aria-live": "polite", className: cn('flex min-w-0 items-center gap-2', className), children: [shown.map((g) => (_jsx(Line, { group: g }, `${g.tone}:${g.text}`))), rest.length > 0 && (_jsxs(Pop, { label: `${rest.length} more messages`, className: cn(TRIGGER, 'num shrink-0 text-foreground/80'), content: _jsx("ul", { className: "flex flex-col gap-1", children: rest.map((g) => (_jsxs("li", { className: "flex items-start gap-1.5", children: [_jsx("span", { className: "flex h-4 items-center", children: _jsx(Dot, { tone: g.tone }) }), _jsx("span", { className: TEXT[g.tone], children: label(g) })] }, `${g.tone}:${g.text}`))) }), children: ["+", rest.length] }))] }));
66
+ return (_jsxs("span", { "aria-live": "polite", className: cn('flex min-w-0 items-center gap-2', className), children: [_jsx(Line, { group: latest }), earlier.length > 0 && (_jsxs(Pop, { label: `${earlier.length} earlier messages`, className: cn(TRIGGER, 'num shrink-0 text-foreground/80'), content: _jsx("ul", { className: "flex flex-col gap-1", children: earlier.map((g) => (_jsxs("li", { className: "flex items-start gap-1.5", children: [_jsx("span", { className: "flex h-4 items-center", children: _jsx(Dot, { tone: g.tone }) }), _jsx("span", { className: TEXT[g.tone], children: label(g) })] }, `${g.tone}:${g.text}`))) }), children: ["+", earlier.length] }))] }));
72
67
  }
package/dist/theme.css CHANGED
@@ -89,8 +89,8 @@
89
89
  --shell-header-height: 48px;
90
90
  --shell-status-height: 32px;
91
91
  /* A status bar message ends in an ellipsis here (StatusMessages), so it fits beside the bar's
92
- other items; the full text opens on hover or tap. A phone shows one message, a wider screen two. */
93
- --status-message-max: 45vw;
92
+ other items; the full text opens on hover or tap. */
93
+ --status-message-max: 55vw;
94
94
  --tile-width: 8.5rem;
95
95
  --shell-gutter: 12px;
96
96
  --shell-section-gap: 12px;
@@ -215,7 +215,7 @@
215
215
  @media (min-width: 768px) {
216
216
  :root {
217
217
  --shell-gutter: 16px;
218
- --status-message-max: min(28rem, 30vw);
218
+ --status-message-max: min(40rem, 45vw);
219
219
  }
220
220
  }
221
221
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@columenlabs/lumen-ui",
3
- "version": "0.1.131",
3
+ "version": "0.1.132",
4
4
  "description": "Lumen: shared React components (frame, views, widgets, charts, drawers).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -49,7 +49,7 @@
49
49
  "@codemirror/lang-javascript": "6.2.5",
50
50
  "@codemirror/lang-json": "6.0.2",
51
51
  "@codemirror/lang-sql": "6.10.0",
52
- "@columenlabs/lumen-ui-types": "0.1.131",
52
+ "@columenlabs/lumen-ui-types": "0.1.132",
53
53
  "@dnd-kit/core": "6.3.1",
54
54
  "@dnd-kit/sortable": "10.0.0",
55
55
  "@dnd-kit/utilities": "3.2.2",