@brokr/sdk 2.0.0 → 2.1.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 (41) hide show
  1. package/dist/react-notifications.js +63 -50
  2. package/dist/react-notifications.mjs +63 -50
  3. package/dist/react-styles.js +113 -75
  4. package/dist/react-styles.mjs +113 -75
  5. package/dist/react-theme.js +6 -4
  6. package/dist/react-theme.mjs +6 -4
  7. package/dist/react.js +325 -246
  8. package/dist/react.mjs +360 -281
  9. package/dist/src/react/account/AccountPanel.d.ts.map +1 -1
  10. package/dist/src/react/account/UserButton.d.ts.map +1 -1
  11. package/dist/src/react/chat/AIChat.d.ts.map +1 -1
  12. package/dist/src/react/chat/ChatInput.d.ts.map +1 -1
  13. package/dist/src/react/chat/MessagePane.d.ts.map +1 -1
  14. package/dist/src/react/chat/ModelSelector.d.ts.map +1 -1
  15. package/dist/src/react/chat/ThreadSidebar.d.ts.map +1 -1
  16. package/dist/src/react/composites/FabAI.d.ts.map +1 -1
  17. package/dist/src/react/css/account.d.ts +1 -1
  18. package/dist/src/react/css/account.d.ts.map +1 -1
  19. package/dist/src/react/css/auth.d.ts +1 -1
  20. package/dist/src/react/css/auth.d.ts.map +1 -1
  21. package/dist/src/react/css/chat-extras.d.ts +1 -1
  22. package/dist/src/react/css/chat-extras.d.ts.map +1 -1
  23. package/dist/src/react/css/chat.d.ts +1 -1
  24. package/dist/src/react/css/chat.d.ts.map +1 -1
  25. package/dist/src/react/css/composites.d.ts +1 -1
  26. package/dist/src/react/css/composites.d.ts.map +1 -1
  27. package/dist/src/react/css/markdown.d.ts +1 -1
  28. package/dist/src/react/css/markdown.d.ts.map +1 -1
  29. package/dist/src/react/css/notifications.d.ts +1 -1
  30. package/dist/src/react/css/notifications.d.ts.map +1 -1
  31. package/dist/src/react/css/tokens.d.ts +1 -1
  32. package/dist/src/react/css/tokens.d.ts.map +1 -1
  33. package/dist/src/react/notifications/NotificationBell.d.ts.map +1 -1
  34. package/dist/src/react/notifications/NotificationList.d.ts.map +1 -1
  35. package/dist/src/react/notifications/Toast.d.ts.map +1 -1
  36. package/dist/src/react/payments/Plans.d.ts.map +1 -1
  37. package/dist/src/react/theme.d.ts.map +1 -1
  38. package/dist/src/react/types.d.ts +4 -4
  39. package/dist/src/react/types.d.ts.map +1 -1
  40. package/dist/tsconfig.tsbuildinfo +1 -1
  41. package/package.json +1 -1
package/dist/react.js CHANGED
@@ -4237,10 +4237,12 @@ function getBrokrRootStyle(theme) {
4237
4237
  ...theme.colors.error ? { ["--brokr-error"]: theme.colors.error } : {},
4238
4238
  ...theme.colors.success ? { ["--brokr-success"]: theme.colors.success } : {},
4239
4239
  ...theme.colors.warning ? { ["--brokr-warning"]: theme.colors.warning } : {},
4240
- ...theme.colors.toastBg ? { ["--brokr-toast-bg"]: theme.colors.toastBg } : {},
4241
- ...theme.colors.toastText ? { ["--brokr-toast-text"]: theme.colors.toastText } : {},
4242
- ...theme.colors.toastTextSecondary ? { ["--brokr-toast-text-secondary"]: theme.colors.toastTextSecondary } : {},
4243
- ...theme.colors.toastBorder ? { ["--brokr-toast-border"]: theme.colors.toastBorder } : {},
4240
+ // Toast vars always emitted with smart defaults — toasts stay light in dark mode.
4241
+ // Users can override via theme.colors.toastBg etc.
4242
+ ["--brokr-toast-bg"]: theme.colors.toastBg ?? "#ffffff",
4243
+ ["--brokr-toast-text"]: theme.colors.toastText ?? "#0a0a0a",
4244
+ ["--brokr-toast-text-secondary"]: theme.colors.toastTextSecondary ?? "#52525b",
4245
+ ["--brokr-toast-border"]: theme.colors.toastBorder ?? "#e4e4e7",
4244
4246
  ["--brokr-radius-card"]: `${theme.radii.card}px`,
4245
4247
  ["--brokr-radius-input"]: `${theme.radii.input}px`,
4246
4248
  ["--brokr-radius-button"]: `${theme.radii.button}px`
@@ -4355,6 +4357,37 @@ function resolveNotificationType(registry, type, data) {
4355
4357
 
4356
4358
  // src/react/notifications/Toast.tsx
4357
4359
  var import_react2 = __toESM(require("react"));
4360
+ function ToastItem({
4361
+ notification,
4362
+ exiting,
4363
+ registry,
4364
+ onDismiss
4365
+ }) {
4366
+ const handleDismiss = (0, import_react2.useCallback)(() => onDismiss(notification.id), [notification.id, onDismiss]);
4367
+ const notifData = notification.data ?? {};
4368
+ const notifType = notifData.type ?? "default";
4369
+ const resolved = resolveNotificationType(registry, notifType, notifData);
4370
+ return /* @__PURE__ */ import_react2.default.createElement(
4371
+ "div",
4372
+ {
4373
+ className: `brokr-toast brokr-toast--${notification.variant}${exiting ? " brokr-toast--exit" : ""}`,
4374
+ role: "alert",
4375
+ "aria-live": "polite"
4376
+ },
4377
+ resolved.image ? /* @__PURE__ */ import_react2.default.createElement("img", { src: resolved.image.url, alt: resolved.image.alt, className: "brokr-toast-provider-logo" }) : /* @__PURE__ */ import_react2.default.createElement("span", { className: `brokr-toast-icon brokr-toast-icon--${notification.variant}` }),
4378
+ /* @__PURE__ */ import_react2.default.createElement("div", { className: "brokr-toast-content" }, /* @__PURE__ */ import_react2.default.createElement("span", { className: "brokr-toast-title" }, notification.title), /* @__PURE__ */ import_react2.default.createElement("span", { className: "brokr-toast-message" }, notification.message)),
4379
+ /* @__PURE__ */ import_react2.default.createElement(
4380
+ "button",
4381
+ {
4382
+ type: "button",
4383
+ className: "brokr-toast-dismiss",
4384
+ onClick: handleDismiss,
4385
+ "aria-label": "Dismiss notification"
4386
+ },
4387
+ /* @__PURE__ */ import_react2.default.createElement("svg", { "aria-hidden": "true", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }, /* @__PURE__ */ import_react2.default.createElement("path", { d: "M18 6 6 18M6 6l12 12" }))
4388
+ )
4389
+ );
4390
+ }
4358
4391
  var DEFAULT_DURATION = 4e3;
4359
4392
  var DEFAULT_MAX_VISIBLE = 3;
4360
4393
  var EXIT_ANIMATION_MS = 300;
@@ -4365,6 +4398,26 @@ function ToastLayer({ toasts, config, registry, onDismiss }) {
4365
4398
  const duration = config.toast?.duration ?? DEFAULT_DURATION;
4366
4399
  const maxVisible = config.toast?.maxVisible ?? DEFAULT_MAX_VISIBLE;
4367
4400
  const position = config.toast?.position ?? "top-right";
4401
+ const onDismissRef = (0, import_react2.useRef)(onDismiss);
4402
+ onDismissRef.current = onDismiss;
4403
+ const exitingRef = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
4404
+ const dismissToast = (0, import_react2.useCallback)((id) => {
4405
+ if (exitingRef.current.has(id)) return;
4406
+ exitingRef.current.add(id);
4407
+ setEntries(
4408
+ (prev) => prev.map((e) => e.notification.id === id ? { ...e, exiting: true } : e)
4409
+ );
4410
+ setTimeout(() => {
4411
+ setEntries((prev) => prev.filter((e) => e.notification.id !== id));
4412
+ onDismissRef.current(id);
4413
+ exitingRef.current.delete(id);
4414
+ }, EXIT_ANIMATION_MS);
4415
+ const timer = timersRef.current.get(id);
4416
+ if (timer) {
4417
+ clearTimeout(timer);
4418
+ timersRef.current.delete(id);
4419
+ }
4420
+ }, []);
4368
4421
  (0, import_react2.useEffect)(() => {
4369
4422
  for (const toast of toasts) {
4370
4423
  if (processedRef.current.has(toast.id)) continue;
@@ -4383,21 +4436,7 @@ function ToastLayer({ toasts, config, registry, onDismiss }) {
4383
4436
  timersRef.current.set(toast.id, timer);
4384
4437
  }
4385
4438
  }
4386
- }, [toasts, duration, maxVisible]);
4387
- const dismissToast = (0, import_react2.useCallback)((id) => {
4388
- setEntries(
4389
- (prev) => prev.map((e) => e.notification.id === id ? { ...e, exiting: true } : e)
4390
- );
4391
- setTimeout(() => {
4392
- setEntries((prev) => prev.filter((e) => e.notification.id !== id));
4393
- onDismiss(id);
4394
- }, EXIT_ANIMATION_MS);
4395
- const timer = timersRef.current.get(id);
4396
- if (timer) {
4397
- clearTimeout(timer);
4398
- timersRef.current.delete(id);
4399
- }
4400
- }, [onDismiss]);
4439
+ }, [toasts, duration, maxVisible, dismissToast]);
4401
4440
  (0, import_react2.useEffect)(() => {
4402
4441
  return () => {
4403
4442
  for (const timer of timersRef.current.values()) {
@@ -4417,39 +4456,16 @@ function ToastLayer({ toasts, config, registry, onDismiss }) {
4417
4456
  return map[position] ?? "brokr-toast-layer--bottom-right";
4418
4457
  }, [position]);
4419
4458
  if (entries.length === 0) return null;
4420
- return /* @__PURE__ */ import_react2.default.createElement("div", { className: `brokr-toast-layer ${positionClass}` }, entries.map(({ notification, exiting }) => {
4421
- const notifData = notification.data ?? {};
4422
- const notifType = notifData.type ?? "default";
4423
- const resolved = resolveNotificationType(registry, notifType, notifData);
4424
- return /* @__PURE__ */ import_react2.default.createElement(
4425
- "div",
4426
- {
4427
- key: notification.id,
4428
- className: `brokr-toast brokr-toast--${notification.variant}${exiting ? " brokr-toast--exit" : ""}`,
4429
- role: "alert",
4430
- "aria-live": "polite"
4431
- },
4432
- resolved.image ? /* @__PURE__ */ import_react2.default.createElement(
4433
- "img",
4434
- {
4435
- src: resolved.image.url,
4436
- alt: resolved.image.alt,
4437
- className: "brokr-toast-provider-logo"
4438
- }
4439
- ) : /* @__PURE__ */ import_react2.default.createElement("span", { className: `brokr-toast-icon brokr-toast-icon--${notification.variant}` }),
4440
- /* @__PURE__ */ import_react2.default.createElement("div", { className: "brokr-toast-content" }, /* @__PURE__ */ import_react2.default.createElement("span", { className: "brokr-toast-title" }, notification.title), /* @__PURE__ */ import_react2.default.createElement("span", { className: "brokr-toast-message" }, notification.message)),
4441
- /* @__PURE__ */ import_react2.default.createElement(
4442
- "button",
4443
- {
4444
- type: "button",
4445
- className: "brokr-toast-dismiss",
4446
- onClick: () => dismissToast(notification.id),
4447
- "aria-label": "Dismiss notification"
4448
- },
4449
- /* @__PURE__ */ import_react2.default.createElement("svg", { "aria-hidden": "true", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }, /* @__PURE__ */ import_react2.default.createElement("path", { d: "M18 6 6 18M6 6l12 12" }))
4450
- )
4451
- );
4452
- }));
4459
+ return /* @__PURE__ */ import_react2.default.createElement("div", { className: `brokr-toast-layer ${positionClass}` }, entries.map(({ notification, exiting }) => /* @__PURE__ */ import_react2.default.createElement(
4460
+ ToastItem,
4461
+ {
4462
+ key: notification.id,
4463
+ notification,
4464
+ exiting,
4465
+ registry,
4466
+ onDismiss: dismissToast
4467
+ }
4468
+ )));
4453
4469
  }
4454
4470
 
4455
4471
  // src/react/notifications/provider.tsx
@@ -5565,6 +5581,26 @@ function filterDefined(defaults, overrides) {
5565
5581
  }
5566
5582
 
5567
5583
  // src/react/account/AccountPanel.tsx
5584
+ function AccountTabButton({
5585
+ tab,
5586
+ active,
5587
+ icon,
5588
+ label,
5589
+ onSelect
5590
+ }) {
5591
+ const handleClick = (0, import_react11.useCallback)(() => onSelect(tab), [tab, onSelect]);
5592
+ return /* @__PURE__ */ import_react11.default.createElement(
5593
+ "button",
5594
+ {
5595
+ className: "brokr-account-tab",
5596
+ "data-active": active,
5597
+ onClick: handleClick,
5598
+ type: "button"
5599
+ },
5600
+ /* @__PURE__ */ import_react11.default.createElement("span", { className: "brokr-account-tab-icon" }, icon),
5601
+ /* @__PURE__ */ import_react11.default.createElement("span", null, label)
5602
+ );
5603
+ }
5568
5604
  var TAB_META = {
5569
5605
  general: {
5570
5606
  label: "General"
@@ -5696,16 +5732,15 @@ function AccountPanel(inlineProps) {
5696
5732
  }
5697
5733
  }, []);
5698
5734
  return /* @__PURE__ */ import_react11.default.createElement("section", { className: "brokr-account-panel", "data-density": density }, /* @__PURE__ */ import_react11.default.createElement("aside", { className: "brokr-account-sidebar" }, groupedTabs.map((group) => /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-sidebar-group", key: group.label }, /* @__PURE__ */ import_react11.default.createElement("span", { className: "brokr-account-sidebar-kicker" }, group.label), /* @__PURE__ */ import_react11.default.createElement("nav", { className: "brokr-account-tab-list", "aria-label": `${group.label} settings` }, group.tabs.map((tab) => /* @__PURE__ */ import_react11.default.createElement(
5699
- "button",
5735
+ AccountTabButton,
5700
5736
  {
5701
- className: "brokr-account-tab",
5702
- "data-active": activeTab === tab,
5703
5737
  key: tab,
5704
- onClick: () => setActiveTab(tab),
5705
- type: "button"
5706
- },
5707
- /* @__PURE__ */ import_react11.default.createElement("span", { className: "brokr-account-tab-icon" }, getTabIcon(tab)),
5708
- /* @__PURE__ */ import_react11.default.createElement("span", null, TAB_META[tab].label)
5738
+ tab,
5739
+ active: activeTab === tab,
5740
+ icon: getTabIcon(tab),
5741
+ label: TAB_META[tab].label,
5742
+ onSelect: setActiveTab
5743
+ }
5709
5744
  )))))), /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-surface" }, /* @__PURE__ */ import_react11.default.createElement("header", { className: "brokr-account-surface-header" }, /* @__PURE__ */ import_react11.default.createElement("h2", { className: "brokr-title" }, activeTabMeta.label)), activeTab === "general" ? /* @__PURE__ */ import_react11.default.createElement("form", { className: "brokr-account-form", onSubmit: handleSaveProfile }, /* @__PURE__ */ import_react11.default.createElement("section", { className: "brokr-account-card" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-photo-row" }, /* @__PURE__ */ import_react11.default.createElement(ProfilePhotoButton, { size: 88 }), /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-photo-copy" }, /* @__PURE__ */ import_react11.default.createElement("strong", null, "Profile photo"), /* @__PURE__ */ import_react11.default.createElement("span", { className: "brokr-copy" }, "PNG, JPEG, and GIF under 10MB"), /* @__PURE__ */ import_react11.default.createElement("span", { className: "brokr-account-photo-hint" }, /* @__PURE__ */ import_react11.default.createElement(UploadIcon, { size: 14 }), "Upload new picture")))), /* @__PURE__ */ import_react11.default.createElement("section", { className: "brokr-account-card brokr-account-field-list" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-field-row" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-field-head" }, /* @__PURE__ */ import_react11.default.createElement("label", { className: "brokr-label", htmlFor: "brokr-account-name" }, "Name")), /* @__PURE__ */ import_react11.default.createElement("div", { className: "brokr-account-field-body" }, /* @__PURE__ */ import_react11.default.createElement(
5710
5745
  "input",
5711
5746
  {
@@ -5807,6 +5842,9 @@ function UserButton({
5807
5842
  setOpen(false);
5808
5843
  await signOut();
5809
5844
  }, [signOut]);
5845
+ const stopPropagation = (0, import_react13.useCallback)((event) => {
5846
+ event.stopPropagation();
5847
+ }, []);
5810
5848
  (0, import_react13.useEffect)(() => {
5811
5849
  if (!open) return void 0;
5812
5850
  const handlePointerDown = (event) => {
@@ -5840,13 +5878,13 @@ function UserButton({
5840
5878
  "data-align": align,
5841
5879
  role: "dialog"
5842
5880
  },
5843
- /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu" }, /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-header" }, /* @__PURE__ */ import_react13.default.createElement(Avatar, { email: summary.email, name: summary.name, src: user.image, size: 44 }), /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-copy" }, /* @__PURE__ */ import_react13.default.createElement("strong", null, summary.name), /* @__PURE__ */ import_react13.default.createElement("span", null, summary.email))), /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-actions" }, /* @__PURE__ */ import_react13.default.createElement("button", { className: "brokr-account-menu-action", onClick: openSettings, type: "button" }, /* @__PURE__ */ import_react13.default.createElement("span", { className: "brokr-account-menu-action-icon" }, /* @__PURE__ */ import_react13.default.createElement(SettingsIcon, { size: 15 })), /* @__PURE__ */ import_react13.default.createElement("span", null, "Settings")), /* @__PURE__ */ import_react13.default.createElement("button", { className: "brokr-account-menu-action", onClick: () => void handleSignOut(), type: "button" }, /* @__PURE__ */ import_react13.default.createElement("span", { className: "brokr-account-menu-action-icon" }, /* @__PURE__ */ import_react13.default.createElement(LogoutIcon, { size: 15 })), /* @__PURE__ */ import_react13.default.createElement("span", null, "Sign out"))))
5881
+ /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu" }, /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-header" }, /* @__PURE__ */ import_react13.default.createElement(Avatar, { email: summary.email, name: summary.name, src: user.image, size: 44 }), /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-copy" }, /* @__PURE__ */ import_react13.default.createElement("strong", null, summary.name), /* @__PURE__ */ import_react13.default.createElement("span", null, summary.email))), /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-account-menu-actions" }, /* @__PURE__ */ import_react13.default.createElement("button", { className: "brokr-account-menu-action", onClick: openSettings, type: "button" }, /* @__PURE__ */ import_react13.default.createElement("span", { className: "brokr-account-menu-action-icon" }, /* @__PURE__ */ import_react13.default.createElement(SettingsIcon, { size: 15 })), /* @__PURE__ */ import_react13.default.createElement("span", null, "Settings")), /* @__PURE__ */ import_react13.default.createElement("button", { className: "brokr-account-menu-action", onClick: handleSignOut, type: "button" }, /* @__PURE__ */ import_react13.default.createElement("span", { className: "brokr-account-menu-action-icon" }, /* @__PURE__ */ import_react13.default.createElement(LogoutIcon, { size: 15 })), /* @__PURE__ */ import_react13.default.createElement("span", null, "Sign out"))))
5844
5882
  ) : null, settingsOpen ? /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-modal-backdrop", role: "presentation", onClick: closeSettings }, /* @__PURE__ */ import_react13.default.createElement(
5845
5883
  "div",
5846
5884
  {
5847
5885
  "aria-modal": "true",
5848
5886
  className: "brokr-panel brokr-modal-dialog brokr-account-settings-dialog",
5849
- onClick: (event) => event.stopPropagation(),
5887
+ onClick: stopPropagation,
5850
5888
  role: "dialog"
5851
5889
  },
5852
5890
  /* @__PURE__ */ import_react13.default.createElement("div", { className: "brokr-modal-toolbar" }, /* @__PURE__ */ import_react13.default.createElement("button", { className: "brokr-button-ghost", onClick: closeSettings, type: "button" }, /* @__PURE__ */ import_react13.default.createElement(CloseIcon, { size: 16 }))),
@@ -6042,6 +6080,28 @@ function AuthWall({ children }) {
6042
6080
 
6043
6081
  // src/react/payments/Plans.tsx
6044
6082
  var import_react22 = __toESM(require("react"));
6083
+ function PlanCard({
6084
+ plan,
6085
+ highlight,
6086
+ isPending,
6087
+ onSelect
6088
+ }) {
6089
+ const isHighlighted = highlight === plan.slug;
6090
+ const features = Object.entries(plan.features);
6091
+ const handleClick = (0, import_react22.useCallback)(() => {
6092
+ void onSelect(plan.slug);
6093
+ }, [plan.slug, onSelect]);
6094
+ return /* @__PURE__ */ import_react22.default.createElement("article", { className: "brokr-card brokr-plan-card", "data-highlight": isHighlighted, key: plan.slug }, /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-3)" } }, /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react22.default.createElement("strong", null, plan.name), plan.isCurrent ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-badge" }, "Current") : null, isHighlighted && !plan.isCurrent ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-badge" }, "Recommended") : null), /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-plan-price" }, /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-plan-value" }, plan.price === 0 ? "$0" : `$${(plan.price / 100).toFixed(0)}`), /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-copy" }, "/", plan.interval)), plan.trialDays ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-copy" }, plan.trialDays, " day trial included.") : null), /* @__PURE__ */ import_react22.default.createElement(
6095
+ "button",
6096
+ {
6097
+ className: plan.isCurrent ? "brokr-button-secondary" : "brokr-button",
6098
+ disabled: plan.isCurrent || isPending,
6099
+ onClick: handleClick,
6100
+ type: "button"
6101
+ },
6102
+ plan.isCurrent ? "Current plan" : isPending ? "Redirecting" : "Choose plan"
6103
+ ), /* @__PURE__ */ import_react22.default.createElement("ul", { className: "brokr-feature-list" }, features.map(([key, value]) => /* @__PURE__ */ import_react22.default.createElement("li", { className: "brokr-feature-item", key }, /* @__PURE__ */ import_react22.default.createElement(CheckIcon, { size: 14 }), /* @__PURE__ */ import_react22.default.createElement("span", null, featureLabel(key), " \xB7 ", featureValueLabel(value))))));
6104
+ }
6045
6105
  function Plans({
6046
6106
  columns,
6047
6107
  highlight,
@@ -6072,34 +6132,16 @@ function Plans({
6072
6132
  setPendingPlan(null);
6073
6133
  }
6074
6134
  }, [checkout, onSelect]);
6075
- return /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-section" }, paymentsMode === "sandbox" ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-inline-message" }, "Sandbox mode \u2014 test cards only.") : null, error ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-inline-message", "data-tone": "error" }, error) : null, /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-grid-auto", style: layoutStyle }, plans.map((plan) => {
6076
- const features = Object.entries(plan.features);
6077
- const isHighlighted = highlight === plan.slug;
6078
- const isPending = pendingPlan === plan.slug;
6079
- const handleClick = () => {
6080
- void handleSelect(plan.slug);
6081
- };
6082
- return /* @__PURE__ */ import_react22.default.createElement(
6083
- "article",
6084
- {
6085
- className: "brokr-card brokr-plan-card",
6086
- "data-highlight": isHighlighted,
6087
- key: plan.slug
6088
- },
6089
- /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-section", style: { gap: "0.75rem" } }, /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react22.default.createElement("strong", null, plan.name), plan.isCurrent ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-badge" }, "Current") : null, isHighlighted && !plan.isCurrent ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-badge" }, "Recommended") : null), /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-plan-price" }, /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-plan-value" }, plan.price === 0 ? "$0" : `$${(plan.price / 100).toFixed(0)}`), /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-copy" }, "/", plan.interval)), plan.trialDays ? /* @__PURE__ */ import_react22.default.createElement("span", { className: "brokr-copy" }, plan.trialDays, " day trial included.") : null),
6090
- /* @__PURE__ */ import_react22.default.createElement(
6091
- "button",
6092
- {
6093
- className: plan.isCurrent ? "brokr-button-secondary" : "brokr-button",
6094
- disabled: plan.isCurrent || isPending,
6095
- onClick: handleClick,
6096
- type: "button"
6097
- },
6098
- plan.isCurrent ? "Current plan" : isPending ? "Redirecting" : "Choose plan"
6099
- ),
6100
- /* @__PURE__ */ import_react22.default.createElement("ul", { className: "brokr-feature-list" }, features.map(([key, value]) => /* @__PURE__ */ import_react22.default.createElement("li", { className: "brokr-feature-item", key }, /* @__PURE__ */ import_react22.default.createElement(CheckIcon, { size: 14 }), /* @__PURE__ */ import_react22.default.createElement("span", null, featureLabel(key), " \xB7 ", featureValueLabel(value)))))
6101
- );
6102
- })));
6135
+ return /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-section" }, paymentsMode === "sandbox" ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-inline-message" }, "Sandbox mode \u2014 test cards only.") : null, error ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-inline-message", "data-tone": "error" }, error) : null, /* @__PURE__ */ import_react22.default.createElement("div", { className: "brokr-grid-auto", style: layoutStyle }, plans.map((plan) => /* @__PURE__ */ import_react22.default.createElement(
6136
+ PlanCard,
6137
+ {
6138
+ key: plan.slug,
6139
+ plan,
6140
+ highlight,
6141
+ isPending: pendingPlan === plan.slug,
6142
+ onSelect: handleSelect
6143
+ }
6144
+ ))));
6103
6145
  }
6104
6146
 
6105
6147
  // src/react/payments/FeatureMeter.tsx
@@ -6237,7 +6279,7 @@ function AutoReloadToggle({ onChange }) {
6237
6279
  setIsPending(false);
6238
6280
  }
6239
6281
  }, [enabled, onChange]);
6240
- return /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-card brokr-gate-card" }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-section", style: { gap: "0.35rem" } }, /* @__PURE__ */ import_react27.default.createElement("strong", null, "Auto reload"), /* @__PURE__ */ import_react27.default.createElement("span", { className: "brokr-copy" }, helperText)), /* @__PURE__ */ import_react27.default.createElement(
6282
+ return /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-card brokr-gate-card" }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-1)" } }, /* @__PURE__ */ import_react27.default.createElement("strong", null, "Auto reload"), /* @__PURE__ */ import_react27.default.createElement("span", { className: "brokr-copy" }, helperText)), /* @__PURE__ */ import_react27.default.createElement(
6241
6283
  "button",
6242
6284
  {
6243
6285
  className: "brokr-button-secondary",
@@ -6927,6 +6969,37 @@ function useChat(config) {
6927
6969
 
6928
6970
  // src/react/chat/ModelSelector.tsx
6929
6971
  var import_react32 = __toESM(require("react"));
6972
+ function ModelOption({
6973
+ provider,
6974
+ isActive,
6975
+ isLocked,
6976
+ onSelect,
6977
+ onCheckout
6978
+ }) {
6979
+ const handleClick = (0, import_react32.useCallback)(() => {
6980
+ if (isLocked) {
6981
+ void onCheckout({ plan: "pro" });
6982
+ } else {
6983
+ onSelect(provider.model);
6984
+ }
6985
+ }, [isLocked, onCheckout, onSelect, provider.model]);
6986
+ return /* @__PURE__ */ import_react32.default.createElement(
6987
+ "button",
6988
+ {
6989
+ "aria-selected": isActive,
6990
+ className: "brokr-model-option",
6991
+ "data-active": isActive,
6992
+ "data-locked": isLocked,
6993
+ disabled: isLocked,
6994
+ onClick: handleClick,
6995
+ title: isLocked ? "Add credits to unlock" : void 0,
6996
+ type: "button"
6997
+ },
6998
+ /* @__PURE__ */ import_react32.default.createElement("img", { alt: "", className: "brokr-model-logo", src: provider.logo }),
6999
+ /* @__PURE__ */ import_react32.default.createElement("span", { className: "brokr-model-option-label" }, provider.label),
7000
+ isLocked ? /* @__PURE__ */ import_react32.default.createElement("span", { className: "brokr-model-lock", "aria-hidden": "true" }, /* @__PURE__ */ import_react32.default.createElement(LockIcon, { size: 13 })) : null
7001
+ );
7002
+ }
6930
7003
  function ModelSelector({
6931
7004
  activeModel,
6932
7005
  setSelectedModel,
@@ -6939,6 +7012,10 @@ function ModelSelector({
6939
7012
  () => providers.find((p) => p.model === activeModel) ?? providers[0],
6940
7013
  [activeModel]
6941
7014
  );
7015
+ const handleModelSelect = (0, import_react32.useCallback)((model) => {
7016
+ setSelectedModel(model);
7017
+ setSelectorOpen(false);
7018
+ }, [setSelectedModel]);
6942
7019
  (0, import_react32.useEffect)(() => {
6943
7020
  if (!selectorOpen) return;
6944
7021
  const onMouseDown = (e) => {
@@ -6969,37 +7046,34 @@ function ModelSelector({
6969
7046
  activeProvider ? /* @__PURE__ */ import_react32.default.createElement("img", { alt: "", className: "brokr-model-logo", src: activeProvider.logo }) : /* @__PURE__ */ import_react32.default.createElement("span", { className: "brokr-model-dot", style: { background: "currentColor" } }),
6970
7047
  activeProvider?.label ?? "Model",
6971
7048
  /* @__PURE__ */ import_react32.default.createElement(ChevronDownIcon, { size: 13 })
6972
- ), selectorOpen ? /* @__PURE__ */ import_react32.default.createElement("div", { className: "brokr-model-dropdown", role: "listbox" }, providers.map((p) => {
6973
- const locked = !availableProviders.some((a) => a.id === p.id);
6974
- return /* @__PURE__ */ import_react32.default.createElement(
6975
- "button",
6976
- {
6977
- "aria-selected": p.model === activeModel,
6978
- className: "brokr-model-option",
6979
- "data-active": p.model === activeModel,
6980
- "data-locked": locked,
6981
- disabled: locked,
6982
- key: p.id,
6983
- onClick: () => {
6984
- if (locked) {
6985
- void checkout({ plan: "pro" });
6986
- } else {
6987
- setSelectedModel(p.model);
6988
- setSelectorOpen(false);
6989
- }
6990
- },
6991
- title: locked ? "Add credits to unlock" : void 0,
6992
- type: "button"
6993
- },
6994
- /* @__PURE__ */ import_react32.default.createElement("img", { alt: "", className: "brokr-model-logo", src: p.logo }),
6995
- /* @__PURE__ */ import_react32.default.createElement("span", { className: "brokr-model-option-label" }, p.label),
6996
- locked ? /* @__PURE__ */ import_react32.default.createElement("span", { className: "brokr-model-lock", "aria-hidden": "true" }, /* @__PURE__ */ import_react32.default.createElement(LockIcon, { size: 13 })) : null
6997
- );
6998
- })) : null);
7049
+ ), selectorOpen ? /* @__PURE__ */ import_react32.default.createElement("div", { className: "brokr-model-dropdown", role: "listbox" }, providers.map((p) => /* @__PURE__ */ import_react32.default.createElement(
7050
+ ModelOption,
7051
+ {
7052
+ key: p.id,
7053
+ provider: p,
7054
+ isActive: p.model === activeModel,
7055
+ isLocked: !availableProviders.some((a) => a.id === p.id),
7056
+ onSelect: handleModelSelect,
7057
+ onCheckout: checkout
7058
+ }
7059
+ ))) : null);
6999
7060
  }
7000
7061
 
7001
7062
  // src/react/chat/ThreadSidebar.tsx
7002
7063
  var import_react33 = __toESM(require("react"));
7064
+ function ThreadItemButton({ id, title, isActive, onSelect }) {
7065
+ const handleClick = (0, import_react33.useCallback)(() => onSelect(id), [id, onSelect]);
7066
+ return /* @__PURE__ */ import_react33.default.createElement(
7067
+ "button",
7068
+ {
7069
+ className: "brokr-ai-chat-conversation",
7070
+ "data-active": isActive,
7071
+ onClick: handleClick,
7072
+ type: "button"
7073
+ },
7074
+ title
7075
+ );
7076
+ }
7003
7077
  function ThreadSidebar() {
7004
7078
  const {
7005
7079
  startNewChat,
@@ -7050,15 +7124,14 @@ function ThreadSidebar() {
7050
7124
  value: renameValue
7051
7125
  }
7052
7126
  ) : /* @__PURE__ */ import_react33.default.createElement(
7053
- "button",
7127
+ ThreadItemButton,
7054
7128
  {
7055
- className: "brokr-ai-chat-conversation",
7056
- "data-active": item.id === activeId,
7057
7129
  key: item.id,
7058
- onClick: () => selectThreadAndCloseSidebar(item.id),
7059
- type: "button"
7060
- },
7061
- item.title
7130
+ id: item.id,
7131
+ title: item.title,
7132
+ isActive: item.id === activeId,
7133
+ onSelect: selectThreadAndCloseSidebar
7134
+ }
7062
7135
  )));
7063
7136
  }, [
7064
7137
  threadsLoading,
@@ -7258,6 +7331,12 @@ function MessageBubble({ message, isTyping, user }) {
7258
7331
  }
7259
7332
 
7260
7333
  // src/react/chat/MessagePane.tsx
7334
+ function StarterPromptButton({ prompt, onSend }) {
7335
+ const handleClick = (0, import_react36.useCallback)(() => {
7336
+ void onSend(prompt);
7337
+ }, [prompt, onSend]);
7338
+ return /* @__PURE__ */ import_react36.default.createElement("button", { className: "brokr-ai-chat-starter", onClick: handleClick, type: "button" }, prompt);
7339
+ }
7261
7340
  function MessagePane({ starterPrompts, emptyTitle, emptyCopy, subtitle }) {
7262
7341
  const {
7263
7342
  displayMessages,
@@ -7288,20 +7367,17 @@ function MessagePane({ starterPrompts, emptyTitle, emptyCopy, subtitle }) {
7288
7367
  );
7289
7368
  });
7290
7369
  }, [visibleMessages, isSubmitting, user]);
7291
- return /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-thread", "data-empty": isEmpty, ref: scrollContainerRef }, isEmpty ? /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-empty" }, /* @__PURE__ */ import_react36.default.createElement(SparkIcon, { size: 28 }), /* @__PURE__ */ import_react36.default.createElement("h2", { className: "brokr-title" }, emptyTitle), subtitle ?? emptyCopy ? /* @__PURE__ */ import_react36.default.createElement("p", { className: "brokr-copy" }, subtitle ?? emptyCopy) : null, starterPrompts.length > 0 ? /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-starters" }, starterPrompts.map((sp) => /* @__PURE__ */ import_react36.default.createElement(
7292
- "button",
7293
- {
7294
- className: "brokr-ai-chat-starter",
7295
- key: sp,
7296
- onClick: () => void sendMessage(sp),
7297
- type: "button"
7298
- },
7299
- sp
7300
- ))) : null) : /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-thread-inner" }, (isPersist ? hasMoreMessages : memHasMore) ? /* @__PURE__ */ import_react36.default.createElement("div", { ref: sentinelRef, className: "brokr-ai-chat-sentinel" }, loadingOlder ? /* @__PURE__ */ import_react36.default.createElement("div", { style: { display: "flex", justifyContent: "center", padding: "0.5rem" } }, /* @__PURE__ */ import_react36.default.createElement(Skeleton, { width: 120, height: 12, radius: 6 })) : null) : null, messageElements, /* @__PURE__ */ import_react36.default.createElement("div", { ref: bottomRef })));
7370
+ return /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-thread", "data-empty": isEmpty, ref: scrollContainerRef }, isEmpty ? /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-empty" }, /* @__PURE__ */ import_react36.default.createElement(SparkIcon, { size: 28 }), /* @__PURE__ */ import_react36.default.createElement("h2", { className: "brokr-title" }, emptyTitle), subtitle ?? emptyCopy ? /* @__PURE__ */ import_react36.default.createElement("p", { className: "brokr-copy" }, subtitle ?? emptyCopy) : null, starterPrompts.length > 0 ? /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-starters" }, starterPrompts.map((sp) => /* @__PURE__ */ import_react36.default.createElement(StarterPromptButton, { key: sp, prompt: sp, onSend: sendMessage }))) : null) : /* @__PURE__ */ import_react36.default.createElement("div", { className: "brokr-ai-chat-thread-inner" }, (isPersist ? hasMoreMessages : memHasMore) ? /* @__PURE__ */ import_react36.default.createElement("div", { ref: sentinelRef, className: "brokr-ai-chat-sentinel" }, loadingOlder ? /* @__PURE__ */ import_react36.default.createElement("div", { style: { display: "flex", justifyContent: "center", padding: "0.5rem" } }, /* @__PURE__ */ import_react36.default.createElement(Skeleton, { width: 120, height: 12, radius: 6 })) : null) : null, messageElements, /* @__PURE__ */ import_react36.default.createElement("div", { ref: bottomRef })));
7301
7371
  }
7302
7372
 
7303
7373
  // src/react/chat/ChatInput.tsx
7304
7374
  var import_react37 = __toESM(require("react"));
7375
+ function CommandButton({ cmd, chatContext }) {
7376
+ const handleClick = (0, import_react37.useCallback)(() => {
7377
+ void cmd.run(chatContext);
7378
+ }, [cmd, chatContext]);
7379
+ return /* @__PURE__ */ import_react37.default.createElement("button", { className: "brokr-ai-chat-sidebar-button", key: cmd.id, onClick: handleClick, type: "button" }, cmd.text);
7380
+ }
7305
7381
  function ChatInput() {
7306
7382
  const {
7307
7383
  input,
@@ -7332,16 +7408,7 @@ function ChatInput() {
7332
7408
  const handleChange = (0, import_react37.useCallback)((e) => {
7333
7409
  setInput(e.target.value);
7334
7410
  }, [setInput]);
7335
- return /* @__PURE__ */ import_react37.default.createElement("form", { className: "brokr-ai-chat-input-area", onSubmit: handleSubmit }, /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-input-container" }, composerCommands.length > 0 ? /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-composer-actions" }, composerCommands.map((cmd) => /* @__PURE__ */ import_react37.default.createElement(
7336
- "button",
7337
- {
7338
- className: "brokr-ai-chat-sidebar-button",
7339
- key: cmd.id,
7340
- onClick: () => void cmd.run(chatContext),
7341
- type: "button"
7342
- },
7343
- cmd.text
7344
- ))) : null, /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-input-row" }, /* @__PURE__ */ import_react37.default.createElement(
7411
+ return /* @__PURE__ */ import_react37.default.createElement("form", { className: "brokr-ai-chat-input-area", onSubmit: handleSubmit }, /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-input-container" }, composerCommands.length > 0 ? /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-composer-actions" }, composerCommands.map((cmd) => /* @__PURE__ */ import_react37.default.createElement(CommandButton, { key: cmd.id, cmd, chatContext }))) : null, /* @__PURE__ */ import_react37.default.createElement("div", { className: "brokr-ai-chat-input-row" }, /* @__PURE__ */ import_react37.default.createElement(
7345
7412
  "textarea",
7346
7413
  {
7347
7414
  className: "brokr-ai-chat-textarea",
@@ -7480,6 +7547,14 @@ function AIChat(inlineProps) {
7480
7547
  chat.selectThread(id);
7481
7548
  setSidebarOpen(false);
7482
7549
  }, [chat.selectThread]);
7550
+ const handleCopy = (0, import_react38.useCallback)((content) => {
7551
+ navigator.clipboard.writeText(content).catch(() => {
7552
+ });
7553
+ }, []);
7554
+ const handleStartRename = (0, import_react38.useCallback)((threadId) => {
7555
+ setThreadMenuOpenId(null);
7556
+ chat.startRename(threadId);
7557
+ }, [chat.startRename]);
7483
7558
  (0, import_react38.useEffect)(() => {
7484
7559
  if (!threadMenuOpenId) return;
7485
7560
  const onMouseDown = (e) => {
@@ -7537,17 +7612,11 @@ function AIChat(inlineProps) {
7537
7612
  startNewChat: chat.startNewChat,
7538
7613
  selectThread: chat.selectThread,
7539
7614
  deleteThread: chat.deleteThread,
7540
- handleCopy: (content) => {
7541
- navigator.clipboard.writeText(content).catch(() => {
7542
- });
7543
- },
7615
+ handleCopy,
7544
7616
  renamingId: chat.renamingId,
7545
7617
  renameValue: chat.renameValue,
7546
7618
  setRenameValue: chat.setRenameValue,
7547
- startRename: (threadId) => {
7548
- setThreadMenuOpenId(null);
7549
- chat.startRename(threadId);
7550
- },
7619
+ startRename: handleStartRename,
7551
7620
  submitRename: chat.submitRename,
7552
7621
  displaySidebarItems: chat.displaySidebarItems,
7553
7622
  threadsLoading: chat.threadsLoading,
@@ -7633,6 +7702,19 @@ function AIChat(inlineProps) {
7633
7702
  ), /* @__PURE__ */ import_react38.default.createElement(ChatInput, null))
7634
7703
  ));
7635
7704
  }
7705
+ function CommandButton2({ cmd, chatContext }) {
7706
+ const handleClick = (0, import_react38.useCallback)(() => {
7707
+ void cmd.run(chatContext);
7708
+ }, [cmd, chatContext]);
7709
+ return /* @__PURE__ */ import_react38.default.createElement("button", { className: "brokr-ai-chat-sidebar-button", onClick: handleClick, type: "button" }, cmd.text);
7710
+ }
7711
+ function MenuCommandItem({ cmd, chatContext, onClose }) {
7712
+ const handleClick = (0, import_react38.useCallback)(() => {
7713
+ onClose();
7714
+ void cmd.run(chatContext);
7715
+ }, [cmd, chatContext, onClose]);
7716
+ return /* @__PURE__ */ import_react38.default.createElement("button", { className: "brokr-ai-chat-thread-dropdown-item", onClick: handleClick, type: "button" }, cmd.text);
7717
+ }
7636
7718
  function ChatHeader({
7637
7719
  activeId,
7638
7720
  sidebarVisible,
@@ -7656,6 +7738,16 @@ function ChatHeader({
7656
7738
  const handleToggleMenu = (0, import_react38.useCallback)(() => {
7657
7739
  setThreadMenuOpenId(threadMenuOpenId ? null : activeId);
7658
7740
  }, [setThreadMenuOpenId, threadMenuOpenId, activeId]);
7741
+ const closeMenu = (0, import_react38.useCallback)(() => setThreadMenuOpenId(null), [setThreadMenuOpenId]);
7742
+ const handleRename = (0, import_react38.useCallback)(() => {
7743
+ if (activeId) startRename(activeId);
7744
+ }, [activeId, startRename]);
7745
+ const handleDelete = (0, import_react38.useCallback)(() => {
7746
+ if (activeId) {
7747
+ setThreadMenuOpenId(null);
7748
+ void deleteThread(activeId);
7749
+ }
7750
+ }, [activeId, deleteThread, setThreadMenuOpenId]);
7659
7751
  return /* @__PURE__ */ import_react38.default.createElement("header", { className: "brokr-ai-chat-topbar" }, /* @__PURE__ */ import_react38.default.createElement("div", { className: "brokr-ai-chat-topbar-left" }, sidebarVisible ? /* @__PURE__ */ import_react38.default.createElement(
7660
7752
  "button",
7661
7753
  {
@@ -7665,16 +7757,7 @@ function ChatHeader({
7665
7757
  type: "button"
7666
7758
  },
7667
7759
  /* @__PURE__ */ import_react38.default.createElement(MenuIcon, { size: 18 })
7668
- ) : null), /* @__PURE__ */ import_react38.default.createElement("div", { className: "brokr-ai-chat-topbar-actions" }, headerCommands.map((cmd) => /* @__PURE__ */ import_react38.default.createElement(
7669
- "button",
7670
- {
7671
- className: "brokr-ai-chat-sidebar-button",
7672
- key: cmd.id,
7673
- onClick: () => void cmd.run(chatContext),
7674
- type: "button"
7675
- },
7676
- cmd.text
7677
- )), modelSelectorVisible ? /* @__PURE__ */ import_react38.default.createElement(
7760
+ ) : null), /* @__PURE__ */ import_react38.default.createElement("div", { className: "brokr-ai-chat-topbar-actions" }, headerCommands.map((cmd) => /* @__PURE__ */ import_react38.default.createElement(CommandButton2, { key: cmd.id, cmd, chatContext })), modelSelectorVisible ? /* @__PURE__ */ import_react38.default.createElement(
7678
7761
  ModelSelector,
7679
7762
  {
7680
7763
  activeModel,
@@ -7695,32 +7778,25 @@ function ChatHeader({
7695
7778
  "button",
7696
7779
  {
7697
7780
  className: "brokr-ai-chat-thread-dropdown-item",
7698
- onClick: () => startRename(activeId),
7781
+ onClick: handleRename,
7699
7782
  type: "button"
7700
7783
  },
7701
7784
  /* @__PURE__ */ import_react38.default.createElement(PencilIcon, { size: 13 }),
7702
7785
  "Rename"
7703
7786
  ), threadMenuCommands.map((cmd) => /* @__PURE__ */ import_react38.default.createElement(
7704
- "button",
7787
+ MenuCommandItem,
7705
7788
  {
7706
- className: "brokr-ai-chat-thread-dropdown-item",
7707
7789
  key: cmd.id,
7708
- onClick: () => {
7709
- setThreadMenuOpenId(null);
7710
- void cmd.run(chatContext);
7711
- },
7712
- type: "button"
7713
- },
7714
- cmd.text
7790
+ cmd,
7791
+ chatContext,
7792
+ onClose: closeMenu
7793
+ }
7715
7794
  )), /* @__PURE__ */ import_react38.default.createElement(
7716
7795
  "button",
7717
7796
  {
7718
7797
  className: "brokr-ai-chat-thread-dropdown-item",
7719
7798
  "data-tone": "danger",
7720
- onClick: () => {
7721
- setThreadMenuOpenId(null);
7722
- void deleteThread(activeId);
7723
- },
7799
+ onClick: handleDelete,
7724
7800
  type: "button"
7725
7801
  },
7726
7802
  /* @__PURE__ */ import_react38.default.createElement(TrashIcon, { size: 13 }),
@@ -7730,6 +7806,10 @@ function ChatHeader({
7730
7806
 
7731
7807
  // src/react/composites/FabAI.tsx
7732
7808
  var import_react39 = __toESM(require("react"));
7809
+ function StarterButton({ prompt, onSelect }) {
7810
+ const handleClick = (0, import_react39.useCallback)(() => onSelect(prompt), [prompt, onSelect]);
7811
+ return /* @__PURE__ */ import_react39.default.createElement("button", { className: "brokr-chat-starter", onClick: handleClick, type: "button" }, prompt);
7812
+ }
7733
7813
  function FabAI({
7734
7814
  model,
7735
7815
  onSendMessage,
@@ -7821,30 +7901,16 @@ function FabAI({
7821
7901
  },
7822
7902
  /* @__PURE__ */ import_react39.default.createElement(MessageIcon, { size: 16 }),
7823
7903
  "Ask AI"
7824
- )), isOpen ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-panel brokr-chat-panel", role: "dialog" }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-section", style: { gap: "0.25rem" } }, /* @__PURE__ */ import_react39.default.createElement("strong", null, "AI Chat"), user?.name ? /* @__PURE__ */ import_react39.default.createElement("span", { className: "brokr-copy" }, user.name) : null), /* @__PURE__ */ import_react39.default.createElement("button", { className: "brokr-button-ghost", onClick: handleClose, type: "button" }, /* @__PURE__ */ import_react39.default.createElement(CloseIcon, { size: 16 }))), /* @__PURE__ */ import_react39.default.createElement(
7904
+ )), isOpen ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-panel brokr-chat-panel", role: "dialog" }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-1)" } }, /* @__PURE__ */ import_react39.default.createElement("strong", null, "AI Chat"), user?.name ? /* @__PURE__ */ import_react39.default.createElement("span", { className: "brokr-copy" }, user.name) : null), /* @__PURE__ */ import_react39.default.createElement("button", { className: "brokr-button-ghost", onClick: handleClose, type: "button" }, /* @__PURE__ */ import_react39.default.createElement(CloseIcon, { size: 16 }))), /* @__PURE__ */ import_react39.default.createElement(
7825
7905
  "div",
7826
7906
  {
7827
7907
  className: "brokr-chat-messages",
7828
7908
  "data-empty": messages.length === 0
7829
7909
  },
7830
- messages.length === 0 ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-chat-empty" }, /* @__PURE__ */ import_react39.default.createElement(SparkIcon, { size: 18 }), /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-section", style: { gap: "0.35rem" } }, /* @__PURE__ */ import_react39.default.createElement("strong", null, "Send a message to chat with the AI."), /* @__PURE__ */ import_react39.default.createElement("span", { className: "brokr-copy" }, "Ask a question or drop in a starter prompt below.")), starterPrompts.length > 0 ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-chat-starters" }, starterPrompts.map((prompt) => {
7831
- const handleClick = () => {
7832
- handleStarterPrompt(prompt);
7833
- };
7834
- return /* @__PURE__ */ import_react39.default.createElement(
7835
- "button",
7836
- {
7837
- className: "brokr-chat-starter",
7838
- key: prompt,
7839
- onClick: handleClick,
7840
- type: "button"
7841
- },
7842
- prompt
7843
- );
7844
- })) : null) : null,
7910
+ messages.length === 0 ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-chat-empty" }, /* @__PURE__ */ import_react39.default.createElement(SparkIcon, { size: 18 }), /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-1)" } }, /* @__PURE__ */ import_react39.default.createElement("strong", null, "Send a message to chat with the AI."), /* @__PURE__ */ import_react39.default.createElement("span", { className: "brokr-copy" }, "Ask a question or drop in a starter prompt below.")), starterPrompts.length > 0 ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-chat-starters" }, starterPrompts.map((prompt) => /* @__PURE__ */ import_react39.default.createElement(StarterButton, { key: prompt, prompt, onSelect: handleStarterPrompt }))) : null) : null,
7845
7911
  messages.map((message, index) => /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-chat-bubble", "data-role": message.role, key: `${message.role}-${index}` }, contentToText(message.content))),
7846
7912
  error ? /* @__PURE__ */ import_react39.default.createElement("div", { className: "brokr-inline-message", "data-tone": "error" }, error) : null
7847
- ), /* @__PURE__ */ import_react39.default.createElement("form", { className: "brokr-section", onSubmit: handleSubmit, style: { gap: "0.75rem" } }, /* @__PURE__ */ import_react39.default.createElement(
7913
+ ), /* @__PURE__ */ import_react39.default.createElement("form", { className: "brokr-section", onSubmit: handleSubmit, style: { gap: "var(--brokr-space-3)" } }, /* @__PURE__ */ import_react39.default.createElement(
7848
7914
  "textarea",
7849
7915
  {
7850
7916
  className: "brokr-textarea brokr-chat-input",
@@ -7937,7 +8003,7 @@ function SmartUpload({
7937
8003
  const handleBrowse = (0, import_react40.useCallback)(() => {
7938
8004
  inputRef.current?.click();
7939
8005
  }, []);
7940
- return /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-card brokr-upload-shell" }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-section", style: { gap: "0.35rem" } }, /* @__PURE__ */ import_react40.default.createElement("strong", null, "Upload files"), /* @__PURE__ */ import_react40.default.createElement("span", { className: "brokr-copy" }, "Drop a file and let Brokr handle the boring part.")), paymentsMode === "sandbox" ? /* @__PURE__ */ import_react40.default.createElement("span", { className: "brokr-badge brokr-badge-sandbox" }, "Sandbox") : null), /* @__PURE__ */ import_react40.default.createElement(
8006
+ return /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-card brokr-upload-shell" }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-brand-row", style: { justifyContent: "space-between" } }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-1)" } }, /* @__PURE__ */ import_react40.default.createElement("strong", null, "Upload files"), /* @__PURE__ */ import_react40.default.createElement("span", { className: "brokr-copy" }, "Drop a file and let Brokr handle the boring part.")), paymentsMode === "sandbox" ? /* @__PURE__ */ import_react40.default.createElement("span", { className: "brokr-badge brokr-badge-sandbox" }, "Sandbox") : null), /* @__PURE__ */ import_react40.default.createElement(
7941
8007
  "label",
7942
8008
  {
7943
8009
  className: "brokr-upload-dropzone",
@@ -7962,7 +8028,7 @@ function SmartUpload({
7962
8028
  ref: inputRef,
7963
8029
  type: "file"
7964
8030
  }
7965
- ), fileName ? /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-card brokr-upload-file" }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-section", style: { gap: "0.35rem" } }, /* @__PURE__ */ import_react40.default.createElement("strong", null, fileName), /* @__PURE__ */ import_react40.default.createElement("span", { className: "brokr-copy" }, isUploading ? `Uploading ${progress}%` : progress === 100 ? "Processed" : "Queued")), /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-meter-bar", style: { width: "7rem" } }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-meter-fill", style: { width: `${progress}%` } }))) : null, error ? /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-inline-message", "data-tone": "error" }, error) : null);
8031
+ ), fileName ? /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-card brokr-upload-file" }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-section", style: { gap: "var(--brokr-space-1)" } }, /* @__PURE__ */ import_react40.default.createElement("strong", null, fileName), /* @__PURE__ */ import_react40.default.createElement("span", { className: "brokr-copy" }, isUploading ? `Uploading ${progress}%` : progress === 100 ? "Processed" : "Queued")), /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-meter-bar" }, /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-meter-fill", style: { width: `${progress}%` } }))) : null, error ? /* @__PURE__ */ import_react40.default.createElement("div", { className: "brokr-inline-message", "data-tone": "error" }, error) : null);
7966
8032
  }
7967
8033
 
7968
8034
  // src/react/composites/FeedbackWidget.tsx
@@ -8327,6 +8393,28 @@ function timeAgo(iso) {
8327
8393
  const days = Math.floor(hours / 24);
8328
8394
  return `${days}d ago`;
8329
8395
  }
8396
+ function NotifDropdownItem({
8397
+ notif,
8398
+ registry,
8399
+ onClick
8400
+ }) {
8401
+ const handleClick = (0, import_react44.useCallback)(() => onClick(notif), [notif, onClick]);
8402
+ const notifData = notif.data ?? {};
8403
+ const notifType = notifData.type ?? "default";
8404
+ const resolved = resolveNotificationType(registry, notifType, notifData);
8405
+ return /* @__PURE__ */ import_react44.default.createElement(
8406
+ "button",
8407
+ {
8408
+ type: "button",
8409
+ className: `brokr-notif-item${notif.read ? "" : " brokr-notif-item--unread"}`,
8410
+ onClick: handleClick,
8411
+ role: "menuitem"
8412
+ },
8413
+ resolved.image ? /* @__PURE__ */ import_react44.default.createElement("img", { src: resolved.image.url, alt: resolved.image.alt, className: "brokr-notif-item-logo" }) : /* @__PURE__ */ import_react44.default.createElement("span", { className: `brokr-notif-item-dot brokr-notif-item-dot--${notif.variant}` }),
8414
+ /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-item-body" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-title" }, notif.title), /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-message" }, notif.message)),
8415
+ /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-time" }, timeAgo(notif.createdAt))
8416
+ );
8417
+ }
8330
8418
  function NotificationBell() {
8331
8419
  const { notifications, unreadCount, markRead, markAllRead, isLoading, registry } = useNotifications();
8332
8420
  const [open, setOpen] = (0, import_react44.useState)(false);
@@ -8391,7 +8479,8 @@ function NotificationBell() {
8391
8479
  className: "brokr-notif-bell",
8392
8480
  onClick: toggle,
8393
8481
  "aria-label": `Notifications${unreadCount > 0 ? ` (${unreadCount} unread)` : ""}`,
8394
- "aria-expanded": open
8482
+ "aria-expanded": open,
8483
+ "aria-haspopup": "menu"
8395
8484
  },
8396
8485
  /* @__PURE__ */ import_react44.default.createElement("svg", { "aria-hidden": "true", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react44.default.createElement("path", { d: "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" }), /* @__PURE__ */ import_react44.default.createElement("path", { d: "M10.3 21a1.94 1.94 0 0 0 3.4 0" })),
8397
8486
  unreadCount > 0 && /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-badge" }, unreadCount > 99 ? "99+" : unreadCount)
@@ -8403,31 +8492,15 @@ function NotificationBell() {
8403
8492
  onClick: markAllRead
8404
8493
  },
8405
8494
  "Mark all read"
8406
- )), /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-dropdown-list" }, isLoading ? /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-empty-text" }, "Loading\u2026")) : sorted.length === 0 ? /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-empty-text" }, "No notifications yet")) : sorted.map((notif) => {
8407
- const notifData = notif.data ?? {};
8408
- const notifType = notifData.type ?? "default";
8409
- const resolved = resolveNotificationType(registry, notifType, notifData);
8410
- return /* @__PURE__ */ import_react44.default.createElement(
8411
- "button",
8412
- {
8413
- key: notif.id,
8414
- type: "button",
8415
- className: `brokr-notif-item${notif.read ? "" : " brokr-notif-item--unread"}`,
8416
- onClick: () => handleItemClick(notif),
8417
- role: "menuitem"
8418
- },
8419
- resolved.image ? /* @__PURE__ */ import_react44.default.createElement(
8420
- "img",
8421
- {
8422
- src: resolved.image.url,
8423
- alt: resolved.image.alt,
8424
- className: "brokr-notif-item-logo"
8425
- }
8426
- ) : /* @__PURE__ */ import_react44.default.createElement("span", { className: `brokr-notif-item-dot brokr-notif-item-dot--${notif.variant}` }),
8427
- /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-item-body" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-title" }, notif.title), /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-message" }, notif.message)),
8428
- /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-item-time" }, timeAgo(notif.createdAt))
8429
- );
8430
- }))));
8495
+ )), /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-dropdown-list" }, isLoading ? /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-empty-text" }, "Loading\u2026")) : sorted.length === 0 ? /* @__PURE__ */ import_react44.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react44.default.createElement("span", { className: "brokr-notif-empty-text" }, "No notifications yet")) : sorted.map((notif) => /* @__PURE__ */ import_react44.default.createElement(
8496
+ NotifDropdownItem,
8497
+ {
8498
+ key: notif.id,
8499
+ notif,
8500
+ registry,
8501
+ onClick: handleItemClick
8502
+ }
8503
+ )))));
8431
8504
  }
8432
8505
 
8433
8506
  // src/react/notifications/NotificationList.tsx
@@ -8444,6 +8517,27 @@ function formatTimestamp(iso) {
8444
8517
  function NotificationListSkeleton() {
8445
8518
  return /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-list-items" }, [1, 2, 3].map((i) => /* @__PURE__ */ import_react45.default.createElement("div", { key: i, className: "brokr-notif-list-row brokr-notif-list-row--skeleton" }, /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-dot brokr-notif-item-dot--skeleton" }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-item-body" }, /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-title brokr-skeleton-line", style: { width: "60%" } }), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-message brokr-skeleton-line", style: { width: "80%" } })), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-time brokr-skeleton-line", style: { width: 48 } }))));
8446
8519
  }
8520
+ function NotifListItem({
8521
+ notif,
8522
+ registry,
8523
+ onClick
8524
+ }) {
8525
+ const handleClick = (0, import_react45.useCallback)(() => onClick(notif), [notif, onClick]);
8526
+ const notifData = notif.data ?? {};
8527
+ const notifType = notif.type ?? notifData.type ?? "default";
8528
+ const resolved = resolveNotificationType(registry, notifType, notifData);
8529
+ return /* @__PURE__ */ import_react45.default.createElement(
8530
+ "button",
8531
+ {
8532
+ type: "button",
8533
+ className: `brokr-notif-list-row${notif.read ? "" : " brokr-notif-list-row--unread"}`,
8534
+ onClick: handleClick
8535
+ },
8536
+ resolved.image ? /* @__PURE__ */ import_react45.default.createElement("img", { src: resolved.image.url, alt: resolved.image.alt, className: "brokr-notif-item-logo" }) : /* @__PURE__ */ import_react45.default.createElement("span", { className: `brokr-notif-item-dot brokr-notif-item-dot--${notif.variant}` }),
8537
+ /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-item-body" }, /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-title" }, notif.title), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-message" }, notif.message)),
8538
+ /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-time" }, formatTimestamp(notif.createdAt))
8539
+ );
8540
+ }
8447
8541
  function NotificationList() {
8448
8542
  const { notifications, unreadCount, markRead, markAllRead, isLoading, registry } = useNotifications();
8449
8543
  const sorted = (0, import_react45.useMemo)(
@@ -8470,30 +8564,15 @@ function NotificationList() {
8470
8564
  onClick: markAllRead
8471
8565
  },
8472
8566
  "Mark all read"
8473
- )), isLoading ? /* @__PURE__ */ import_react45.default.createElement(NotificationListSkeleton, null) : sorted.length === 0 ? /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react45.default.createElement("svg", { "aria-hidden": "true", width: "40", height: "40", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1", strokeLinecap: "round", strokeLinejoin: "round", style: { opacity: 0.3 } }, /* @__PURE__ */ import_react45.default.createElement("path", { d: "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" }), /* @__PURE__ */ import_react45.default.createElement("path", { d: "M10.3 21a1.94 1.94 0 0 0 3.4 0" })), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-empty-text" }, "No notifications yet")) : /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-list-items" }, sorted.map((notif) => {
8474
- const notifData = notif.data ?? {};
8475
- const notifType = notif.type ?? notifData.type ?? "default";
8476
- const resolved = resolveNotificationType(registry, notifType, notifData);
8477
- return /* @__PURE__ */ import_react45.default.createElement(
8478
- "button",
8479
- {
8480
- key: notif.id,
8481
- type: "button",
8482
- className: `brokr-notif-list-row${notif.read ? "" : " brokr-notif-list-row--unread"}`,
8483
- onClick: () => handleClick(notif)
8484
- },
8485
- resolved.image ? /* @__PURE__ */ import_react45.default.createElement(
8486
- "img",
8487
- {
8488
- src: resolved.image.url,
8489
- alt: resolved.image.alt,
8490
- className: "brokr-notif-item-logo"
8491
- }
8492
- ) : /* @__PURE__ */ import_react45.default.createElement("span", { className: `brokr-notif-item-dot brokr-notif-item-dot--${notif.variant}` }),
8493
- /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-item-body" }, /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-title" }, notif.title), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-message" }, notif.message)),
8494
- /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-item-time" }, formatTimestamp(notif.createdAt))
8495
- );
8496
- })));
8567
+ )), isLoading ? /* @__PURE__ */ import_react45.default.createElement(NotificationListSkeleton, null) : sorted.length === 0 ? /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-empty" }, /* @__PURE__ */ import_react45.default.createElement("svg", { "aria-hidden": "true", width: "40", height: "40", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1", strokeLinecap: "round", strokeLinejoin: "round", style: { opacity: 0.3 } }, /* @__PURE__ */ import_react45.default.createElement("path", { d: "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" }), /* @__PURE__ */ import_react45.default.createElement("path", { d: "M10.3 21a1.94 1.94 0 0 0 3.4 0" })), /* @__PURE__ */ import_react45.default.createElement("span", { className: "brokr-notif-empty-text" }, "No notifications yet")) : /* @__PURE__ */ import_react45.default.createElement("div", { className: "brokr-notif-list-items" }, sorted.map((notif) => /* @__PURE__ */ import_react45.default.createElement(
8568
+ NotifListItem,
8569
+ {
8570
+ key: notif.id,
8571
+ notif,
8572
+ registry,
8573
+ onClick: handleClick
8574
+ }
8575
+ ))));
8497
8576
  }
8498
8577
 
8499
8578
  // src/react/hooks/use-user.ts